Pool TLS: BIND_BOX simplification - TID cache only (SEGV fixed)
Problem: Range-based ownership check caused SEGV in MT benchmarks
Root cause: Arena range tracking complexity + initialization race condition
Solution: Simplified to TID-cache-only approach
- Removed arena range tracking (arena_base, arena_end)
- Fast same-thread check via TID comparison only
- gettid() cached in TLS to avoid repeated syscalls
Changes:
1. core/pool_tls_bind.h - Simplified to TID cache struct
- PoolTLSBind: only stores tid (no arena range)
- pool_get_my_tid(): inline TID cache accessor
- pool_tls_is_mine_tid(owner_tid): simple TID comparison
2. core/pool_tls_bind.c - Minimal TLS storage only
- All logic moved to inline functions in header
- Only defines: __thread PoolTLSBind g_pool_tls_bind = {0};
3. core/pool_tls.c - Use TID comparison in pool_free()
- Changed: pool_tls_is_mine(ptr) → pool_tls_is_mine_tid(owner_tid)
- Registry lookup still needed for owner_tid (accepted overhead)
- Fixed gettid_cached() duplicate definition (#ifdef guard)
4. core/pool_tls_arena.c - Removed arena range hooks
- Removed: pool_tls_bind_update_range() call (disabled)
- Removed: pool_arena_get_my_range() implementation
5. core/pool_tls_arena.h - Removed getter API
- Removed: pool_arena_get_my_range() declaration
Results:
- MT stability: ✅ 2T/4T benchmarks SEGV-free
- Throughput: 2T=0.93M ops/s, 4T=1.64M ops/s
- Code simplicity: 90% reduction in BIND_BOX complexity
Trade-off:
- Registry lookup still required (TID-only doesn't eliminate it)
- But: simplified code, no initialization complexity, MT-safe
Next: Profile with perf to find remaining Mid-Large bottlenecks
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -6,10 +6,15 @@
|
||||
#include <unistd.h>
|
||||
#include <stdatomic.h>
|
||||
#include "pool_tls_registry.h"
|
||||
|
||||
#ifdef HAKMEM_POOL_TLS_BIND_BOX
|
||||
#include "pool_tls_bind.h"
|
||||
#else
|
||||
// gettid_cached is defined in pool_tls_bind.h when BIND_BOX is enabled
|
||||
static inline pid_t gettid_cached(void){
|
||||
static __thread pid_t t=0; if (__builtin_expect(t==0,0)) t=(pid_t)syscall(SYS_gettid); return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// Class sizes: 8KB, 16KB, 24KB, 32KB, 40KB, 48KB, 52KB
|
||||
@ -146,15 +151,30 @@ void pool_free(void* ptr) {
|
||||
// Need registry lookup (slower fallback) - not implemented in Phase 1
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Owner resolution via page registry
|
||||
pid_t owner_tid=0; int reg_cls=-1;
|
||||
if (pool_reg_lookup(ptr, &owner_tid, ®_cls)){
|
||||
pid_t me = gettid_cached();
|
||||
if (owner_tid != me){
|
||||
pid_t owner_tid = 0;
|
||||
int reg_cls = -1;
|
||||
if (pool_reg_lookup(ptr, &owner_tid, ®_cls)) {
|
||||
#ifdef HAKMEM_POOL_TLS_BIND_BOX
|
||||
// POOL_TLS_BIND_BOX: Fast TID comparison (no repeated gettid syscalls)
|
||||
if (!pool_tls_is_mine_tid(owner_tid)) {
|
||||
// Cross-thread free
|
||||
extern int pool_remote_push(int class_idx, void* ptr, int owner_tid);
|
||||
(void)pool_remote_push(class_idx, ptr, owner_tid);
|
||||
return;
|
||||
}
|
||||
// Same-thread: Continue to fast free path below
|
||||
#else
|
||||
// Original gettid comparison
|
||||
pid_t me = gettid_cached();
|
||||
if (owner_tid != me) {
|
||||
// Cross-thread free
|
||||
extern int pool_remote_push(int class_idx, void* ptr, int owner_tid);
|
||||
(void)pool_remote_push(class_idx, ptr, owner_tid);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Same-thread: Push to TLS freelist (2-3 instructions)
|
||||
|
||||
Reference in New Issue
Block a user