fix(scheduler): wire mem reservation reconciliation into live rusage event path

sched_reconcile_job_resource_usage() was only reachable from
sched_apply_job_rusage() (scheduler.c's sched_update(), which has no live
caller), so real-usage reconciliation never actually ran outside tests.
Wire it into core_events.c's XCE_CORE_EVENT_JOB_RUSAGE handler instead,
the actual live path shared by both normal-mode (driver.c) and sim/replay
mode (sim_loop.c). Adds link-satisfying stubs to the testsuite files that
#include core_events.c directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4M5MJM2zK6nU43da267Ku
This commit is contained in:
Rongsong Shen 2026-09-01 07:08:37 +00:00
parent 728496bea0
commit eb06f16d75
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
21 changed files with 389 additions and 6 deletions

View file

@ -1,6 +1,6 @@
# Implementation Plan # Implementation Plan
- [ ] 1. Foundation: controller-side dispatch-failure classification and durable transition record - [x] 1. Foundation: controller-side dispatch-failure classification and durable transition record
- [x] 1.1 (P) Define the dispatch-failure classification used to decide whether a failed dispatch attempt should retry or fail permanently - [x] 1.1 (P) Define the dispatch-failure classification used to decide whether a failed dispatch attempt should retry or fail permanently
- Enumerate each distinct way a dispatch attempt to a worker can fail today (worker lookup, worker unavailable, worker not ready, invalid allocation, queue configuration lookup, the dispatch request itself failing), and classify each as either retryable (transient/environmental) or terminal (a locally invalid decision that retrying will not fix) - Enumerate each distinct way a dispatch attempt to a worker can fail today (worker lookup, worker unavailable, worker not ready, invalid allocation, queue configuration lookup, the dispatch request itself failing), and classify each as either retryable (transient/environmental) or terminal (a locally invalid decision that retrying will not fix)
- The classification is a pure decision with no side effects, independently testable against every known failure case without needing a live dispatch attempt - The classification is a pure decision with no side effects, independently testable against every known failure case without needing a live dispatch attempt
@ -22,7 +22,7 @@
- _Requirements: 4.3_ - _Requirements: 4.3_
- _Boundary: Controller Dispatch-Failure Classification (retry-counter data model)_ - _Boundary: Controller Dispatch-Failure Classification (retry-counter data model)_
- [ ] 2. Core: scheduler transitions a job to running state at dispatch-commit time - [x] 2. Core: scheduler transitions a job to running state at dispatch-commit time
- No dependency on Task 1 — scheduler-side files only, independent of the controller-side foundation work above. - No dependency on Task 1 — scheduler-side files only, independent of the controller-side foundation work above.
- [x] 2.1 (P) Scheduler marks a job as running in the same operation that commits its dispatch decision - [x] 2.1 (P) Scheduler marks a job as running in the same operation that commits its dispatch decision
- When the scheduler commits a decision to dispatch a job, the job's state becomes running immediately, in the same operation that already records the job's resource allocation — not waiting for any later confirmation - When the scheduler commits a decision to dispatch a job, the job's state becomes running immediately, in the same operation that already records the job's resource allocation — not waiting for any later confirmation
@ -38,7 +38,7 @@
- _Requirements: 3.1, 3.2, 4.4_ - _Requirements: 3.1, 3.2, 4.4_
- _Boundary: Scheduler Dispatch-Failure Handler_ - _Boundary: Scheduler Dispatch-Failure Handler_
- [ ] 3. Core: controller transitions a job to running state only once dispatch to the worker succeeds, and resolves failures - [x] 3. Core: controller transitions a job to running state only once dispatch to the worker succeeds, and resolves failures
- Sub-tasks 3.1-3.3 all restructure the same function and share its per-job lock scope, so none of them are marked parallel to each other, regardless of how disjoint their individual concerns look. - Sub-tasks 3.1-3.3 all restructure the same function and share its per-job lock scope, so none of them are marked parallel to each other, regardless of how disjoint their individual concerns look.
- [x] 3.1 Controller commits a job's resource allocation and running-state transition together, only on a successful dispatch - [x] 3.1 Controller commits a job's resource allocation and running-state transition together, only on a successful dispatch
- The controller's existing (currently unconditional) commit of a job's resource-allocation data becomes conditional on the dispatch request to the worker actually succeeding; the job's state transition to running happens in that same successful outcome, protected against concurrent access to the job record - The controller's existing (currently unconditional) commit of a job's resource-allocation data becomes conditional on the dispatch request to the worker actually succeeding; the job's state transition to running happens in that same successful outcome, protected against concurrent access to the job record
@ -63,14 +63,14 @@
- _Requirements: 4.1, 4.3, 4.4, 4.5_ - _Requirements: 4.1, 4.3, 4.4, 4.5_
- _Depends: 1.1, 1.3, 3.2_ - _Depends: 1.1, 1.3, 3.2_
- [ ] 4. Integration: caller no longer duplicates dispatch-outcome reporting - [x] 4. Integration: caller no longer duplicates dispatch-outcome reporting
- [x] 4.1 Remove the caller's own dispatch-outcome reporting now that resolution owns it - [x] 4.1 Remove the caller's own dispatch-outcome reporting now that resolution owns it
- The function that invokes a dispatch attempt for each job in a batch no longer separately reports the outcome itself — reporting is now entirely owned by the dispatch resolution added in Task 3, preventing a failed dispatch from ever producing two different, conflicting outcome reports for the same job - The function that invokes a dispatch attempt for each job in a batch no longer separately reports the outcome itself — reporting is now entirely owned by the dispatch resolution added in Task 3, preventing a failed dispatch from ever producing two different, conflicting outcome reports for the same job
- Observable completion: a dispatch failure that resolves as permanent produces exactly one outcome report, not two conflicting ones - Observable completion: a dispatch failure that resolves as permanent produces exactly one outcome report, not two conflicting ones
- _Requirements: 3.1, 4.1, 4.2_ - _Requirements: 3.1, 4.1, 4.2_
- _Depends: 3.1, 3.2, 3.3_ - _Depends: 3.1, 3.2, 3.3_
- [ ] 5. Validation: end-to-end behavior and regression - [x] 5. Validation: end-to-end behavior and regression
- [x] 5.1 End-to-end test: resource-in-use accounting survives a multi-round gap between dispatch and confirmation - [x] 5.1 End-to-end test: resource-in-use accounting survives a multi-round gap between dispatch and confirmation
- Reproduce bug-1624 directly: dispatch a job, let several rounds pass before the worker confirms it started, and confirm resource-in-use totals reflect the job continuously from the round it was dispatched, matching what a same-round confirmation would have produced - Reproduce bug-1624 directly: dispatch a job, let several rounds pass before the worker confirms it started, and confirm resource-in-use totals reflect the job continuously from the round it was dispatched, matching what a same-round confirmation would have produced
- Observable completion: the regression scenario passes, and fails against the pre-change code path if temporarily reverted - Observable completion: the regression scenario passes, and fails against the pre-change code path if temporarily reverted

