fix(scheduler): sim mode picker never learns about the initial snapshot's own jobs/queues (bug-1567)
xce_scheduler -i -s <replay>: WARN "failed to resolve job picker plugin (rc=-2)" on load, and every job already present in the replay file's INITIAL snapshot stayed PEND forever -- never even reached the picker, let alone got dispatched. Root cause: sched_sim_driver_start() (sim.c) loads the initial snapshot via xce_sched_core_load_snapshot() BEFORE any picker plugin is registered (sim.h's own documented "Known scope boundary" -- only the picker's NAME is threaded through from the ReplayHeader). sched_resolve_job_picker() therefore always returns -ENOENT there, and xce_sched_core_load_snapshot()'s own picker-rebuild walk (on_queue_update/on_job_push per queue/job) is silently skipped. The real builtin_fcfs picker only gets registered moments later in sched_sim_driver_run() -- but nothing then replayed that rebuild walk, so any job/queue from the INITIAL snapshot (as opposed to one arriving later via a ReplayEvent, which correctly reaches the picker through xce_core_push_events()'s own picker!=NULL check) was permanently invisible to next_job(). Fixed by a new file, sim_picker.c: sim_bootstrap_picker() (replacing sim_loop.c's sim_register_default_picker(), moved out because sim_loop.c was already at its own documented 800-line "zero line-budget headroom" cap) registers the picker AND then replays the missed rebuild walk against it. Wired into scheduler_srcs, sched_sim_isolation_lib, and all 9 white-box test TUs that #include sim_loop.c directly. New regression test (test_sim_event_loop.c): a job baked into a fixture's INITIAL snapshot (not a ReplayEvent) now gets a live PEND decision. RED confirmed by temporarily no-op'ing the rebuild walk (test failed as expected), GREEN with the real fix. Full scheduler suite green (41/41, excluding the pre-existing unrelated bug-1560). Note: sim mode still never DISPATCHes (only PENDs) -- that is a separate, intentionally out-of-scope gap (real resource-matching allocation belongs to the not-yet-designed scheduler-allocation spec), not addressed here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
0f1df4998e
commit
0c8e417bda
14 changed files with 395 additions and 93 deletions
|
|
@ -16,6 +16,7 @@ scheduler_srcs = [
|
|||
'src/recording_session.c',
|
||||
'src/sim.c',
|
||||
'src/sim_loop.c',
|
||||
'src/sim_picker.c',
|
||||
'src/sim_verify.c',
|
||||
'src/sim_record.c',
|
||||
'src/repl.c',
|
||||
|
|
@ -82,23 +83,28 @@ sched_core_isolation_lib = static_library(
|
|||
# the simulation driver's own files, consumed by
|
||||
# testsuite/test_sim_isolation.c to prove at build time that
|
||||
# sim.c/sim_loop.c/sim_record.c/repl.c/repl_break.c/repl_info.c/
|
||||
# repl_params.c reference zero controller-facing symbols (client/netio/
|
||||
# xceapi/delay/idgen). All files are compiled together into ONE archive --
|
||||
# task 11.2 added sim_loop.c as a sibling file to task 11.1's sim.c, task
|
||||
# 11.5 added sim_record.c as a third, task 12.1 added repl.c as a fourth,
|
||||
# task 12.2 added repl_break.c/repl_info.c as a fifth/sixth (task 12.2's
|
||||
# own 800-line-cap split of repl.c's breakpoint/state-inspection logic --
|
||||
# repl_internal.h's own "Why a split at all" section has the full
|
||||
# rationale), and task 12.3 adds repl_params.c as a seventh (the same
|
||||
# split, extended again for `snapshot`/`set`); covering only a subset of
|
||||
# them would repeat core.c's own siblings' (core_events.c/core_session.c/
|
||||
# core_clock.c) never-mechanically-covered gap for the sim driver. Same
|
||||
# "compiling to an object is enough, no real linking needed" rationale as
|
||||
# sched_core_isolation_lib above.
|
||||
# repl_params.c/sim_picker.c reference zero controller-facing symbols
|
||||
# (client/netio/xceapi/delay/idgen). All files are compiled together into
|
||||
# ONE archive -- task 11.2 added sim_loop.c as a sibling file to task
|
||||
# 11.1's sim.c, task 11.5 added sim_record.c as a third, task 12.1 added
|
||||
# repl.c as a fourth, task 12.2 added repl_break.c/repl_info.c as a
|
||||
# fifth/sixth (task 12.2's own 800-line-cap split of repl.c's
|
||||
# breakpoint/state-inspection logic -- repl_internal.h's own "Why a split
|
||||
# at all" section has the full rationale), task 12.3 added repl_params.c
|
||||
# as a seventh (the same split, extended again for `snapshot`/`set`), and
|
||||
# bug-1567's fix added sim_picker.c as an eighth (sim_loop.c's own
|
||||
# "zero line-budget headroom" -- same reason its siblings above exist --
|
||||
# so the fix's picker-registration + post-load picker-rebuild-walk logic
|
||||
# lives here instead of growing sim_loop.c past its cap); covering only a
|
||||
# subset of them would repeat core.c's own siblings' (core_events.c/
|
||||
# core_session.c/core_clock.c) never-mechanically-covered gap for the sim
|
||||
# driver. Same "compiling to an object is enough, no real linking needed"
|
||||
# rationale as sched_core_isolation_lib above.
|
||||
sched_sim_isolation_lib = static_library(
|
||||
'sched_sim_isolation',
|
||||
['src/sim.c', 'src/sim_loop.c', 'src/sim_record.c', 'src/repl.c',
|
||||
'src/repl_break.c', 'src/repl_info.c', 'src/repl_params.c'],
|
||||
['src/sim.c', 'src/sim_loop.c', 'src/sim_picker.c', 'src/sim_record.c',
|
||||
'src/repl.c', 'src/repl_break.c', 'src/repl_info.c',
|
||||
'src/repl_params.c'],
|
||||
include_directories: incdir,
|
||||
dependencies: scheduler_deps,
|
||||
install: false)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue