2025-12-06 01:34:04 +09:00
|
|
|
|
// tiny_policy_learner_box.c - Placeholder learner hook
|
|
|
|
|
|
|
|
|
|
|
|
#include "tiny_policy_learner_box.h"
|
2025-12-06 01:44:05 +09:00
|
|
|
|
#include "tiny_class_policy_box.h"
|
|
|
|
|
|
#include "tiny_class_stats_box.h"
|
|
|
|
|
|
#include <stdint.h>
|
2025-12-07 03:12:27 +09:00
|
|
|
|
#include <stdio.h>
|
2025-12-06 01:34:04 +09:00
|
|
|
|
|
2025-12-07 03:12:27 +09:00
|
|
|
|
// 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 は C5–C7:8, それ以外:4
|
|
|
|
|
|
// - スコアが 0 なら何も変更しない
|
2025-12-06 01:34:04 +09:00
|
|
|
|
void tiny_policy_learner_tick(void) {
|
2025-12-07 03:12:27 +09:00
|
|
|
|
if (!tiny_class_policy_is_auto()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-06 01:44:05 +09:00
|
|
|
|
TinyClassStatsThread snap = {0};
|
|
|
|
|
|
tiny_class_stats_snapshot_global(&snap);
|
|
|
|
|
|
|
2025-12-07 03:12:27 +09:00
|
|
|
|
// 事前に全クラスを 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クラスをスコアで選択
|
2025-12-06 01:44:05 +09:00
|
|
|
|
int top1 = -1, top2 = -1;
|
|
|
|
|
|
uint64_t v1 = 0, v2 = 0;
|
|
|
|
|
|
for (int i = 0; i < TINY_NUM_CLASSES; i++) {
|
2025-12-07 03:12:27 +09:00
|
|
|
|
if (i == 7) continue;
|
|
|
|
|
|
uint64_t score = snap.shared_lock[i] * 4 + snap.uc_miss[i];
|
|
|
|
|
|
if (score > v1) {
|
2025-12-06 01:44:05 +09:00
|
|
|
|
top2 = top1;
|
|
|
|
|
|
v2 = v1;
|
|
|
|
|
|
top1 = i;
|
2025-12-07 03:12:27 +09:00
|
|
|
|
v1 = score;
|
|
|
|
|
|
} else if (score > v2) {
|
2025-12-06 01:44:05 +09:00
|
|
|
|
top2 = i;
|
2025-12-07 03:12:27 +09:00
|
|
|
|
v2 = score;
|
2025-12-06 01:44:05 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-07 03:12:27 +09:00
|
|
|
|
// スコアが全く無い場合は C7 だけ維持
|
2025-12-06 01:44:05 +09:00
|
|
|
|
if (v1 == 0) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-07 03:12:27 +09:00
|
|
|
|
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);
|
2025-12-06 01:44:05 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-06 01:34:04 +09:00
|
|
|
|
}
|