View file

@ -1267,6 +1267,24 @@ int xce_core_push_events(xce_sched_core_t* core, xce_core_event_t* events,
} }
job->rusages = rusages; job->rusages = rusages;
/* resource-accounting.md: reconcile the job's "mem" reservation
* charge against this report's real usage. THIS is the actual
* live path (both normal-mode, driver.c, and sim/replay mode,
* sim_loop.c, translate their own rusage events into this same
* XCE_CORE_EVENT_JOB_RUSAGE core-level event) -- schedobj.c's
* sched_apply_job_rusage() duplicates this same job->rusages
* bookkeeping but is itself reachable only from scheduler.c's
* sched_update(), which has no live caller anywhere in this
* codebase (confirmed by grep) and exists only for this file's
* own test suite. A no-op (see resource.c's own doc comments)
* if the job's allocation isn't known yet or spans more than
* one host -- not errors, so not propagated as this handler's
* own result. */
if (job->accounts != NULL) {
sched_reconcile_job_resource_usage(core, job->accounts,
rusages);
}
if ((picker != NULL) if ((picker != NULL)
&& (picker->picker_iface->on_job_rusage != NULL)) { && (picker->picker_iface->on_job_rusage != NULL)) {
picker->picker_iface->on_job_rusage(picker, job, rusages); picker->picker_iface->on_job_rusage(picker, job, rusages);

View file

@ -120,6 +120,18 @@ void kill_sched_worker(void* arg) { (void)arg; }
void kill_sched_user(void* arg) { (void)arg; } void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
void plugin_unregister(void* arg) { (void)arg; } void plugin_unregister(void* arg) { (void)arg; }
/* Link-satisfying stubs for scheduler.c's sched_publish_dispatch()/ /* Link-satisfying stubs for scheduler.c's sched_publish_dispatch()/

View file

@ -58,9 +58,17 @@
/* Pull in the real xce_sched_core_init()/xce_core_push_events() under test /* Pull in the real xce_sched_core_init()/xce_core_push_events() under test
* into this TU (white-box #include, same convention as * into this TU (white-box #include, same convention as
* test_core_jbuf_capacity_pin.c's `#include "../src/core.c"`). */ * test_core_jbuf_capacity_pin.c's `#include "../src/core.c"`).
*
* resource.c added (bug-1740, the reconciliation wiring fix): XCE_CORE_
* EVENT_JOB_RUSAGE now calls sched_reconcile_job_resource_usage() (that
* file), the ONLY live call site anywhere in this codebase -- the whole
* point of this file's own end-to-end test for it is to exercise the REAL
* implementation, not a stub that would silently let the wiring rot again
* unnoticed, exactly as it did the first time. */
#include "../src/core.c" #include "../src/core.c"
#include "../src/core_events.c" #include "../src/core_events.c"
#include "../src/resource.c"
void kill_sched_job(void* arg) { (void)arg; } void kill_sched_job(void* arg) { (void)arg; }
void kill_sched_queue(void* arg) { (void)arg; } void kill_sched_queue(void* arg) { (void)arg; }
@ -68,6 +76,19 @@ void kill_sched_worker(void* arg) { (void)arg; }
void kill_sched_user(void* arg) { (void)arg; } void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* Link-satisfying stubs for resource.c's sched_try_alloc_on_host_() (its
* OWN callees, live in plugin.c/schedobj.c, neither pulled in here) -- same
* two stubs test_resource_accounting.c already establishes needing for the
* identical reason. Never actually invoked: this file's tests never call
* sched_try_alloc_on_hosts()/sched_try_alloc_on_host_(). */
int plugin_prepare_allocation(void* s, xce_sched_ctx_t* c)
{
(void)s; (void)c; return 0;
}
int sched_ctx_get_uncomit_host(xvec_t** v, xce_sched_ctx_t* c, int i)
{
(void)v; (void)c; (void)i; return 0;
}
/* dup_val - real reimplementation of snapshot_wire.c's function of the same /* dup_val - real reimplementation of snapshot_wire.c's function of the same
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/ * name (verbatim logic), needed because core_events.c's RESVALS_FULL/
@ -1248,6 +1269,128 @@ static void test_job_rusage_applies_state_when_hook_is_null(void)
TEST_ASSERT_EQUAL_PTR(&rusages, sched_get_job(&core, 7)->rusages); TEST_ASSERT_EQUAL_PTR(&rusages, sched_get_job(&core, 7)->rusages);
} }
/*
* bug-1740: XCE_CORE_EVENT_JOB_RUSAGE -- the ONLY live production path for
* job rusage, per both the normal-mode driver (driver.c) and the sim/replay
* driver (sim_loop.c), which both translate their own rusage events into
* this exact core-level event type -- must actually drive resource-
* accounting.md's reservation-vs-usage reconciliation. It didn't: the
* reconciliation code was wired into schedobj.c's sched_apply_job_rusage()
* instead, a function with exactly ONE caller anywhere in this codebase
* (scheduler.c's sched_update(), itself confirmed to have NO live caller at
* all -- superseded by this file's own driver-event mechanism, per driver.c's
* own comments: "Replaces sched_update()'s inline handling"). The entire
* reconciliation feature was therefore unreachable in both normal-mode and
* sim/replay operation despite passing every unit test that called its
* functions directly -- exactly the trap of testing a function in isolation
* without a test proving the real event path actually reaches it. Fixed by
* calling sched_reconcile_job_resource_usage() directly from THIS handler.
* This test drives the full path: register "mem", join a worker, dispatch a
* job with a real 4MB "mem" allocation (core_build_job() -> make_job_account()
* populates job->accounts exactly as a genuine dispatch would), then push a
* JOB_RUSAGE report claiming 7MB actual usage (> the 4MB reservation) and
* asserts the OVERAGE (3MB) landed on the account and the pool.
*/
static void test_job_rusage_reconciles_mem_reservation_against_usage(void)
{
xce_sched_core_t core;
xce_core_event_t event;
xce_resource_t wire_mem;
xce_worker_t wire_worker;
xce_worker_t* worker_ptrs[1];
xce_sched_worker_t* w;
xce_resource_t* r_mem = NULL;
xce_job_t* job1;
xce_alloc_t* a_mem;
xce_host_alloc_t* h0;
xce_host_alloc_t* hallocs[1];
xce_job_alloc_t* jalloc;
xce_sched_job_t* tracked;
xce_rusage_t ru;
xce_rusage_t* ru_ptrs[1];
xce_job_rusages_t rusages;
int rc;
int idx[1];
float val[1];
fixture_init(&core, &g_full_plugin);
memset(&wire_mem, 0, sizeof(wire_mem));
wire_mem.name = "mem";
TEST_ASSERT_NOT_NULL(makeResource(core.resmgr, &wire_mem));
TEST_ASSERT_TRUE(key_find(core.resmgr, (void*)"mem", (void**)&r_mem) >= 0);
TEST_ASSERT_NOT_NULL(r_mem);
memset(&wire_worker, 0, sizeof(wire_worker));
wire_worker.name = "hostA";
wire_worker.nresvals_to_sched = 0;
worker_ptrs[0] = &wire_worker;
memset(&event, 0, sizeof(event));
event.type = XCE_CORE_EVENT_WORKERS_PUSH;
event.u.workers_push.nworkers = 1;
event.u.workers_push.workers = worker_ptrs;
rc = xce_core_push_events(&core, &event, 1);
TEST_ASSERT_EQUAL_INT(0, rc);
w = sched_get_worker(&core, "hostA");
TEST_ASSERT_NOT_NULL(w);
/* Dispatch job 77 with a real 4MB "mem" allocation on hostA -- exactly
* what a genuine DISPATCH decision's job->allocs would carry. */
a_mem = make_alloc((char*)"mem", NULL, 0, 4.0f, 0);
h0 = make_host_alloc((char*)"hostA", 1, make_allocs(1, a_mem));
hallocs[0] = h0;
jalloc = make_job_alloc(77, 1, make_host_allocs(1, hallocs[0]));
job1 = make_job(77, JOB_STAT_RUN, "normal", "alice", "proj1");
job1->allocs = jalloc;
memset(&event, 0, sizeof(event));
event.type = XCE_CORE_EVENT_JOBS_PUSH;
event.u.jobs_push.njobs = 1;
event.u.jobs_push.jobs = &job1;
rc = xce_core_push_events(&core, &event, 1);
TEST_ASSERT_EQUAL_INT(0, rc);
tracked = sched_get_job(&core, 77);
TEST_ASSERT_NOT_NULL(tracked);
TEST_ASSERT_NOT_NULL(tracked->accounts);
/* Sanity: the reservation charge landed at dispatch time (before any
* rusage tick), matching sched_charge_account()'s existing behavior. */
idx[0] = r_mem->idx;
get_resvals(&(w->resInUse), 1, idx, val);
TEST_ASSERT_EQUAL_FLOAT(4.0f, val[0]);
/* Now the worker reports job 77's REAL usage: 7MB, exceeding the 4MB
* reservation. */
memset(&ru, 0, sizeof(ru));
ru.resname = (char*)"memory_rss";
ru.value = 7.0f;
ru_ptrs[0] = &ru;
memset(&rusages, 0, sizeof(rusages));
rusages.jobid = 77;
rusages.count = 1;
rusages.usages = ru_ptrs;
memset(&event, 0, sizeof(event));
event.type = XCE_CORE_EVENT_JOB_RUSAGE;
event.u.job_rusage.jobid = 77;
event.u.job_rusage.rusages = &rusages;
rc = xce_core_push_events(&core, &event, 1);
TEST_ASSERT_EQUAL_INT(0, rc);
/* The overage (3MB) must now be reflected both on the account and in
* the pool -- the whole point of this test: this ONLY happens if the
* live event handler actually calls the reconciliation code. */
TEST_ASSERT_EQUAL_FLOAT(
3.0f, (float)tracked->accounts->accounts[0]->accounts[0]->used);
get_resvals(&(w->resInUse), 1, idx, val);
TEST_ASSERT_EQUAL_FLOAT(7.0f, val[0]);
}
/* CONFIG_PUSH must decompose the pushed xce_conf4sched_t's embedded /* CONFIG_PUSH must decompose the pushed xce_conf4sched_t's embedded
* queues[]/resources[]/resvals[] arrays into core state -- not just store * queues[]/resources[]/resvals[] arrays into core state -- not just store
* the config pointer and bump configver (Req 5 AC 4's CONFIG_PUSH row: * the config pointer and bump configver (Req 5 AC 4's CONFIG_PUSH row:
@ -1413,6 +1556,7 @@ int main(void)
RUN_TEST(test_workers_push_twice_updates_existing_worker_in_place); RUN_TEST(test_workers_push_twice_updates_existing_worker_in_place);
RUN_TEST(test_workers_push_with_null_val_does_not_clobber_existing_resval); RUN_TEST(test_workers_push_with_null_val_does_not_clobber_existing_resval);
RUN_TEST(test_job_rusage_applies_state_when_hook_is_null); RUN_TEST(test_job_rusage_applies_state_when_hook_is_null);
RUN_TEST(test_job_rusage_reconciles_mem_reservation_against_usage);
RUN_TEST(test_config_push_decomposes_queues_resources_and_resvals); RUN_TEST(test_config_push_decomposes_queues_resources_and_resvals);
RUN_TEST(test_push_events_rejects_with_ebusy_when_session_active_no_mutation); RUN_TEST(test_push_events_rejects_with_ebusy_when_session_active_no_mutation);
RUN_TEST(test_push_events_null_core_returns_einval); RUN_TEST(test_push_events_null_core_returns_einval);

View file

@ -135,6 +135,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* dup_val - real reimplementation of snapshot_wire.c's function of the same /* dup_val - real reimplementation of snapshot_wire.c's function of the same
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/ * name (verbatim logic), needed because core_events.c's RESVALS_FULL/
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's * RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's

View file

@ -68,6 +68,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* dup_val - real reimplementation of snapshot_wire.c's function of the same /* dup_val - real reimplementation of snapshot_wire.c's function of the same
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/ * name (verbatim logic), needed because core_events.c's RESVALS_FULL/
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's * RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's

View file

@ -168,6 +168,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* dup_val - real reimplementation of snapshot_wire.c's function of the same /* dup_val - real reimplementation of snapshot_wire.c's function of the same
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/ * name (verbatim logic), needed because core_events.c's RESVALS_FULL/
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's * RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's

View file

@ -66,6 +66,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* dup_val - real reimplementation of snapshot_wire.c's function of the same /* dup_val - real reimplementation of snapshot_wire.c's function of the same
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/ * name (verbatim logic), needed because core_events.c's RESVALS_FULL/
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's * RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's

View file

@ -113,6 +113,19 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
* invoked (no worker is ever added here). */ * invoked (no worker is ever added here). */
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; this fixture never populates job->accounts, so the real body is
* never reached -- link-satisfying stub only, same rationale as every
* other stub in this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* Link-satisfying stubs for scheduler.c's sched_publish_dispatch()/ /* Link-satisfying stubs for scheduler.c's sched_publish_dispatch()/
* sched_publish_pend_reason() -- never actually invoked (this fixture * sched_publish_pend_reason() -- never actually invoked (this fixture
* pushes no jobs, so the driver's decision-drain loop never observes a * pushes no jobs, so the driver's decision-drain loop never observes a

View file

@ -99,6 +99,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec, int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,

View file

@ -148,6 +148,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec, int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,

View file

@ -113,6 +113,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec, int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,

View file

@ -77,6 +77,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec, int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,

View file

@ -107,6 +107,18 @@ void kill_sched_resval(xce_val_t* val)
free_Value(val); free_Value(val);
} }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* REAL implementation -- snapshot_wire.c:37 verbatim. This is the fix under /* REAL implementation -- snapshot_wire.c:37 verbatim. This is the fix under
* test: core_events.c's RESVALS_FULL/RESVALS_DELTA handlers must dup_val() * test: core_events.c's RESVALS_FULL/RESVALS_DELTA handlers must dup_val()
* before zarray_put() so the zarray owns an independent copy, not the same * before zarray_put() so the zarray owns an independent copy, not the same

View file

@ -108,6 +108,19 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; this fixture never populates job->accounts, so the real body is
* never reached -- link-satisfying stub only, same rationale as every
* other stub in this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec, int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,
xlist_t* limits) xlist_t* limits)
{ {

View file

@ -175,6 +175,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* core_reset_workers()'s (core_session.c) linker dependency -- never /* core_reset_workers()'s (core_session.c) linker dependency -- never
* invoked (no worker is ever added here). */ * invoked (no worker is ever added here). */
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }

