Phase 9-2: Remove Legacy Backend & Unify to Shared Pool (50M ops/s)
- Removed Legacy Backend fallback; Shared Pool is now the sole backend. - Removed Soft Cap limit in Shared Pool to allow full memory management. - Implemented EMPTY slab recycling with batched meta->used decrement in remote drain. - Updated tiny_free_local_box to return is_empty status for safe recycling. - Fixed race condition in release path by removing from legacy list early. - Achieved 50.3M ops/s in WS8192 benchmark (+200% vs baseline).
This commit is contained in:
@ -26,6 +26,23 @@ shared_pool_release_slab(SuperSlab* ss, int slab_idx)
|
||||
return;
|
||||
}
|
||||
|
||||
// Phase 9-2 FIX: Promote Legacy SuperSlabs to Shared Pool on first recycle
|
||||
// If we are recycling a slot from a Legacy SS, we must remove it from the
|
||||
// Legacy list (g_superslab_heads) to prevent Legacy Backend from allocating
|
||||
// from it simultaneously (Double Allocation Race).
|
||||
// This effectively transfers ownership to Shared Pool.
|
||||
extern void remove_superslab_from_legacy_head(SuperSlab* ss);
|
||||
remove_superslab_from_legacy_head(ss);
|
||||
|
||||
// BUGFIX: Re-check used count after removal. Legacy Backend might have
|
||||
// allocated from this slab while we were waiting for the lock in remove().
|
||||
TinySlabMeta* slab_meta = &ss->slabs[slab_idx];
|
||||
if (atomic_load_explicit(&slab_meta->used, memory_order_acquire) != 0) {
|
||||
// Legacy Backend stole this slab. It's now an orphan (removed from list).
|
||||
// We abort recycling. It will be recycled when Legacy frees it later.
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug logging
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
static int dbg = -1;
|
||||
@ -46,9 +63,9 @@ shared_pool_release_slab(SuperSlab* ss, int slab_idx)
|
||||
|
||||
pthread_mutex_lock(&g_shared_pool.alloc_lock);
|
||||
|
||||
TinySlabMeta* slab_meta = &ss->slabs[slab_idx];
|
||||
// TinySlabMeta* slab_meta = &ss->slabs[slab_idx]; // Already declared above
|
||||
if (slab_meta->used != 0) {
|
||||
// Not actually empty; nothing to do
|
||||
// Not actually empty (double check under lock)
|
||||
if (g_lock_stats_enabled == 1) {
|
||||
atomic_fetch_add(&g_lock_release_count, 1);
|
||||
}
|
||||
@ -160,15 +177,28 @@ shared_pool_release_slab(SuperSlab* ss, int slab_idx)
|
||||
|
||||
pthread_mutex_unlock(&g_shared_pool.alloc_lock);
|
||||
|
||||
// Remove from legacy backend list (if present) to prevent dangling pointers
|
||||
extern void remove_superslab_from_legacy_head(SuperSlab* ss);
|
||||
remove_superslab_from_legacy_head(ss);
|
||||
// Remove from legacy backend list (moved to top of function)
|
||||
// extern void remove_superslab_from_legacy_head(SuperSlab* ss);
|
||||
// remove_superslab_from_legacy_head(ss);
|
||||
|
||||
// Free SuperSlab:
|
||||
// 1. Try LRU cache (hak_ss_lru_push) - lazy deallocation
|
||||
// 2. Or munmap if LRU is full - eager deallocation
|
||||
extern void superslab_free(SuperSlab* ss);
|
||||
superslab_free(ss);
|
||||
|
||||
// BUGFIX: Double check total_active_blocks. Legacy Backend might have
|
||||
// allocated from ANOTHER slab in this SS just before we removed it.
|
||||
// If so, we must NOT free the SS.
|
||||
if (atomic_load(&ss->total_active_blocks) == 0) {
|
||||
extern void superslab_free(SuperSlab* ss);
|
||||
superslab_free(ss);
|
||||
} else {
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
if (dbg == 1) {
|
||||
fprintf(stderr, "[SP_SLOT_RELEASE] SKIP free ss=%p: total_active_blocks=%u > 0\n",
|
||||
(void*)ss, atomic_load(&ss->total_active_blocks));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user