149 lines
5.3 KiB
C
149 lines
5.3 KiB
C
|
|
// ss_addr_map_box.h - Phase 9-1: SuperSlab Address Map Box
|
|||
|
|
// Purpose: O(1) address → SuperSlab* mapping (replace linear search)
|
|||
|
|
// Contract: Fast lookup with hash table (O(1) amortized, upgrade to true O(1) later)
|
|||
|
|
//
|
|||
|
|
// Box Pattern:
|
|||
|
|
// - Single Responsibility: Address→SuperSlab mapping ONLY
|
|||
|
|
// - Clear Contract: ss_map_lookup(ptr) returns SuperSlab* in O(1) amortized
|
|||
|
|
// - Observable: Debug macros log all lookups in non-release builds
|
|||
|
|
// - Composable: Can coexist with legacy registry during migration
|
|||
|
|
//
|
|||
|
|
// Performance Target:
|
|||
|
|
// - Current: Linear search 50-80 cycles
|
|||
|
|
// - Phase 9-1: Hash table ~10-20 cycles
|
|||
|
|
// - Future: 2-tier page table ~5-10 cycles (Phase 9-2)
|
|||
|
|
|
|||
|
|
#ifndef HAK_BOX_SS_ADDR_MAP_H
|
|||
|
|
#define HAK_BOX_SS_ADDR_MAP_H
|
|||
|
|
|
|||
|
|
#include <stddef.h>
|
|||
|
|
#include <stdint.h>
|
|||
|
|
#include "../hakmem_build_flags.h"
|
|||
|
|
|
|||
|
|
// Forward declaration
|
|||
|
|
struct SuperSlab;
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// Hash Table Entry (Chaining for collision resolution)
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
typedef struct SSMapEntry {
|
|||
|
|
void* base; // SuperSlab base address (key)
|
|||
|
|
struct SuperSlab* ss; // SuperSlab pointer (value)
|
|||
|
|
struct SSMapEntry* next; // Chain for collisions
|
|||
|
|
} SSMapEntry;
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// Address Map Structure
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
// Hash table size: 8192 buckets (2^13)
|
|||
|
|
// - Trade-off: Memory vs collision rate
|
|||
|
|
// - 8K buckets × 8 bytes = 64KB (acceptable overhead)
|
|||
|
|
// - Load factor target: <2 entries/bucket average
|
|||
|
|
#define SS_MAP_HASH_SIZE 8192
|
|||
|
|
|
|||
|
|
typedef struct {
|
|||
|
|
SSMapEntry* buckets[SS_MAP_HASH_SIZE]; // Hash table buckets
|
|||
|
|
size_t count; // Total entries (for stats)
|
|||
|
|
size_t collisions; // Collision counter (for stats)
|
|||
|
|
} SSAddrMap;
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// API Functions
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
// Initialize map (call once at startup)
|
|||
|
|
void ss_map_init(SSAddrMap* map);
|
|||
|
|
|
|||
|
|
// Insert SuperSlab into map
|
|||
|
|
// Precondition: base must be SuperSlab-aligned (512KB/1MB/2MB)
|
|||
|
|
// Contract: O(1) insertion
|
|||
|
|
void ss_map_insert(SSAddrMap* map, void* base, struct SuperSlab* ss);
|
|||
|
|
|
|||
|
|
// Lookup SuperSlab by pointer
|
|||
|
|
// Contract: O(1) amortized lookup
|
|||
|
|
// Returns: SuperSlab* if found, NULL if not found
|
|||
|
|
struct SuperSlab* ss_map_lookup(SSAddrMap* map, void* ptr);
|
|||
|
|
|
|||
|
|
// Remove SuperSlab from map
|
|||
|
|
// Contract: O(1) amortized removal
|
|||
|
|
void ss_map_remove(SSAddrMap* map, void* base);
|
|||
|
|
|
|||
|
|
// Shutdown map (free all entries)
|
|||
|
|
void ss_map_shutdown(SSAddrMap* map);
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// Statistics (Debug builds only)
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
#if !HAKMEM_BUILD_RELEASE
|
|||
|
|
// Print map statistics (count, collisions, load factor)
|
|||
|
|
void ss_map_print_stats(SSAddrMap* map);
|
|||
|
|
|
|||
|
|
// Get collision rate (for performance tuning)
|
|||
|
|
double ss_map_collision_rate(SSAddrMap* map);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// Debug Macros (Observable Box Pattern)
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
#if !HAKMEM_BUILD_RELEASE
|
|||
|
|
#define SS_MAP_LOOKUP(map, ptr) \
|
|||
|
|
({ \
|
|||
|
|
void* _ptr = (ptr); \
|
|||
|
|
struct SuperSlab* _ss = ss_map_lookup(map, _ptr); \
|
|||
|
|
if (getenv("HAKMEM_SS_MAP_TRACE")) { \
|
|||
|
|
fprintf(stderr, "[SS_MAP_LOOKUP] ptr=%p -> ss=%p\n", _ptr, (void*)_ss); \
|
|||
|
|
} \
|
|||
|
|
_ss; \
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
#define SS_MAP_INSERT(map, base, ss) \
|
|||
|
|
do { \
|
|||
|
|
if (getenv("HAKMEM_SS_MAP_TRACE")) { \
|
|||
|
|
fprintf(stderr, "[SS_MAP_INSERT] base=%p ss=%p\n", (void*)(base), (void*)(ss)); \
|
|||
|
|
} \
|
|||
|
|
ss_map_insert(map, base, ss); \
|
|||
|
|
} while(0)
|
|||
|
|
|
|||
|
|
#define SS_MAP_REMOVE(map, base) \
|
|||
|
|
do { \
|
|||
|
|
if (getenv("HAKMEM_SS_MAP_TRACE")) { \
|
|||
|
|
fprintf(stderr, "[SS_MAP_REMOVE] base=%p\n", (void*)(base)); \
|
|||
|
|
} \
|
|||
|
|
ss_map_remove(map, base); \
|
|||
|
|
} while(0)
|
|||
|
|
#else
|
|||
|
|
// Release builds: Direct function calls (no overhead)
|
|||
|
|
#define SS_MAP_LOOKUP(map, ptr) ss_map_lookup(map, ptr)
|
|||
|
|
#define SS_MAP_INSERT(map, base, ss) ss_map_insert(map, base, ss)
|
|||
|
|
#define SS_MAP_REMOVE(map, base) ss_map_remove(map, base)
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// Hash Function (Internal, exposed for testing)
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
// Hash pointer to bucket index
|
|||
|
|
// Strategy: Use upper bits (SuperSlab-aligned, lower bits are 0)
|
|||
|
|
// - ptr >> 19 (min SuperSlab size 512KB = 2^19)
|
|||
|
|
// - & (SS_MAP_HASH_SIZE - 1) for modulo
|
|||
|
|
static inline size_t ss_map_hash(void* ptr) {
|
|||
|
|
uintptr_t addr = (uintptr_t)ptr;
|
|||
|
|
// Shift by 19 bits (512KB alignment minimum)
|
|||
|
|
// Then mask to table size
|
|||
|
|
return (addr >> 19) & (SS_MAP_HASH_SIZE - 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// Global Instance (TLS or Global, TBD in Phase 9-1-4)
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
// For now: Global instance (shared across threads, needs lock)
|
|||
|
|
// Phase 9-1-4: Consider TLS instance for lock-free access
|
|||
|
|
extern SSAddrMap g_ss_addr_map;
|
|||
|
|
|
|||
|
|
#endif // HAK_BOX_SS_ADDR_MAP_H
|