Adds the interactive simulation REPL's breakpoint and state-inspection commands (Req 5 AC 22): `break <event_type> [key=value ...]` / `info break` / `delete <id>|all` on event and decision types, and `info session/job/queue/worker/resource/summary`. repl.c (370 lines after task 12.1) couldn't hold this task's full surface under the project's 800-line cap, so it's split three ways (matching the snapshot.c/snapshot_wire.c/snapshot_load.c precedent): repl.c (execution control + dispatch), repl_break.c (matching/CRUD + the three new driver-facing hooks), repl_info.c (info dumps), sharing state via repl_internal.h. sim_loop.c gained 3 new bare hook calls (repl.h inline wrappers, same pattern as task 12.1's two) at the points design.md's pseudocode requires -- per decoded event before it joins the batch, per session boundary, and per drained decision -- landing sim_loop.c at exactly 800/800 lines. Two real bugs found and fixed during development (bug-1506, bug-1507): an uninitialized xstr_table left breakpoint filter fields silently NULL instead of failing loud, and repl_breakpoint_free() called a bare free() on an RTTI-refcounted makeString() string, corrupting the heap. Review found one gap: `info job` printed only a resreq presence flag instead of the actual resreq text, when format_resreq() already existed in this repo for exactly this purpose. Fixed to match. Scheduler suite: 35/35 clean (was 34/34). RED-phase evidence (2 real bugs plus 2 synthetic probes, all reverted with confirmed zero residue) recorded in tasks.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPPXeKSUXUqcqvzNXY1rzJ
104 lines
3.8 KiB
Meson
104 lines
3.8 KiB
Meson
scheduler_srcs = [
|
|
'src/main.c',
|
|
'src/handler.c',
|
|
'src/scheduler.c',
|
|
'src/core.c',
|
|
'src/core_events.c',
|
|
'src/core_session.c',
|
|
'src/core_clock.c',
|
|
'src/driver.c',
|
|
'src/snapshot.c',
|
|
'src/snapshot_wire.c',
|
|
'src/snapshot_load.c',
|
|
'src/decision.c',
|
|
'src/recording.c',
|
|
'src/recording_events.c',
|
|
'src/recording_session.c',
|
|
'src/sim.c',
|
|
'src/sim_loop.c',
|
|
'src/sim_verify.c',
|
|
'src/sim_record.c',
|
|
'src/repl.c',
|
|
'src/repl_break.c',
|
|
'src/repl_info.c',
|
|
'src/schedobj.c',
|
|
'src/plugin.c',
|
|
'src/resource.c',
|
|
'src/plugins/fcfs.c',
|
|
'src/plugins/builtin_fcfs.c',
|
|
'src/plugins/seqjob_allocator.c',
|
|
'src/plugins/parjob_allocator.c',
|
|
'src/plugins/limit.c',
|
|
]
|
|
|
|
incdir = include_directories('src',
|
|
'include',
|
|
'../include',
|
|
'../lib')
|
|
|
|
# Task 12.1 (scheduler-core spec, Req 5 AC 22): the interactive REPL's
|
|
# line-editing input loop (src/repl.c) needs readline()/add_history().
|
|
# Uses libedit (BSD), not GNU readline (GPL) -- xce_scheduler is a shipped
|
|
# production daemon (unlike xce_test, a debug tool), so a GPL dependency
|
|
# would encumber the whole linked binary. libedit's editline/readline.h
|
|
# emulation header provides the same two calls under a permissive license;
|
|
# src/controller/meson.build (xce_test's own REPL) uses the identical dep
|
|
# for the same reason, kept consistent project-wide.
|
|
libedit_dep = dependency('libedit')
|
|
|
|
scheduler_deps = [
|
|
libxce_dep,
|
|
librtti_dep,
|
|
math_dep,
|
|
tinylog_dep,
|
|
thread_dep,
|
|
libedit_dep,
|
|
]
|
|
|
|
scheduler = executable('xce_scheduler',
|
|
scheduler_srcs,
|
|
include_directories: incdir,
|
|
dependencies: scheduler_deps,
|
|
link_args: wrap_link_args,
|
|
install: true)
|
|
|
|
# Task 4.1 (scheduler-core spec, Req 5.1/5.2): isolated compile target for
|
|
# core.c alone, consumed by testsuite/test_core_isolation.c to prove at
|
|
# build time that core.c references zero symbols from the networking/API
|
|
# libraries (netio/xceapi/client/delay/idgen). A static_library() here need
|
|
# not LINK against anything for this purpose -- compiling src/core.c to an
|
|
# object is enough; the object's own undefined-symbol table (inspected via
|
|
# nm(1) in the test) reflects exactly what core.c's code calls, independent
|
|
# of which libraries are nominally "dependencies" of this build target.
|
|
sched_core_isolation_lib = static_library(
|
|
'sched_core_isolation',
|
|
['src/core.c'],
|
|
include_directories: incdir,
|
|
dependencies: scheduler_deps,
|
|
install: false)
|
|
|
|
# Task 11.3 (scheduler-core spec, Req 5 AC 17): isolated compile target for
|
|
# 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 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, and task
|
|
# 12.2 adds 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); 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'],
|
|
include_directories: incdir,
|
|
dependencies: scheduler_deps,
|
|
install: false)
|
|
|
|
subdir('testsuite')
|