// front_gate_box.c - Front Gate Box (SFC/SLL priority and helpers) #include "front_gate_box.h" #include "tiny_alloc_fast_sfc.inc.h" #include "tls_sll_box.h" // Box TLS-SLL API #include "ptr_conversion_box.h" // Box 3: Pointer conversions // TLS SLL state (extern from hakmem_tiny.c) extern __thread TinyTLSSLL g_tls_sll[TINY_NUM_CLASSES]; extern int g_tls_sll_enable; // set at init via HAKMEM_TINY_TLS_SLL // Front breakdown counters (extern from hakmem_tiny.c) extern unsigned long long g_front_sfc_hit[]; extern unsigned long long g_front_sll_hit[]; // SFC feature flag (extern from hakmem_tiny_sfc.c) extern int g_sfc_enabled; int front_gate_try_pop(int class_idx, void** out_ptr) { if (!out_ptr) return 0; // Layer 0: SFC if (__builtin_expect(g_sfc_enabled, 1)) { void* base = sfc_alloc(class_idx); if (base != NULL) { g_front_sfc_hit[class_idx]++; /* BOX_BOUNDARY: Box 1 (SFC) → Box 3 → Box 4 (User) */ /* sfc_alloc returns BASE, must convert to USER for caller */ *out_ptr = PTR_BASE_TO_USER(base, class_idx); return 1; } } // Layer 1: TLS SLL if (__builtin_expect(g_tls_sll_enable, 1)) { void* base = NULL; if (tls_sll_pop(class_idx, &base)) { g_front_sll_hit[class_idx]++; /* BOX_BOUNDARY: Box 1 (TLS SLL) → Box 3 → Box 4 (User) */ /* tls_sll_pop returns BASE, must convert to USER for caller */ *out_ptr = PTR_BASE_TO_USER(base, class_idx); return 1; } } return 0; } // Cascade some of refilled blocks into SFC (one-way, safe) void front_gate_after_refill(int class_idx, int refilled_count) { if (!g_sfc_enabled || refilled_count <= 0) return; int to_move = refilled_count / 2; if (to_move <= 0) return; while (to_move-- > 0 && g_tls_sll[class_idx].count > 0) { // SLL pop void* ptr = NULL; if (!tls_sll_pop(class_idx, &ptr)) break; // SFC push (capacity-guarded inside sfc_free_push) if (!sfc_free_push(class_idx, ptr)) { // If SFC refused (full), stop early to avoid spinning break; } } } void front_gate_push_tls(int class_idx, hak_base_ptr_t ptr) { // IMPORTANT: ptr is ALREADY a BASE pointer (callers from tiny_free_fast.inc.h // convert USER→BASE before calling tiny_alloc_fast_push) // Do NOT double-convert! Pass directly to TLS SLL which expects BASE. // Use Box TLS-SLL API (C7-safe; expects base pointer) if (!tls_sll_push(class_idx, ptr, UINT32_MAX)) { // C7 rejected or capacity exceeded - should not happen in front gate // but handle gracefully (silent discard) return; } }