Phase 4c: Add master trace control (HAKMEM_TRACE)
Add unified trace control that allows enabling specific trace modules using comma-separated values or "all" to enable everything. New file: core/hakmem_trace_master.h - HAKMEM_TRACE=all: Enable all trace modules - HAKMEM_TRACE=ptr,refill,free,mailbox: Enable specific modules - HAKMEM_TRACE_LEVEL=N: Set trace verbosity (1-3) - hak_trace_check(): Check if module should enable tracing Available trace modules: ptr, refill, superslab, ring, free, mailbox, registry Priority order: 1. HAKMEM_QUIET=1 → suppress all 2. Specific module ENV (e.g., HAKMEM_PTR_TRACE=1) 3. HAKMEM_TRACE=module1,module2 4. Default → disabled Updated files: - core/tiny_refill.h: Use hak_trace_check() for refill tracing - core/box/mailbox_box.c: Use hak_trace_check() for mailbox tracing Performance: No regression (72.9M ops/s) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
// mailbox_box.c - Publish Mailbox box (fully separated)
|
// mailbox_box.c - Publish Mailbox box (fully separated)
|
||||||
#include "mailbox_box.h"
|
#include "mailbox_box.h"
|
||||||
#include "hakmem_tiny.h"
|
#include "hakmem_tiny.h"
|
||||||
|
#include "hakmem_trace_master.h" // Phase 4c: Master trace control
|
||||||
#include "tiny_debug_ring.h"
|
#include "tiny_debug_ring.h"
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@ -55,14 +56,15 @@ extern unsigned long long g_mailbox_slow_discoveries[];
|
|||||||
void mailbox_box_register(int class_idx) {
|
void mailbox_box_register(int class_idx) {
|
||||||
if (g_tls_mailbox_registered[class_idx]) return;
|
if (g_tls_mailbox_registered[class_idx]) return;
|
||||||
g_mailbox_register_calls[class_idx]++;
|
g_mailbox_register_calls[class_idx]++;
|
||||||
// One-shot visibility trace (env: HAKMEM_TINY_RF_TRACE)
|
// One-shot visibility trace (env: HAKMEM_TINY_RF_TRACE or HAKMEM_TRACE=refill,mailbox)
|
||||||
|
// Phase 4c: Now uses hak_trace_check() for unified trace control
|
||||||
#if HAKMEM_BUILD_RELEASE
|
#if HAKMEM_BUILD_RELEASE
|
||||||
static const int trace_en = 0;
|
static const int trace_en = 0;
|
||||||
#else
|
#else
|
||||||
static int trace_en = -1;
|
static int trace_en = -1;
|
||||||
if (__builtin_expect(trace_en == -1, 0)) {
|
if (__builtin_expect(trace_en == -1, 0)) {
|
||||||
const char* e = getenv("HAKMEM_TINY_RF_TRACE");
|
trace_en = hak_trace_check("HAKMEM_TINY_RF_TRACE", "refill") ||
|
||||||
trace_en = (e && atoi(e) != 0) ? 1 : 0;
|
hak_trace_check("HAKMEM_TINY_MAILBOX_TRACE", "mailbox");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
pthread_once(&g_mailbox_tls_once, mailbox_tls_init);
|
pthread_once(&g_mailbox_tls_once, mailbox_tls_init);
|
||||||
@ -167,20 +169,20 @@ uintptr_t mailbox_box_peek_one(int class_idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t mailbox_box_fetch(int class_idx) {
|
uintptr_t mailbox_box_fetch(int class_idx) {
|
||||||
|
// Phase 4c: Unified trace control via hak_trace_check()
|
||||||
#if HAKMEM_BUILD_RELEASE
|
#if HAKMEM_BUILD_RELEASE
|
||||||
if (__builtin_expect(g_mailbox_trace_en == -1, 0)) g_mailbox_trace_en = 0;
|
if (__builtin_expect(g_mailbox_trace_en == -1, 0)) g_mailbox_trace_en = 0;
|
||||||
if (__builtin_expect(g_mailbox_slowdisc_en == -1, 0)) g_mailbox_slowdisc_en = 0;
|
if (__builtin_expect(g_mailbox_slowdisc_en == -1, 0)) g_mailbox_slowdisc_en = 0;
|
||||||
if (__builtin_expect(g_mailbox_slowdisc_period == -1, 0)) g_mailbox_slowdisc_period = 256;
|
if (__builtin_expect(g_mailbox_slowdisc_period == -1, 0)) g_mailbox_slowdisc_period = 256;
|
||||||
#else
|
#else
|
||||||
if (__builtin_expect(g_mailbox_trace_en == -1, 0)) {
|
if (__builtin_expect(g_mailbox_trace_en == -1, 0)) {
|
||||||
const char* e = getenv("HAKMEM_TINY_MAILBOX_TRACE");
|
g_mailbox_trace_en = hak_trace_check("HAKMEM_TINY_MAILBOX_TRACE", "mailbox");
|
||||||
g_mailbox_trace_en = (e && atoi(e) != 0) ? 1 : 0;
|
|
||||||
const char* l = getenv("HAKMEM_TINY_MAILBOX_TRACE_LIMIT");
|
const char* l = getenv("HAKMEM_TINY_MAILBOX_TRACE_LIMIT");
|
||||||
int v = l ? atoi(l) : 0;
|
int v = l ? atoi(l) : 0;
|
||||||
if (v > 0) g_mailbox_trace_limit = v;
|
if (v > 0) g_mailbox_trace_limit = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional slow discovery
|
// Optional slow discovery (not trace-related, keep original logic)
|
||||||
if (__builtin_expect(g_mailbox_slowdisc_en == -1, 0)) {
|
if (__builtin_expect(g_mailbox_slowdisc_en == -1, 0)) {
|
||||||
const char* e = getenv("HAKMEM_TINY_MAILBOX_SLOWDISC");
|
const char* e = getenv("HAKMEM_TINY_MAILBOX_SLOWDISC");
|
||||||
g_mailbox_slowdisc_en = (e ? ((atoi(e) != 0) ? 1 : 0) : 1);
|
g_mailbox_slowdisc_en = (e ? ((atoi(e) != 0) ? 1 : 0) : 1);
|
||||||
|
|||||||
144
core/hakmem_trace_master.h
Normal file
144
core/hakmem_trace_master.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// hakmem_trace_master.h - Master Trace Control
|
||||||
|
//
|
||||||
|
// ENV Cleanup Phase 4c: Unified trace control
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// HAKMEM_TRACE=all Enable ALL trace modules
|
||||||
|
// HAKMEM_TRACE=ptr,refill,free Enable specific modules (comma-separated)
|
||||||
|
// HAKMEM_TRACE_LEVEL=N Set trace verbosity (1=basic, 2=detailed, 3=verbose)
|
||||||
|
//
|
||||||
|
// Available trace modules:
|
||||||
|
// ptr - Pointer tracking (HAKMEM_PTR_TRACE, PTR_TRACE_ALL, PTR_TRACE_VERBOSE)
|
||||||
|
// refill - Refill path (HAKMEM_TINY_RF_TRACE)
|
||||||
|
// superslab - SuperSlab operations (HAKMEM_TINY_SUPERSLAB_TRACE)
|
||||||
|
// ring - Debug ring (HAKMEM_TINY_TRACE_RING)
|
||||||
|
// free - Free path (HAKMEM_FREE_ROUTE_TRACE, FREE_WRAP_TRACE)
|
||||||
|
// mailbox - Mailbox operations (HAKMEM_TINY_MAILBOX_TRACE)
|
||||||
|
// registry - Registry operations (HAKMEM_SUPER_REG_REQTRACE)
|
||||||
|
//
|
||||||
|
// Priority (highest to lowest):
|
||||||
|
// 1. HAKMEM_QUIET=1 → suppress all traces
|
||||||
|
// 2. Specific module ENV (e.g., HAKMEM_PTR_TRACE=1) → use that value
|
||||||
|
// 3. HAKMEM_TRACE=module1,module2 → enable listed modules
|
||||||
|
// 4. HAKMEM_TRACE=all → enable all
|
||||||
|
// 5. Default → disabled
|
||||||
|
//
|
||||||
|
// Integration example:
|
||||||
|
// Old: static int tr = -1;
|
||||||
|
// if (tr==-1) { const char* e = getenv("HAKMEM_FOO_TRACE"); tr = (e && *e != '0') ? 1 : 0; }
|
||||||
|
//
|
||||||
|
// New: static int tr = -1;
|
||||||
|
// if (tr==-1) { tr = hak_trace_check("HAKMEM_FOO_TRACE", "foo"); }
|
||||||
|
|
||||||
|
#ifndef HAKMEM_TRACE_MASTER_H
|
||||||
|
#define HAKMEM_TRACE_MASTER_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Trace module flags (bit positions)
|
||||||
|
#define HAK_TRACE_PTR (1 << 0)
|
||||||
|
#define HAK_TRACE_REFILL (1 << 1)
|
||||||
|
#define HAK_TRACE_SUPERSLAB (1 << 2)
|
||||||
|
#define HAK_TRACE_RING (1 << 3)
|
||||||
|
#define HAK_TRACE_FREE (1 << 4)
|
||||||
|
#define HAK_TRACE_MAILBOX (1 << 5)
|
||||||
|
#define HAK_TRACE_REGISTRY (1 << 6)
|
||||||
|
#define HAK_TRACE_ALL 0xFFFFFFFF
|
||||||
|
|
||||||
|
// Master trace state (cached at first access)
|
||||||
|
static int g_trace_master_mask = -1; // -1 = uninitialized
|
||||||
|
static int g_trace_level = -1;
|
||||||
|
static int g_trace_quiet = -1;
|
||||||
|
|
||||||
|
// Map module name to bit flag
|
||||||
|
static inline int hak_trace_name_to_flag(const char* name) {
|
||||||
|
if (!name || !*name) return 0;
|
||||||
|
if (strcmp(name, "all") == 0) return HAK_TRACE_ALL;
|
||||||
|
if (strcmp(name, "ptr") == 0) return HAK_TRACE_PTR;
|
||||||
|
if (strcmp(name, "refill") == 0) return HAK_TRACE_REFILL;
|
||||||
|
if (strcmp(name, "superslab") == 0) return HAK_TRACE_SUPERSLAB;
|
||||||
|
if (strcmp(name, "ring") == 0) return HAK_TRACE_RING;
|
||||||
|
if (strcmp(name, "free") == 0) return HAK_TRACE_FREE;
|
||||||
|
if (strcmp(name, "mailbox") == 0) return HAK_TRACE_MAILBOX;
|
||||||
|
if (strcmp(name, "registry") == 0) return HAK_TRACE_REGISTRY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse comma-separated module list
|
||||||
|
static inline int hak_trace_parse_modules(const char* str) {
|
||||||
|
if (!str || !*str) return 0;
|
||||||
|
|
||||||
|
int mask = 0;
|
||||||
|
char buf[256];
|
||||||
|
strncpy(buf, str, sizeof(buf) - 1);
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
|
||||||
|
char* token = strtok(buf, ",");
|
||||||
|
while (token) {
|
||||||
|
// Trim whitespace
|
||||||
|
while (*token == ' ') token++;
|
||||||
|
char* end = token + strlen(token) - 1;
|
||||||
|
while (end > token && *end == ' ') *end-- = '\0';
|
||||||
|
|
||||||
|
mask |= hak_trace_name_to_flag(token);
|
||||||
|
token = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize master trace settings (called once, lazily)
|
||||||
|
static inline void hak_trace_master_init(void) {
|
||||||
|
if (__builtin_expect(g_trace_master_mask >= 0, 1)) return;
|
||||||
|
|
||||||
|
// Check HAKMEM_QUIET first (highest priority)
|
||||||
|
const char* quiet = getenv("HAKMEM_QUIET");
|
||||||
|
g_trace_quiet = (quiet && *quiet && *quiet != '0') ? 1 : 0;
|
||||||
|
|
||||||
|
// Check HAKMEM_TRACE
|
||||||
|
const char* trace = getenv("HAKMEM_TRACE");
|
||||||
|
g_trace_master_mask = hak_trace_parse_modules(trace);
|
||||||
|
|
||||||
|
// Check HAKMEM_TRACE_LEVEL
|
||||||
|
const char* lvl = getenv("HAKMEM_TRACE_LEVEL");
|
||||||
|
if (lvl && *lvl) {
|
||||||
|
int v = atoi(lvl);
|
||||||
|
if (v < 0) v = 0;
|
||||||
|
if (v > 3) v = 3;
|
||||||
|
g_trace_level = v;
|
||||||
|
} else {
|
||||||
|
g_trace_level = (g_trace_master_mask > 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a specific trace module should be enabled
|
||||||
|
// env_name: The specific ENV variable (e.g., "HAKMEM_PTR_TRACE")
|
||||||
|
// module: The module name for HAKMEM_TRACE (e.g., "ptr")
|
||||||
|
// Returns: 1 if trace should be enabled, 0 otherwise
|
||||||
|
static inline int hak_trace_check(const char* env_name, const char* module) {
|
||||||
|
hak_trace_master_init();
|
||||||
|
|
||||||
|
// HAKMEM_QUIET overrides everything
|
||||||
|
if (g_trace_quiet) return 0;
|
||||||
|
|
||||||
|
// Check specific ENV first (allows explicit enable/disable)
|
||||||
|
const char* e = getenv(env_name);
|
||||||
|
if (e && *e) {
|
||||||
|
return (*e != '0') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to master trace mask
|
||||||
|
int flag = hak_trace_name_to_flag(module);
|
||||||
|
if (flag && (g_trace_master_mask & flag)) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check trace level for a module
|
||||||
|
// Returns current trace level if module is enabled, 0 otherwise
|
||||||
|
static inline int hak_trace_level(const char* env_name, const char* module) {
|
||||||
|
if (!hak_trace_check(env_name, module)) return 0;
|
||||||
|
return g_trace_level > 0 ? g_trace_level : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAKMEM_TRACE_MASTER_H
|
||||||
@ -2,6 +2,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include "hakmem_tiny_superslab.h"
|
#include "hakmem_tiny_superslab.h"
|
||||||
|
#include "hakmem_trace_master.h" // Phase 4c: Master trace control
|
||||||
#include "slab_handle.h"
|
#include "slab_handle.h"
|
||||||
#include "tiny_sticky.h"
|
#include "tiny_sticky.h"
|
||||||
#include "tiny_ready.h"
|
#include "tiny_ready.h"
|
||||||
@ -86,13 +87,13 @@ static inline SuperSlab* tiny_refill_try_fast(int class_idx, TinyTLSSlab* tls) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// One-shot entry trace (env: HAKMEM_TINY_RF_TRACE), disabled in release builds
|
// One-shot entry trace (env: HAKMEM_TINY_RF_TRACE or HAKMEM_TRACE=refill)
|
||||||
|
// Phase 4c: Now uses hak_trace_check() for unified trace control
|
||||||
#if !HAKMEM_BUILD_RELEASE
|
#if !HAKMEM_BUILD_RELEASE
|
||||||
do {
|
do {
|
||||||
static int en = -1; static _Atomic int printed[8];
|
static int en = -1; static _Atomic int printed[8];
|
||||||
if (__builtin_expect(en == -1, 0)) {
|
if (__builtin_expect(en == -1, 0)) {
|
||||||
const char* e = getenv("HAKMEM_TINY_RF_TRACE");
|
en = hak_trace_check("HAKMEM_TINY_RF_TRACE", "refill");
|
||||||
en = (e && atoi(e) != 0) ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
if (en) {
|
if (en) {
|
||||||
int expected = 0;
|
int expected = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user