feat(scheduler-core): implement scheduler-side admin request handler (task 9.4)
Implements the scheduler's first request-reply opcode (OPCode_schedAdmin). sched_handle_admin_request() (handler.c) decodes SchedAdminRequest and dispatches by action: recordStatus answers synchronously (pure read); recordStart/recordStop are deferred onto the existing pend_updates queue (XCE_SCHED_OP_ADMIN_RECORD) since sched_record_start()'s snapshot call requires the session_active==0 precondition only guaranteed on the driver thread, not the async request-handling thread. driver.c's xce_sched_driver_translate_pending_events() performs the deferred action and sends the reply via a new xcecli_reply_schedadmin() (client.c/client.h), correlated by seq copied before the original request is freed. Adversarial review found a genuine cross-thread race: sched_record_status() read driver-owned recording state (including a pointer the driver thread frees) from the vtask thread with no lock -- the codebase's first such race, missed by ASan (doesn't detect races). Fixed with a dedicated record_lock scoped strictly to in-memory field access, never spanning file I/O; sched_record_status() now strdup()s under the lock instead of returning a borrowed live pointer. Verified with a real two-thread lock-contention test (independently confirmed non-vacuous by removing the lock and observing the test fail) plus a deterministic use-after-free reproduction. 26/26 scheduler suite, clang-format clean.
This commit is contained in:
parent
7494542a60
commit
e819a50600
19 changed files with 1761 additions and 115 deletions
|
|
@ -434,6 +434,30 @@ sched_record_lifecycle_test = executable(
|
|||
dependencies: [scheduler_test_deps],
|
||||
install: false)
|
||||
|
||||
# Contract test for the scheduler-side OPCode_schedAdmin request handler
|
||||
# (scheduler-core spec, task 9.4, Req 5 AC 10): decodes a forwarded
|
||||
# SchedAdminRequest, dispatches by action to sched_record_start()/
|
||||
# sched_record_stop()/sched_record_status(), and sends back a
|
||||
# SchedAdminReply matching requirements.md's field-semantics table.
|
||||
# recordStatus is proven synchronous (answered directly on the handler
|
||||
# thread, both idle and while genuinely recording); recordStart/recordStop
|
||||
# are proven deferred (enqueued, not executed, until a subsequent
|
||||
# xce_sched_driver_translate_pending_events() drain actually performs the
|
||||
# real sched_record_start()/sched_record_stop() call and sends the reply).
|
||||
# Same white-box #include pattern as sched_driver_translate_test
|
||||
# (core.c/core_clock.c/core_events.c/driver.c) PLUS ../src/recording.c/
|
||||
# recording_events.c/snapshot.c/snapshot_wire.c (real record start/stop/
|
||||
# status/write, task 9.1/9.2/9.3) PLUS ../src/handler.c (the code under
|
||||
# test). xcecli_reply_schedadmin() is a SPY test double, same pattern
|
||||
# sched_driver_decision_cb_test already establishes for
|
||||
# sched_publish_dispatch()/sched_publish_pend_reason().
|
||||
sched_admin_request_test = executable(
|
||||
'sched_admin_request_test',
|
||||
['test_admin_request.c'],
|
||||
include_directories:[incdir],
|
||||
dependencies: [scheduler_test_deps],
|
||||
install: false)
|
||||
|
||||
# Register as meson tests so `meson test --suite scheduler` runs them all.
|
||||
# detect_leaks=0 matches the suite convention (fixtures are not torn down).
|
||||
test('scheduler test', scheduler_test, suite: 'scheduler',
|
||||
|
|
@ -500,3 +524,6 @@ test('scheduler recording path validation test',
|
|||
test('scheduler record lifecycle test',
|
||||
sched_record_lifecycle_test, suite: 'scheduler',
|
||||
env: ['ASAN_OPTIONS=detect_leaks=0'])
|
||||
test('scheduler admin request test',
|
||||
sched_admin_request_test, suite: 'scheduler',
|
||||
env: ['ASAN_OPTIONS=detect_leaks=0'])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue