Continue hakmem_tiny.c refactoring with 3 large module extractions. ## Changes **hakmem_tiny.c**: 995 → 616 lines (-379 lines, -38% this phase) **Total reduction**: 2081 → 616 lines (-1465 lines, -70% cumulative) 🏆 ## Extracted Modules (3 new boxes) 6. **tls_state_box** (224 lines) - TLS SLL enable flags and configuration - TLS canaries and SLL array definitions - Debug counters (path, ultra, allocation) - Frontend/backend configuration - TLS thread ID caching helpers - Frontend hit/miss counters - HotMag, QuickSlot, Ultra-front configuration - Helper functions (is_hot_class, tiny_optional_push) - Intelligence system helpers 7. **legacy_slow_box** (96 lines) - tiny_slow_alloc_fast() function (cold/unused) - Legacy slab-based allocation with refill - TLS cache/fast cache refill from slabs - Remote drain handling - List management (move to full/free lists) - Marked __attribute__((cold, noinline, unused)) 8. **slab_lookup_box** (77 lines) - registry_lookup() - O(1) hash-based lookup - hak_tiny_owner_slab() - public API for slab discovery - Linear probing search with atomic owner access - O(N) fallback for non-registry mode - Safety validation for membership checking ## Cumulative Progress (8 boxes total) **Previously extracted** (Phase 1): 1. config_box (211 lines) 2. publish_box (419 lines) 3. globals_box (256 lines) 4. phase6_wrappers_box (122 lines) 5. ace_guard_box (100 lines) **This phase** (Phase 2): 6. tls_state_box (224 lines) 7. legacy_slow_box (96 lines) 8. slab_lookup_box (77 lines) **Total extracted**: 1,505 lines across 8 coherent modules **Remaining core**: 616 lines (well-organized, focused) ## Benefits - **Readability**: 2k monolith → focused 616-line core - **Maintainability**: Each box has single responsibility - **Organization**: TLS state, legacy code, lookup utilities separated - **Build**: All modules compile successfully ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
78 lines
3.2 KiB
C++
78 lines
3.2 KiB
C++
static TinySlab* registry_lookup(uintptr_t slab_base) {
|
|
// Lock-free read with atomic owner access (MT-safe)
|
|
int hash = registry_hash(slab_base);
|
|
|
|
// Linear probing search
|
|
for (int i = 0; i < SLAB_REGISTRY_MAX_PROBE; i++) {
|
|
int idx = (hash + i) & SLAB_REGISTRY_MASK;
|
|
SlabRegistryEntry* entry = &g_slab_registry[idx];
|
|
|
|
if (entry->slab_base == slab_base) {
|
|
// Atomic load to prevent TOCTOU race with registry_unregister()
|
|
TinySlab* owner = atomic_load_explicit(&entry->owner, memory_order_acquire);
|
|
if (!owner) return NULL; // Entry cleared by unregister
|
|
return owner;
|
|
}
|
|
|
|
if (entry->slab_base == 0) {
|
|
return NULL; // Empty slot - not found
|
|
}
|
|
}
|
|
return NULL; // Not found after max probes
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXTRACTED TO hakmem_tiny_slab_mgmt.inc (Phase 2D-4 FINAL)
|
|
// ============================================================================
|
|
// Function: allocate_new_slab() - 79 lines (lines 952-1030)
|
|
// Allocate new slab for a class
|
|
|
|
// Function: release_slab() - 23 lines (lines 1033-1055)
|
|
// Release a slab back to system
|
|
|
|
// Step 2: Find slab owner by pointer (O(1) via hash table registry, or O(N) fallback)
|
|
TinySlab* hak_tiny_owner_slab(void* ptr) {
|
|
if (!ptr || !g_tiny_initialized) return NULL;
|
|
|
|
// Phase 6.14: Runtime toggle between Registry (O(1)) and List (O(N))
|
|
if (g_use_registry) {
|
|
// O(1) lookup via hash table
|
|
uintptr_t slab_base = (uintptr_t)ptr & ~(TINY_SLAB_SIZE - 1);
|
|
TinySlab* slab = registry_lookup(slab_base);
|
|
if (!slab) return NULL;
|
|
// SAFETY: validate membership (ptr must be inside [base, base+64KB))
|
|
uintptr_t start = (uintptr_t)slab->base;
|
|
uintptr_t end = start + TINY_SLAB_SIZE;
|
|
if ((uintptr_t)ptr < start || (uintptr_t)ptr >= end) {
|
|
return NULL; // false positive from registry → treat as non-Tiny
|
|
}
|
|
return slab;
|
|
} else {
|
|
// O(N) fallback: linear search through all slab lists (lock per class)
|
|
for (int class_idx = 0; class_idx < TINY_NUM_CLASSES; class_idx++) {
|
|
pthread_mutex_t* lock = &g_tiny_class_locks[class_idx].m;
|
|
pthread_mutex_lock(lock);
|
|
// Search free slabs
|
|
for (TinySlab* slab = g_tiny_pool.free_slabs[class_idx]; slab; slab = slab->next) {
|
|
uintptr_t slab_start = (uintptr_t)slab->base;
|
|
uintptr_t slab_end = slab_start + TINY_SLAB_SIZE;
|
|
if ((uintptr_t)ptr >= slab_start && (uintptr_t)ptr < slab_end) {
|
|
pthread_mutex_unlock(lock);
|
|
return slab;
|
|
}
|
|
}
|
|
// Search full slabs
|
|
for (TinySlab* slab = g_tiny_pool.full_slabs[class_idx]; slab; slab = slab->next) {
|
|
uintptr_t slab_start = (uintptr_t)slab->base;
|
|
uintptr_t slab_end = slab_start + TINY_SLAB_SIZE;
|
|
if ((uintptr_t)ptr >= slab_start && (uintptr_t)ptr < slab_end) {
|
|
pthread_mutex_unlock(lock);
|
|
return slab;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(lock);
|
|
}
|
|
return NULL; // Not found
|
|
}
|
|
}
|