// tiny_c7_ultra_segment.c - C7 ULTRA 専用セグメント管理(UF-3) #include "box/tiny_c7_ultra_segment_box.h" #include #include #include #include #include // 2MiB セグメントを 64KiB ページに分割(C7 専用、pow2 で mask しやすく) #define TINY_C7_ULTRA_SEG_SIZE ((size_t)(2 * 1024 * 1024)) #define TINY_C7_ULTRA_PAGE_SIZE ((size_t)(64 * 1024)) #define TINY_C7_ULTRA_PAGE_SHIFT 16 // 64KiB = 2^16 (for O(1) bit shift instead of division) static __thread tiny_c7_ultra_segment_t* g_ultra_seg; static inline void tiny_c7_ultra_segment_clear(tiny_c7_ultra_segment_t* seg) { if (!seg) return; seg->base = NULL; seg->seg_size = 0; seg->page_size = 0; seg->num_pages = 0; seg->pages = NULL; } tiny_c7_ultra_segment_t* tiny_c7_ultra_segment_acquire(void) { if (g_ultra_seg) { return g_ultra_seg; } tiny_c7_ultra_segment_t* seg = (tiny_c7_ultra_segment_t*)calloc(1, sizeof(tiny_c7_ultra_segment_t)); if (!seg) { return NULL; } seg->seg_size = TINY_C7_ULTRA_SEG_SIZE; seg->page_size = TINY_C7_ULTRA_PAGE_SIZE; seg->num_pages = (uint32_t)(seg->seg_size / seg->page_size); seg->pages = (tiny_c7_ultra_page_meta_t*)calloc(seg->num_pages, sizeof(tiny_c7_ultra_page_meta_t)); if (!seg->pages) { free(seg); return NULL; } void* base = mmap(NULL, seg->seg_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (base == MAP_FAILED) { int saved = errno; free(seg->pages); free(seg); (void)saved; return NULL; } seg->base = base; g_ultra_seg = seg; return seg; } void tiny_c7_ultra_segment_release(tiny_c7_ultra_segment_t* seg) { if (!seg) return; if (seg->base && seg->seg_size) { munmap(seg->base, seg->seg_size); } free(seg->pages); if (seg == g_ultra_seg) { g_ultra_seg = NULL; } free(seg); } tiny_c7_ultra_segment_t* tiny_c7_ultra_segment_from_ptr(void* p) { tiny_c7_ultra_segment_t* seg = g_ultra_seg; if (!seg || !seg->base || seg->seg_size == 0) return NULL; uintptr_t base = (uintptr_t)seg->base; uintptr_t addr = (uintptr_t)p; if (addr < base || addr >= base + seg->seg_size) { return NULL; } return seg; } tiny_c7_ultra_page_meta_t* tiny_c7_ultra_page_of(void* p, tiny_c7_ultra_segment_t** out_seg, uint32_t* out_page_idx) { tiny_c7_ultra_segment_t* seg = tiny_c7_ultra_segment_from_ptr(p); if (!seg) { return NULL; } uintptr_t base = (uintptr_t)seg->base; uintptr_t addr = (uintptr_t)p; size_t offset = (size_t)(addr - base); // Phase PERF-ULTRA-REFILL-OPT-1a: Replace division with bit shift for O(1) lookup uint32_t idx = (uint32_t)(offset >> TINY_C7_ULTRA_PAGE_SHIFT); if (idx >= seg->num_pages) { return NULL; } if (out_seg) { *out_seg = seg; } if (out_page_idx) { *out_page_idx = idx; } return &seg->pages[idx]; }