Files
hakmem/core/hakmem_tiny_remote.inc
Moe Charm (CI) 52386401b3 Debug Counters Implementation - Clean History
Major Features:
- Debug counter infrastructure for Refill Stage tracking
- Free Pipeline counters (ss_local, ss_remote, tls_sll)
- Diagnostic counters for early return analysis
- Unified larson.sh benchmark runner with profiles
- Phase 6-3 regression analysis documentation

Bug Fixes:
- Fix SuperSlab disabled by default (HAKMEM_TINY_USE_SUPERSLAB)
- Fix profile variable naming consistency
- Add .gitignore patterns for large files

Performance:
- Phase 6-3: 4.79 M ops/s (has OOM risk)
- With SuperSlab: 3.13 M ops/s (+19% improvement)

This is a clean repository without large log files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 12:31:14 +09:00

57 lines
2.2 KiB
C++

// hakmem_tiny_remote.inc
// Remote free operations for TinySlab cross-thread deallocation
static void tiny_remote_push(struct TinySlab* slab, void* ptr) {
if (!slab || !ptr) return;
// Push to slab's remote freelist using atomic operations
uintptr_t old_head = atomic_load_explicit(&slab->remote_head, memory_order_relaxed);
do {
*(uintptr_t*)ptr = old_head;
} while (!atomic_compare_exchange_weak_explicit(&slab->remote_head, &old_head, (uintptr_t)ptr,
memory_order_release,
memory_order_relaxed));
atomic_fetch_add_explicit(&slab->remote_count, 1, memory_order_relaxed);
}
static void tiny_remote_drain_locked(struct TinySlab* slab) {
if (!slab) return;
// Drain remote frees (assumes lock held on slab)
uintptr_t remote = atomic_exchange_explicit(&slab->remote_head, 0, memory_order_acquire);
uint32_t remote_cnt = atomic_exchange_explicit(&slab->remote_count, 0, memory_order_relaxed);
if (!remote || remote_cnt == 0) return;
// Process each remote free: mark the block as free in the bitmap
while (remote && remote_cnt > 0) {
uintptr_t next = *(uintptr_t*)remote;
// Mark block as free in bitmap
uintptr_t offset = remote - (uintptr_t)slab->base;
size_t block_size = g_tiny_class_sizes[slab->class_idx];
size_t block_idx = offset / block_size;
if (block_idx < slab->total_count) {
size_t word_idx = block_idx / 64;
size_t bit_idx = block_idx % 64;
slab->bitmap[word_idx] &= ~(1UL << bit_idx); // Clear bit = free
slab->free_count++;
}
remote = next;
remote_cnt--;
}
}
static inline void tiny_remote_drain_owner(struct TinySlab* slab) {
if (!slab) return;
if (!pthread_equal(slab->owner_tid, tiny_self_pt())) return;
if (atomic_load_explicit(&slab->remote_count, memory_order_relaxed) == 0) return;
pthread_mutex_t* lock = &g_tiny_class_locks[slab->class_idx].m;
if (pthread_mutex_trylock(lock) != 0) return;
tiny_remote_drain_locked(slab);
pthread_mutex_unlock(lock);
}