Files
hakmem/core/box/ss_prefault_box.h

81 lines
2.9 KiB
C
Raw Normal View History

// ss_prefault_box.h - Box: SuperSlab Page Prefaulting Policy
// Purpose: Control SuperSlab prefault strategy (MAP_POPULATE / manual touch)
// Box Theory:
// - This box owns「いつ / どの程度 pf を前倒しするか」というポリシーだけを担当。
// - 実際の mmap は ss_os_acquire_box下層、Superslab 初期化は ss_allocation_box上層が担当。
//
// Responsibilities:
// - HAKMEM_SS_PREFAULT の値から prefault ポリシーを決定
// - 必要に応じて SuperSlab 全域を 1 回だけ touch して page-in する
//
// ENV:
// HAKMEM_SS_PREFAULT=0 Off 既存動作に近い。g_ss_populate_once のワンショットのみ)
// HAKMEM_SS_PREFAULT=1 POPULATE MAP_POPULATE のみ使用)
// HAKMEM_SS_PREFAULT=2 TOUCH MAP_POPULATE + 手動4KB touch
// HAKMEM_SS_PREFAULT=3 ASYNC (予約値。現状は TOUCH と同等に扱う)
//
// Default:
// - 未指定時は 1 (POPULATE) とし、SuperSlab 取得時の page fault を大きく削減する。
#ifndef HAKMEM_SS_PREFAULT_BOX_H
#define HAKMEM_SS_PREFAULT_BOX_H
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
typedef enum {
SS_PREFAULT_OFF = 0, // No prefault (legacy: g_ss_populate_once のみ)
SS_PREFAULT_POPULATE = 1, // MAP_POPULATE only
SS_PREFAULT_TOUCH = 2, // MAP_POPULATE + manual page touch
SS_PREFAULT_ASYNC = 3 // Reserved for future background prefault
} SSPrefaultPolicy;
// Return current prefault policy (parsed once from HAKMEM_SS_PREFAULT).
static inline SSPrefaultPolicy ss_prefault_policy(void)
{
static int cached = -1;
if (cached != -1) {
return (SSPrefaultPolicy)cached;
}
// 一時的な安全デフォルト: OFF
// 4MB MAP_POPULATE 問題の影響を避けつつ、必要なときだけ明示的に ON にする)
int policy = SS_PREFAULT_OFF;
const char* env = getenv("HAKMEM_SS_PREFAULT");
if (env && *env) {
int v = atoi(env);
if (v < 0) v = 0;
if (v > 3) v = 3;
policy = v;
}
cached = policy;
return (SSPrefaultPolicy)policy;
}
// Prefault a contiguous SuperSlab region by touching one byte per page.
// Caller is expected to call this「mmap直後」に 1 回だけ実行する。
static inline void ss_prefault_region(void* addr, size_t size)
{
SSPrefaultPolicy policy = ss_prefault_policy();
if (policy < SS_PREFAULT_TOUCH) {
// POPULATE または OFF の場合は手動 touch は行わない。
return;
}
if (!addr || size == 0) {
return;
}
long ps = sysconf(_SC_PAGESIZE);
size_t page = (ps > 0) ? (size_t)ps : (size_t)4096;
volatile char* p = (volatile char*)addr;
for (size_t off = 0; off < size; off += page) {
(void)p[off];
}
// Ensure last byte is also touched (covers exact multiples).
(void)p[size - 1];
}
#endif // HAKMEM_SS_PREFAULT_BOX_H