173 lines
6.0 KiB
C
173 lines
6.0 KiB
C
// slab_carve_box.h - Slab Carving Box
|
|
// Purpose: Unified API for carving blocks from SuperSlabs
|
|
// Used by: Warm pool hot path, normal refill path, P0 batch refill
|
|
// License: MIT
|
|
// Date: 2025-12-04
|
|
|
|
#ifndef HAK_SLAB_CARVE_BOX_H
|
|
#define HAK_SLAB_CARVE_BOX_H
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdatomic.h>
|
|
#include "../hakmem_tiny_config.h"
|
|
#include "../hakmem_tiny_superslab.h"
|
|
#include "../superslab/superslab_inline.h"
|
|
#include "../tiny_box_geometry.h"
|
|
#include "../box/tiny_next_ptr_box.h"
|
|
#include "../box/pagefault_telemetry_box.h"
|
|
#include "c7_meta_used_counter_box.h"
|
|
|
|
// ============================================================================
|
|
// Slab Carving API (Inline for Hot Path)
|
|
// ============================================================================
|
|
|
|
// Try to carve blocks directly from a SuperSlab
|
|
// Returns: Number of blocks produced (0 if carve failed)
|
|
//
|
|
// Parameters:
|
|
// class_idx - Allocation class (determines block size)
|
|
// ss - Target SuperSlab to carve from
|
|
// out - Output buffer for carved blocks
|
|
// max_blocks - Maximum blocks to carve
|
|
//
|
|
// Algorithm:
|
|
// 1. Validate SuperSlab magic
|
|
// 2. Scan all slabs in SuperSlab for class match
|
|
// 3. For each matching slab:
|
|
// a. Try freelist first (if available)
|
|
// b. Fall back to linear carve (if capacity available)
|
|
// c. Stop when max_blocks reached
|
|
// 4. Return total blocks carved
|
|
//
|
|
// Performance: O(slabs_in_ss) linear scan, typically 3-4 iterations
|
|
//
|
|
static inline int slab_carve_from_ss(int class_idx, SuperSlab* ss,
|
|
void** out, int max_blocks) {
|
|
if (!ss || ss->magic != SUPERSLAB_MAGIC) return 0;
|
|
|
|
// Find an available slab in this SuperSlab
|
|
int cap = ss_slabs_capacity(ss);
|
|
#if HAKMEM_BUILD_RELEASE
|
|
static _Atomic int rel_c7_meta_logged = 0;
|
|
TinySlabMeta* rel_c7_meta = NULL;
|
|
int rel_c7_meta_idx = -1;
|
|
#else
|
|
static __thread int dbg_c7_meta_logged = 0;
|
|
TinySlabMeta* dbg_c7_meta = NULL;
|
|
int dbg_c7_meta_idx = -1;
|
|
#endif
|
|
for (int slab_idx = 0; slab_idx < cap; slab_idx++) {
|
|
TinySlabMeta* meta = &ss->slabs[slab_idx];
|
|
|
|
// Check if this slab matches our class and has capacity
|
|
if (meta->class_idx != (uint8_t)class_idx) continue;
|
|
#if HAKMEM_BUILD_RELEASE
|
|
if (class_idx == 7 && atomic_load_explicit(&rel_c7_meta_logged, memory_order_relaxed) == 0 && !rel_c7_meta) {
|
|
rel_c7_meta = meta;
|
|
rel_c7_meta_idx = slab_idx;
|
|
}
|
|
#else
|
|
if (class_idx == 7 && dbg_c7_meta_logged == 0 && !dbg_c7_meta) {
|
|
dbg_c7_meta = meta;
|
|
dbg_c7_meta_idx = slab_idx;
|
|
}
|
|
#endif
|
|
if (meta->used >= meta->capacity && !meta->freelist) continue;
|
|
|
|
// Carve blocks from this slab
|
|
size_t bs = tiny_stride_for_class(class_idx);
|
|
uint8_t* base = tiny_slab_base_for_geometry(ss, slab_idx);
|
|
int produced = 0;
|
|
|
|
while (produced < max_blocks) {
|
|
void* p = NULL;
|
|
|
|
if (meta->freelist) {
|
|
// Pop from freelist
|
|
p = meta->freelist;
|
|
void* next_node = tiny_next_read(class_idx, p);
|
|
|
|
#if HAKMEM_TINY_HEADER_CLASSIDX
|
|
*(uint8_t*)p = (uint8_t)(0xa0 | (class_idx & 0x0f));
|
|
__atomic_thread_fence(__ATOMIC_RELEASE);
|
|
#endif
|
|
|
|
meta->freelist = next_node;
|
|
meta->used++;
|
|
c7_meta_used_note(class_idx, C7_META_USED_SRC_FRONT);
|
|
|
|
} else if (meta->carved < meta->capacity) {
|
|
// Linear carve
|
|
p = (void*)(base + ((size_t)meta->carved * bs));
|
|
|
|
#if HAKMEM_TINY_HEADER_CLASSIDX
|
|
*(uint8_t*)p = (uint8_t)(0xa0 | (class_idx & 0x0f));
|
|
#endif
|
|
|
|
meta->carved++;
|
|
meta->used++;
|
|
c7_meta_used_note(class_idx, C7_META_USED_SRC_FRONT);
|
|
|
|
} else {
|
|
break; // This slab exhausted
|
|
}
|
|
|
|
if (p) {
|
|
pagefault_telemetry_touch(class_idx, p);
|
|
out[produced++] = p;
|
|
}
|
|
}
|
|
|
|
if (produced > 0) return produced;
|
|
// If this slab had no freelist and no carved capacity, continue to next
|
|
}
|
|
|
|
#if !HAKMEM_BUILD_RELEASE
|
|
static __thread int dbg_c7_slab_carve_zero_logs = 0;
|
|
if (class_idx == 7 && dbg_c7_slab_carve_zero_logs < 10) {
|
|
fprintf(stderr, "[C7_SLAB_CARVE_ZERO] ss=%p no blocks carved\n", (void*)ss);
|
|
dbg_c7_slab_carve_zero_logs++;
|
|
}
|
|
#endif
|
|
#if HAKMEM_BUILD_RELEASE
|
|
if (class_idx == 7 &&
|
|
atomic_load_explicit(&rel_c7_meta_logged, memory_order_relaxed) == 0 &&
|
|
rel_c7_meta) {
|
|
size_t bs = tiny_stride_for_class(class_idx);
|
|
fprintf(stderr,
|
|
"[REL_C7_CARVE_META] ss=%p slab=%d cls=%u used=%u cap=%u carved=%u freelist=%p stride=%zu slabs_cap=%d\n",
|
|
(void*)ss,
|
|
rel_c7_meta_idx,
|
|
(unsigned)rel_c7_meta->class_idx,
|
|
(unsigned)rel_c7_meta->used,
|
|
(unsigned)rel_c7_meta->capacity,
|
|
(unsigned)rel_c7_meta->carved,
|
|
rel_c7_meta->freelist,
|
|
bs,
|
|
cap);
|
|
atomic_store_explicit(&rel_c7_meta_logged, 1, memory_order_relaxed);
|
|
}
|
|
#else
|
|
if (class_idx == 7 && dbg_c7_meta_logged == 0 && dbg_c7_meta) {
|
|
size_t bs = tiny_stride_for_class(class_idx);
|
|
fprintf(stderr,
|
|
"[DBG_C7_CARVE_META] ss=%p slab=%d cls=%u used=%u cap=%u carved=%u freelist=%p stride=%zu slabs_cap=%d\n",
|
|
(void*)ss,
|
|
dbg_c7_meta_idx,
|
|
(unsigned)dbg_c7_meta->class_idx,
|
|
(unsigned)dbg_c7_meta->used,
|
|
(unsigned)dbg_c7_meta->capacity,
|
|
(unsigned)dbg_c7_meta->carved,
|
|
dbg_c7_meta->freelist,
|
|
bs,
|
|
cap);
|
|
dbg_c7_meta_logged = 1;
|
|
}
|
|
#endif
|
|
return 0; // No slab in this SuperSlab had available capacity
|
|
}
|
|
|
|
#endif // HAK_SLAB_CARVE_BOX_H
|