Files
hakmem/core/box/tiny_policy_learner_box.c

82 lines
2.5 KiB
C
Raw Normal View History

// tiny_policy_learner_box.c - Placeholder learner hook
#include "tiny_policy_learner_box.h"
#include "tiny_class_policy_box.h"
#include "tiny_class_stats_box.h"
#include <stdint.h>
#include <stdio.h>
// Simple OBSERVE/LEARN rule (auto profile only):
// - C7 は常に ON (page + warm, cap=8)
// - それ以外のクラスから score = shared_lock*4 + uc_miss の上位2つだけ page/warm を ON
// - warm_cap は C5C7:8, それ以外:4
// - スコアが 0 なら何も変更しない
void tiny_policy_learner_tick(void) {
if (!tiny_class_policy_is_auto()) {
return;
}
TinyClassStatsThread snap = {0};
tiny_class_stats_snapshot_global(&snap);
// 事前に全クラスを OFF ベースに初期化cap はデフォルト値に)
for (int c = 0; c < TINY_NUM_CLASSES; c++) {
TinyClassPolicy* p = &g_tiny_class_policy[c];
p->page_box_enabled = 0;
p->warm_enabled = 0;
p->warm_cap = (c >= 5) ? 8 : 4;
p->tls_carve_enabled = 0;
}
// C7 は常に ON
g_tiny_class_policy[7].page_box_enabled = 1;
g_tiny_class_policy[7].warm_enabled = 1;
g_tiny_class_policy[7].warm_cap = 8;
g_tiny_class_policy[7].tls_carve_enabled = 1;
// C7 を除く上位2クラスをスコアで選択
int top1 = -1, top2 = -1;
uint64_t v1 = 0, v2 = 0;
for (int i = 0; i < TINY_NUM_CLASSES; i++) {
if (i == 7) continue;
uint64_t score = snap.shared_lock[i] * 4 + snap.uc_miss[i];
if (score > v1) {
top2 = top1;
v2 = v1;
top1 = i;
v1 = score;
} else if (score > v2) {
top2 = i;
v2 = score;
}
}
// スコアが全く無い場合は C7 だけ維持
if (v1 == 0) {
return;
}
if (top1 >= 0) {
TinyClassPolicy* p = &g_tiny_class_policy[top1];
p->page_box_enabled = 1;
p->warm_enabled = 1;
p->tls_carve_enabled = 1;
}
if (top2 >= 0 && v2 > 0) {
TinyClassPolicy* p = &g_tiny_class_policy[top2];
p->page_box_enabled = 1;
p->warm_enabled = 1;
p->tls_carve_enabled = 1;
}
// 1-shot ログ(最多 4 回まで)
static _Atomic uint32_t auto_logs = 0;
if (tiny_policy_log_enabled()) {
uint32_t n = atomic_fetch_add_explicit(&auto_logs, 1, memory_order_relaxed);
if (n < 4) {
fprintf(stderr, "[POLICY_AUTO_UPDATE] profile=auto (top=%d/%d)\n", top1, top2);
tiny_class_policy_dump(NULL);
}
}
}