P1.3: Add meta->active for TLS SLL tracking

Add active field to TinySlabMeta to track blocks currently held by
users (not in TLS SLL or freelist caches). This enables accurate
empty slab detection that accounts for TLS SLL cached blocks.

Changes:
- superslab_types.h: Add _Atomic uint16_t active field
- ss_allocation_box.c, hakmem_tiny_superslab.c: Initialize active=0
- tiny_free_fast_v2.inc.h: Decrement active on TLS SLL push
- tiny_alloc_fast.inc.h: Add tiny_active_track_alloc() helper,
  increment active on TLS SLL pop (all code paths)
- ss_hot_cold_box.h: ss_is_slab_empty() uses active when enabled

All tracking is ENV-gated: HAKMEM_TINY_ACTIVE_TRACK=1 to enable.
Default is off for zero performance impact.

Invariant: active = used - tls_cached (active <= used)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-11-28 13:53:45 +09:00
parent dc9e650db3
commit 6b86c60a20
6 changed files with 86 additions and 5 deletions

View File

@ -429,6 +429,7 @@ void superslab_init_slab(SuperSlab* ss, int slab_idx, size_t block_size, uint32_
TinySlabMeta* meta = &ss->slabs[slab_idx];
meta->freelist = NULL; // NULL = linear allocation mode
meta->used = 0;
meta->active = 0; // P1.3: blocks in use by user (starts at 0)
meta->capacity = capacity;
meta->carved = 0;
// Store bits 8-15 of owner_tid (low 8 bits are 0 for glibc pthread IDs)

View File

@ -8,6 +8,7 @@
#include "../superslab/superslab_types.h"
#include <stdbool.h>
#include <stdlib.h> // P1.3: for getenv()
// ============================================================================
// Phase 3d-C: Hot/Cold Split Box API
@ -33,9 +34,27 @@
#define HOT_UTILIZATION_THRESHOLD 50 // 使用率50%以上でホット判定
// Phase 12-1.1: EMPTY判定ロジック最優先再利用
// Returns: true if slab is completely EMPTY (used == 0, highest reuse priority)
// P1.3: ENV gate for active-based empty detection
// ENV: HAKMEM_TINY_ACTIVE_TRACK=1 → use active, else use used
// Returns: true if slab is completely EMPTY (highest reuse priority)
static inline bool ss_is_slab_empty(const TinySlabMeta* meta) {
return (meta->capacity > 0 && meta->used == 0);
if (meta->capacity == 0) return false;
// P1.3: Use active-based empty detection if enabled
static int g_use_active = -1;
if (__builtin_expect(g_use_active == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_ACTIVE_TRACK");
g_use_active = (e && *e && *e != '0') ? 1 : 0;
}
if (g_use_active) {
// P1.3: active == 0 means all blocks returned by user (even if some in TLS SLL)
uint16_t act = atomic_load_explicit(&meta->active, memory_order_relaxed);
return (act == 0);
} else {
// Legacy: used == 0 (doesn't account for TLS SLL)
return (meta->used == 0);
}
}
// Phase 3d-C: Hot判定ロジック