View file

@ -122,6 +122,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* core_reset_workers()'s (core_session.c) linker dependency -- see /* core_reset_workers()'s (core_session.c) linker dependency -- see
* test_core_full_cycle.c's own file header comment for the same stub; * test_core_full_cycle.c's own file header comment for the same stub;
* never invoked (no worker is ever added here). */ * never invoked (no worker is ever added here). */

View file

@ -93,6 +93,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec, int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,

View file

@ -162,6 +162,19 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
* invoked (no worker is ever added here). */ * invoked (no worker is ever added here). */
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; this fixture never populates job->accounts, so the real body is
* never reached -- link-satisfying stub only, same rationale as every
* other stub in this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* plugin_prepare_allocation()'s (plugin.c) linker dependency -- never /* plugin_prepare_allocation()'s (plugin.c) linker dependency -- never
* invoked (this fixture never drives real resource-matching allocation -- * invoked (this fixture never drives real resource-matching allocation --
* same rationale test_sim_equivalence.c's own copy documents). */ * same rationale test_sim_equivalence.c's own copy documents). */

View file

@ -117,6 +117,20 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
* added here). */ * added here). */
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; } void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; this fixture's own scenario keeps job->accounts NULL by design
* (see this file's own header comment), so the real body is never reached
* -- link-satisfying stub only, same rationale as every other stub in this
* block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* plugin_prepare_allocation()'s (plugin.c, the "limit" plugin category) /* plugin_prepare_allocation()'s (plugin.c, the "limit" plugin category)
* linker dependency -- never invoked (this file never drives real * linker dependency -- never invoked (this file never drives real
* allocation). */ * allocation). */

View file

@ -113,6 +113,18 @@ void kill_sched_user(void* arg) { (void)arg; }
void kill_sched_project(void* arg) { (void)arg; } void kill_sched_project(void* arg) { (void)arg; }
void kill_sched_resval(xce_val_t* val) { (void)val; } void kill_sched_resval(xce_val_t* val) { (void)val; }
/* resource-accounting.md's reconciliation (resource.c, not linked here --
* this file only #includes core_events.c). core_events.c's
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
* NULL; link-satisfying stub only, same rationale as every other stub in
* this block (see test_job_update.c's identical stub). */
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
xce_job_account_t* a,
xce_job_rusages_t* r)
{
(void)c; (void)a; (void)r; return 0;
}
/* core_reset_workers()'s (core_session.c) linker dependency -- same stub /* core_reset_workers()'s (core_session.c) linker dependency -- same stub
* test_sim_event_loop.c/test_core_full_cycle.c already establish; never * test_sim_event_loop.c/test_core_full_cycle.c already establish; never
* invoked (no worker is ever added here). */ * invoked (no worker is ever added here). */