feat(scheduler-sim-decision-trace): plan/verdict counters, search-end, summary tallies, rollback merging

Task 1.5: per-requirement plan counts and search-end statements,
decision-wide counters exact past truncation, summary-level position
tallies (per verdict kind and per limit), merged rollback entries.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-08 08:21:57 +00:00
parent e06bdc290b
commit d277bfb657
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
4 changed files with 1159 additions and 15 deletions

View file

@ -141,8 +141,8 @@ typedef struct {
* Entry types (design.md "Logical Data Model"). Every stored entry renders
* as exactly one line in the budgeted sections (requirement, cluster-wide
* check, plan and host), so the number of stored entries is the number of
* budgeted lines. The check rows, host rows, search-end, position-summary
* and rollback entries are added by the tasks that capture them.
* budgeted lines. The check rows and host rows are added by the task that
* captures them (TraceCapture).
*/
typedef enum {
SCHED_TRACE_E_RESREQ_BEGIN = 0, /* requirement named by the path */
@ -163,6 +163,11 @@ typedef enum {
SCHED_TRACE_E_HOST, /* host verdict (5.1-5.7, 5.10) */
SCHED_TRACE_E_COMMIT, /* committed plan (4.5) */
SCHED_TRACE_E_FINALIZE_FAILED, /* allocation build failed (4.5) */
SCHED_TRACE_E_SEARCH_END, /* plan counts of a requirement, and
* the statement (4.6, 4.7, 4.9) */
SCHED_TRACE_E_POS_SUMMARY, /* summary level: the position end with
* its verdict counts (5.9) */
SCHED_TRACE_E_ROLLBACK, /* released hosts, merged (5.8) */
SCHED_TRACE_E_NTYPES
} sched_trace_entry_type_t;
@ -174,6 +179,24 @@ typedef enum {
SCHED_TRACE_PHASE_PERHOST /* per-host resource and limit check */
} sched_trace_phase_t;
/* The statement a search-end line ends with (design "TraceHooks", search
* end). At most one; none when the search returned rc != 0. */
typedef enum {
SCHED_TRACE_SEARCH_NO_STMT = 0,
SCHED_TRACE_SEARCH_NONE_GENERATED, /* g == 0 (4.7) */
SCHED_TRACE_SEARCH_ALL_DISCARDED, /* g > 0 and d == g (4.9) */
SCHED_TRACE_SEARCH_NONE_PLACED /* t > 0, no plan ended in an
* internal error (4.6) */
} sched_trace_search_stmt_t;
/* Hosts of one position that hit one limit (5.9): `count` hosts with a
* limit-exceeded verdict hit the limit `limit` in scope instance `scope`. */
typedef struct {
const char* limit; /* arena copy */
const char* scope; /* arena copy */
int count;
} sched_trace_limit_tally_t;
/* One requested resource of a single requirement or member (3.2). */
typedef struct {
const char* name; /* arena copy */
@ -268,6 +291,30 @@ typedef struct sched_trace_entry_s {
int plan_no; /* the last plan begun */
int err; /* FINALIZE_FAILED only */
} commit;
struct { /* SEARCH_END: plans of the requirement's search */
int generated; /* tried+discarded+not tried */
int tried;
int discarded;
int not_tried;
int rc;
sched_trace_search_stmt_t stmt;
} search_end;
struct { /* POS_SUMMARY: the POS_END fields plus the host tallies */
int pos;
xce_sched_trace_pos_end_t how;
const char* host; /* the accepted host, or NULL */
int err;
int counts[XCE_TRACE_V_NKINDS]; /* hosts
* per verdict kind (bit pos) */
int nlimits;
sched_trace_limit_tally_t* limits; /* hits per limit, in the
* order first hit */
} pos_summary;
struct { /* ROLLBACK: consecutive released hosts, in call order */
int nhosts;
int cap;
const char** hosts;
} rollback;
} u;
} sched_trace_entry_t;
@ -319,6 +366,25 @@ struct xce_sched_trace_rec_s {
bool scan_err_set;
unsigned host_row_verdicts; /* SHORTFALL/LIMIT from the current host's
* unmet rows (set by the row capture) */
/* plans of the current requirement's search (reset by resreq_begin
* and after search_end) */
int scope_tried;
int scope_discarded;
int scope_not_tried;
bool scope_plan_err; /* a tried plan ended in an internal error */
/* summary level: the current position's host tallies. The limit
* tallies live in builder memory (malloc'd, not the arena) until the
* position ends, so an omitted position allocates nothing in the
* record; they are not counted by sched_trace_rec_bytes. */
int pos_counts[XCE_TRACE_V_NKINDS];
struct sched_trace_tally_build_s* pos_limits;
int pos_nlimits;
int pos_limits_cap;
unsigned host_seq; /* numbers host scopes, for one hit per host */
/* the ROLLBACK entry the last call opened, while no other call has
* been made since (NULL when that entry was omitted) */
bool rollback_open;
sched_trace_entry_t* rollback_e;
/* scope pointers, kept only until the matching scope ends and never
* dereferenced after it (TraceCapture's limit lookup) */
const xce_sched_obj_t* scope_obj;
@ -450,8 +516,33 @@ extern void sched_trace_host_begin(xce_sched_trace_rec_t* rec,
extern void sched_trace_host_verdict(xce_sched_trace_rec_t* rec,
unsigned verdicts, int err);
/*
* The current host's per-host check found limit `limit` exceeded in scope
* instance `scope` (both copied). Sets LIMIT in the host's row verdicts
* and, at summary level, tallies the limit for the position summary once
* per host whose verdict is limit exceeded (5.9). Outside a host scope it
* does nothing. The model-side seam of TraceCapture's limit rows (2.2).
*/
extern void sched_trace_host_limit_hit(xce_sched_trace_rec_t* rec,
const char* limit, const char* scope);
/* One host whose claim a failed plan released. Consecutive calls merge
* into one ROLLBACK entry, "released hosts: n01, n02" (5.8). */
extern void sched_trace_rollback_host(xce_sched_trace_rec_t* rec,
const char* host);
/* The plan begun last was committed, or building its allocation failed. */
extern void sched_trace_commit(xce_sched_trace_rec_t* rec);
extern void sched_trace_finalize_failed(xce_sched_trace_rec_t* rec, int err);
/*
* End of a requirement's plan search with its result `rc`: one line with
* the plans generated, tried, discarded and not tried since the
* requirement began, and at most one statement (rc == 0 only): no plan
* generated (g == 0), all discarded (g > 0, d == g), or none placed (t > 0
* and no tried plan ended in an internal error). The matching decision-
* wide counter is bumped under the same conditions, stored or not (9.3).
*/
extern void sched_trace_search_end(xce_sched_trace_rec_t* rec, int rc);
#endif