Files
hakmem/core/tiny_c7_ultra_segment.c
2025-12-10 22:19:32 +09:00

107 lines
3.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// tiny_c7_ultra_segment.c - C7 ULTRA 専用セグメント管理UF-3
#include "box/tiny_c7_ultra_segment_box.h"
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
// 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))
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);
uint32_t idx = (uint32_t)(offset / seg->page_size);
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];
}