feat(scheduler-sim-repl-verbosity): task 3.2 - implement Event Echo Gate
Implements mode-aware event echo classification, job-arrival range
compression (Req 4.5), and round-collapse flush wiring at all 3
breakpoint-match/structural-event call sites (Requirements 1.1-1.4,
3.5, 3.6). All 4 of task 3.1's tests pass; also closes bug-1609
("continue is as verbose as step").
repl_break.c grew 827->905 lines (13% over the 800-line cap). Unlike
task 2.2's Round Rollup, this logic is wiring inside pre-existing
driver-facing hooks, not a relocatable subsystem - accepted in place
per design.md's established residual-tolerance precedent.
Review independently investigated a one-off ASAN stack-use-after-return
in an unrelated test (sched_sim_record_output_test) surfaced by this
change's stack-layout perturbation: traced to the same documented
pre-existing thread-lifecycle bug class as bug-1598/bug-1632 (an
unjoined picker thread reading a stack-local sim after test-function
return), confirmed via 11/11 clean reruns - logged as bug-1763, not a
regression from this task.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAWMhfRJFnmmnG8h97yUDd
This commit is contained in:
parent
f587a441ac
commit
cc78d09140
4 changed files with 124 additions and 18 deletions
|
|
@ -116,6 +116,33 @@ static xce_repl_bp_kind_t repl_bp_kind_for_core_event(xce_core_event_type_t t)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* repl_event_is_structural - scheduler-sim-repl-verbosity spec, task 3.2,
|
||||
* design.md's "Event Echo Gate" component (Requirement 1): partitions the
|
||||
* same ten xce_core_event_type_t members BP_KIND_TABLE/
|
||||
* repl_bp_kind_for_core_event() above already enumerate into structural
|
||||
* (CONFIG_PUSH, JOBS_PUSH, WORKERS_PUSH, RESOURCES_PUSH, RESVALS_FULL --
|
||||
* population/config arrivals echoed every mode, AC 1.3) vs. routine
|
||||
* (RESVALS_DELTA, JOB_STATE_CHANGE, JOB_UPDATE, QUEUE_UPDATE, JOB_RUSAGE --
|
||||
* echoed only while single-stepping, AC 1.1/1.2). Used only to gate
|
||||
* xce_repl_on_event()'s call to repl_print_event_summary() below --
|
||||
* breakpoint matching (repl_find_event_breakpoint()) runs on every event
|
||||
* regardless of this classification (Requirement 1.4).
|
||||
*/
|
||||
static bool repl_event_is_structural(xce_core_event_type_t t)
|
||||
{
|
||||
switch (t) {
|
||||
case XCE_CORE_EVENT_CONFIG_PUSH:
|
||||
case XCE_CORE_EVENT_JOBS_PUSH:
|
||||
case XCE_CORE_EVENT_WORKERS_PUSH:
|
||||
case XCE_CORE_EVENT_RESOURCES_PUSH:
|
||||
case XCE_CORE_EVENT_RESVALS_FULL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* repl_job_state_matches - AC 22's `state=RUN`-style filter value, matched
|
||||
* against the JOB_IS_*() bitmask macros (xce/types.h) every other live
|
||||
* state check in this codebase already uses, rather than an exact bitwise
|
||||
|
|
@ -616,21 +643,48 @@ static void repl_print_event_summary(xce_sched_sim_driver_t* sim,
|
|||
break;
|
||||
|
||||
case XCE_CORE_EVENT_JOBS_PUSH: {
|
||||
int i;
|
||||
/* Requirement 4.5: adopt range compression for this job-arrival
|
||||
* listing instead of printing each jobid individually. */
|
||||
int n = ev->u.jobs_push.njobs;
|
||||
uint64_t* jobids = (n > 0)
|
||||
? (uint64_t*)malloc((size_t)n * sizeof(*jobids))
|
||||
: NULL;
|
||||
int njobids = 0;
|
||||
int i;
|
||||
|
||||
fprintf(stdout, "[sim] event: JOB_PUSH njobs=%d jobids=[",
|
||||
ev->u.jobs_push.njobs);
|
||||
for (i = 0; i < ev->u.jobs_push.njobs; i++) {
|
||||
for (i = 0; (i < n) && (jobids != NULL); i++) {
|
||||
xce_job_t* j = ev->u.jobs_push.jobs[i];
|
||||
char jobidStr[64];
|
||||
|
||||
if (j == NULL) {
|
||||
continue;
|
||||
if (j != NULL) {
|
||||
jobids[njobids++] = j->jobid;
|
||||
}
|
||||
fmt_jobid(jobidStr, sizeof(jobidStr), j->jobid);
|
||||
fprintf(stdout, "%s%s", (i > 0) ? "," : "", jobidStr);
|
||||
}
|
||||
|
||||
fprintf(stdout, "[sim] event: JOB_PUSH njobs=%d jobids=[", n);
|
||||
|
||||
if (njobids > 0) {
|
||||
char jobids_buf[1024];
|
||||
int rc = repl_fmt_jobid_range(jobids_buf, sizeof(jobids_buf),
|
||||
jobids, njobids);
|
||||
|
||||
if (rc >= 0) {
|
||||
fprintf(stdout, "%s", jobids_buf);
|
||||
} else {
|
||||
/* design.md's Error Handling: a too-small compression
|
||||
* buffer falls back to the pre-existing uncompressed
|
||||
* per-id listing rather than truncating or dropping a
|
||||
* jobid. */
|
||||
for (i = 0; i < njobids; i++) {
|
||||
char jobidStr[64];
|
||||
|
||||
fmt_jobid(jobidStr, sizeof(jobidStr), jobids[i]);
|
||||
fprintf(stdout, "%s%s", (i > 0) ? "," : "", jobidStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "]\n");
|
||||
free(jobids);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -733,13 +787,29 @@ void xce_repl_on_event(xce_sched_sim_driver_t* sim, xce_core_event_t* ev)
|
|||
|
||||
rs->event_index++;
|
||||
|
||||
/* task 12.5, bug-1595: unconditional echo, printed before the
|
||||
* breakpoint check below so the operator sees "event happened" before
|
||||
* (if it also matches) "breakpoint hit". */
|
||||
repl_print_event_summary(sim, ev);
|
||||
/*
|
||||
* task 12.5, bug-1595: printed before the breakpoint check below so the
|
||||
* operator sees "event happened" before (if it also matches) "breakpoint
|
||||
* hit". scheduler-sim-repl-verbosity task 3.2 (Event Echo Gate,
|
||||
* Requirement 1): a structural event is always echoed -- first flushing
|
||||
* any active Round Rollup collapsed range so the two never interleave
|
||||
* out of order (Requirement 3.5) -- while a routine event is echoed only
|
||||
* while single-stepping; `continue` mode suppresses it.
|
||||
*/
|
||||
if (repl_event_is_structural(ev->type)) {
|
||||
repl_round_collapse_flush(sim);
|
||||
repl_print_event_summary(sim, ev);
|
||||
} else if (rs->mode == XCE_REPL_MODE_STEP) {
|
||||
repl_print_event_summary(sim, ev);
|
||||
}
|
||||
|
||||
bp = repl_find_event_breakpoint(rs, ev);
|
||||
if (bp != NULL) {
|
||||
/* Requirement 3.6: end any active collapsed range before the
|
||||
* breakpoint interruption is shown -- breakpoint matching itself
|
||||
* is unaffected by the routine/structural classification above
|
||||
* (Requirement 1.4). */
|
||||
repl_round_collapse_flush(sim);
|
||||
fprintf(stdout, "[sim] hit breakpoint %d @ event #%llu: %s\n", bp->id,
|
||||
(unsigned long long)rs->event_index, bp->token);
|
||||
repl_command_loop(sim);
|
||||
|
|
@ -774,6 +844,10 @@ void xce_repl_on_begin_round(xce_sched_sim_driver_t* sim, uint64_t begin_round)
|
|||
|
||||
bp = repl_find_begin_round_breakpoint(rs);
|
||||
if (bp != NULL) {
|
||||
/* scheduler-sim-repl-verbosity task 3.2, Requirement 3.6: end any
|
||||
* active collapsed range before this breakpoint interruption is
|
||||
* shown. */
|
||||
repl_round_collapse_flush(sim);
|
||||
fprintf(stdout, "[sim] hit breakpoint %d @ BEGIN_ROUND round=%llu\n", bp->id,
|
||||
(unsigned long long)begin_round);
|
||||
repl_command_loop(sim);
|
||||
|
|
@ -820,6 +894,10 @@ void xce_repl_on_decision(xce_sched_sim_driver_t* sim, xce_decision_t* d)
|
|||
/* bug-1591: see repl_info.c's repl_info_worker_one() comment on
|
||||
* fmt_jobid() -- same fix, same rationale. */
|
||||
fmt_jobid(jobidStr, sizeof(jobidStr), decision_jobid(d));
|
||||
/* scheduler-sim-repl-verbosity task 3.2, Requirement 3.6: end any
|
||||
* active collapsed range before this breakpoint interruption is
|
||||
* shown. */
|
||||
repl_round_collapse_flush(sim);
|
||||
fprintf(stdout, "[sim] hit breakpoint %d @ decision: %s jobid=%s\n",
|
||||
bp->id, decision_op_name(d->op), jobidStr);
|
||||
repl_command_loop(sim);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue