diff --git a/core/hakmem_tiny_refill.inc.h b/core/hakmem_tiny_refill.inc.h index 7588d4e9..6ab0637c 100644 --- a/core/hakmem_tiny_refill.inc.h +++ b/core/hakmem_tiny_refill.inc.h @@ -204,8 +204,8 @@ static inline int sll_refill_small_from_ss(int class_idx, int max_take) { TinySlabMeta* meta = tls->meta; if (!meta) return 0; - // Class7 special-case: simple batch refill (favor linear carve, minimal branching) - if (__builtin_expect(class_idx == 7, 0)) { + // Class 5/6/7 special-case: simple batch refill (favor linear carve, minimal branching) + if (__builtin_expect(class_idx >= 5, 0)) { uint32_t sll_cap = sll_cap_for_class(class_idx, (uint32_t)TINY_TLS_MAG_CAP); int room = (int)sll_cap - (int)g_tls_sll_count[class_idx]; if (room <= 0) return 0; diff --git a/core/tiny_superslab_alloc.inc.h b/core/tiny_superslab_alloc.inc.h index 7031c515..b4afaaf0 100644 --- a/core/tiny_superslab_alloc.inc.h +++ b/core/tiny_superslab_alloc.inc.h @@ -133,6 +133,24 @@ static inline void* superslab_alloc_from_slab(SuperSlab* ss, int slab_idx) { return NULL; // Slab is full } +// Adopt helper: acquire → drain → bind (single boundary) – returns 1 on success +static inline int adopt_bind_if_safe(TinyTLSSlab* tls, SuperSlab* ss, int slab_idx, int class_idx) { + uint32_t self_tid = tiny_self_u32(); + SlabHandle h = slab_try_acquire(ss, slab_idx, self_tid); + if (!slab_is_valid(&h)) return 0; + slab_drain_remote_full(&h); + if (__builtin_expect(slab_is_safe_to_bind(&h), 1)) { + // Optional: move a few nodes to Front SLL to boost next hits + tiny_drain_freelist_to_sll_once(h.ss, h.slab_idx, class_idx); + tiny_tls_bind_slab(tls, h.ss, h.slab_idx); + // Ownership now associated with TLS slab; release handle bookkeeping + slab_release(&h); + return 1; + } + slab_release(&h); + return 0; +} + // Phase 6.24 & 7.6: Refill TLS SuperSlab (with unified TLS cache + deferred allocation) static SuperSlab* superslab_refill(int class_idx) { #if HAKMEM_DEBUG_COUNTERS @@ -475,21 +493,11 @@ static SuperSlab* superslab_refill(int class_idx) { if (!ss || ss->magic != SUPERSLAB_MAGIC) continue; // Note: class_idx check is not needed (per-class registry!) - // Pick first slab with freelist (Box 4: 所有権取得 + remote check) + // Pick first slab with freelist (Box 4: adopt boundary helper) int reg_cap = ss_slabs_capacity(ss); - uint32_t self_tid = tiny_self_u32(); for (int s = 0; s < reg_cap; s++) { if (ss->slabs[s].freelist) { - SlabHandle h = slab_try_acquire(ss, s, self_tid); - if (slab_is_valid(&h)) { - slab_drain_remote_full(&h); - if (slab_is_safe_to_bind(&h)) { - tiny_drain_freelist_to_sll_once(h.ss, h.slab_idx, class_idx); - tiny_tls_bind_slab(tls, ss, s); - return ss; - } - slab_release(&h); - } + if (adopt_bind_if_safe(tls, ss, s, class_idx)) return ss; } } }