Skip to content

Commit 6fb58fb

Browse files
committed
orchestrator: opt-in per-constraint engine diagnostic
The engine already reports source names, conflicts, and saturation, but never the actual constraint operands. Add engine_report_constraints: for each quantity, dump every constraint's op, value(s), emitting rule, and whether the resolver rejected it — the way to see which rule pins a quantity's lo/hi. Off by default; gated by KASLD_DEBUG_CONSTRAINTS so normal --verbose stays uncluttered, and written to stderr so it never disturbs -j.
1 parent fcdc87d commit 6fb58fb

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

src/orchestrator.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,47 @@ static void engine_report_corroboration(const struct engine *e) {
24242424
}
24252425
}
24262426

2427+
/* Per-constraint dump: every constraint on each quantity, with its op,
2428+
* operand(s), emitting rule, and whether the resolver rejected it. Shows WHAT
2429+
* each source bounds, not just that it does — the way to see which rule pins a
2430+
* quantity's lo/hi. Opt-in via KASLD_DEBUG_CONSTRAINTS so normal --verbose
2431+
* stays uncluttered. Diagnostic only (stderr). */
2432+
static void engine_report_constraints(const struct engine *e) {
2433+
if (!getenv("KASLD_DEBUG_CONSTRAINTS"))
2434+
return;
2435+
for (int q = 0; q < Q__COUNT; q++) {
2436+
int header = 0;
2437+
for (int i = 0; i < e->n_constraints; i++) {
2438+
const struct constraint *cc = &e->constraints[i];
2439+
if ((int)cc->q != q)
2440+
continue;
2441+
int rejected = 0;
2442+
for (int c = 0; c < e->n_conflicts[q]; c++)
2443+
if (e->conflicts[q][c] == cc->id) {
2444+
rejected = 1;
2445+
break;
2446+
}
2447+
if (!header) {
2448+
fprintf(stderr, "[engine] %s constraints:\n", quantities[q].name);
2449+
header = 1;
2450+
}
2451+
const char *o = cc->origin[0] ? cc->origin : "rule";
2452+
const char *tag = rejected ? " [rejected]" : "";
2453+
/* Two-operand ops carry a range / modulus; the rest are a single value
2454+
* against the op symbol from constraint_op_name(). */
2455+
if (cc->op == C_EXCLUDE)
2456+
fprintf(stderr, "[engine] exclude [0x%016lx, 0x%016lx] (%s)%s\n",
2457+
cc->value, cc->value2, o, tag);
2458+
else if (cc->op == C_STRIDE)
2459+
fprintf(stderr, "[engine] stride %lu mod %lu (%s)%s\n", cc->value,
2460+
cc->value2, o, tag);
2461+
else
2462+
fprintf(stderr, "[engine] %s 0x%016lx (%s)%s\n",
2463+
constraint_op_name(cc->op), cc->value, o, tag);
2464+
}
2465+
}
2466+
}
2467+
24272468
/* Report any resolver saturation flags. None of the caps bind on realistic
24282469
* deduped workloads; surfacing a hit makes the dropped-info case observable
24292470
* rather than silent if scale ever grows. Diagnostic only (stderr, --verbose).
@@ -2488,6 +2529,7 @@ static void engine_resolve(struct engine *e) {
24882529
engine_report_saturation(e);
24892530
orchestrator_report_saturation();
24902531
}
2532+
engine_report_constraints(e); /* opt-in via KASLD_DEBUG_CONSTRAINTS */
24912533
}
24922534
#endif /* !KASLD_TESTING (engine_resolve/build need the components+engine.c) \
24932535
*/

0 commit comments

Comments
 (0)