78 lines
3.5 KiB
C
78 lines
3.5 KiB
C
|
|
#pragma once
|
|||
|
|
|
|||
|
|
#include <stdbool.h>
|
|||
|
|
#include <stdint.h>
|
|||
|
|
#include <stddef.h>
|
|||
|
|
#ifndef TINY_NUM_CLASSES
|
|||
|
|
#define TINY_NUM_CLASSES 8
|
|||
|
|
#endif
|
|||
|
|
// SuperRegBox (設計メモ / API スタブ)
|
|||
|
|
// -------------------------------------
|
|||
|
|
// 役割:
|
|||
|
|
// - g_super_reg / g_super_reg_by_class への直接依存を断ち、レジストリ容量を
|
|||
|
|
// プロファイル(full/prod/bench/larson_guard 等)で切り替えられるようにする箱。
|
|||
|
|
// - Box 内部だけで容量決定・確保・破棄を閉じ、外側は薄い API を呼ぶだけにする。
|
|||
|
|
//
|
|||
|
|
// プロファイル方針(案):
|
|||
|
|
// - full/prod : 現行の SUPER_REG_SIZE (=1,048,576) と SUPER_REG_PER_CLASS (=16,384) を維持
|
|||
|
|
// - bench : SUPER_REG_SIZE を 1/16〜1/8 程度 (例: 65,536)、per-class は 1,024 などに縮小
|
|||
|
|
// - guard : bench 同等かさらに小さくして fail-fast(ENOMEM)を優先
|
|||
|
|
//
|
|||
|
|
// スレッド安全性:
|
|||
|
|
// - 既存のロック/atomic 公算を流用しつつ、構造体にまとめて「初期化済みか」を判定。
|
|||
|
|
//
|
|||
|
|
// 想定 API(実装は今後):
|
|||
|
|
|
|||
|
|
typedef struct SuperSlab SuperSlab;
|
|||
|
|
typedef struct SuperRegBox SuperRegBox;
|
|||
|
|
struct SuperRegEntry;
|
|||
|
|
|
|||
|
|
// プロファイル/ENV に応じて容量を決定し、内部配列を確保。
|
|||
|
|
// profile が NULL のときは HAKMEM_PROFILE (bench / full など) を読む。
|
|||
|
|
void super_reg_init(SuperRegBox* box, const char* profile);
|
|||
|
|
|
|||
|
|
// 現在有効なスロット数/マスク
|
|||
|
|
int super_reg_effective_size(void);
|
|||
|
|
int super_reg_effective_mask(void);
|
|||
|
|
int super_reg_effective_per_class(void);
|
|||
|
|
|
|||
|
|
// レジストリ実体へのアクセス(Box 内部で動的確保)
|
|||
|
|
struct SuperRegEntry* super_reg_entries(void);
|
|||
|
|
SuperSlab** super_reg_by_class_slots(void);
|
|||
|
|
int super_reg_by_class_stride(void);
|
|||
|
|
static inline SuperSlab* super_reg_by_class_at(int class_idx, int idx) {
|
|||
|
|
SuperSlab** slots = super_reg_by_class_slots();
|
|||
|
|
int stride = super_reg_by_class_stride();
|
|||
|
|
if (!slots || stride <= 0 || class_idx < 0 || idx < 0 ||
|
|||
|
|
class_idx >= TINY_NUM_CLASSES || idx >= stride) {
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
return slots[class_idx * stride + idx];
|
|||
|
|
}
|
|||
|
|
static inline void super_reg_by_class_set(int class_idx, int idx, SuperSlab* ss) {
|
|||
|
|
SuperSlab** slots = super_reg_by_class_slots();
|
|||
|
|
int stride = super_reg_by_class_stride();
|
|||
|
|
if (!slots || stride <= 0 || class_idx < 0 || idx < 0 ||
|
|||
|
|
class_idx >= TINY_NUM_CLASSES || idx >= stride) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
slots[class_idx * stride + idx] = ss;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Superslab 登録/解除(既存の hak_super_register/unregister 相当を箱内に閉じ込める)
|
|||
|
|
bool super_reg_register(SuperRegBox* box, SuperSlab* ss, uint32_t class_idx);
|
|||
|
|
void super_reg_unregister(SuperRegBox* box, SuperSlab* ss, uint32_t class_idx);
|
|||
|
|
|
|||
|
|
// アドレス検索/クラス別イテレーション(必要最小限の薄い API)
|
|||
|
|
SuperSlab* super_reg_find_by_addr(SuperRegBox* box, void* ptr);
|
|||
|
|
SuperSlab* super_reg_iter_for_class(SuperRegBox* box, uint32_t class_idx, void** cursor);
|
|||
|
|
|
|||
|
|
// 将来のメモリ削減策(コメントのみ)
|
|||
|
|
// - g_super_reg/g_super_reg_by_class を「malloc/mmap でプロファイル毎に確保」するようにし、
|
|||
|
|
// BSS から切り離す。
|
|||
|
|
// - bench プロファイルでは固定長を大幅に縮め、足りなければ ENOMEM を返して fail-fast。
|
|||
|
|
// - prod では現行サイズを維持しつつ、Box 境界でのみアクセスさせる。***
|
|||
|
|
|
|||
|
|
// 前方宣言(実装は既存の superslab に依存)
|
|||
|
|
// typedef struct SuperSlab SuperSlab; // 上で宣言済み
|