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:
parent
728496bea0
commit
eb06f16d75
21 changed files with 389 additions and 6 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# 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
|
||||
- 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
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
- _Requirements: 4.3_
|
||||
- _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.
|
||||
- [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
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
- _Requirements: 3.1, 3.2, 4.4_
|
||||
- _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.
|
||||
- [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
|
||||
|
|
@ -63,14 +63,14 @@
|
|||
- _Requirements: 4.1, 4.3, 4.4, 4.5_
|
||||
- _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
|
||||
- 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
|
||||
- _Requirements: 3.1, 4.1, 4.2_
|
||||
- _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
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -1267,6 +1267,24 @@ int xce_core_push_events(xce_sched_core_t* core, xce_core_event_t* events,
|
|||
}
|
||||
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)
|
||||
&& (picker->picker_iface->on_job_rusage != NULL)) {
|
||||
picker->picker_iface->on_job_rusage(picker, job, rusages);
|
||||
|
|
|
|||
|
|
@ -120,6 +120,18 @@ void kill_sched_worker(void* arg) { (void)arg; }
|
|||
void kill_sched_user(void* arg) { (void)arg; }
|
||||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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; }
|
||||
|
||||
/* Link-satisfying stubs for scheduler.c's sched_publish_dispatch()/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,17 @@
|
|||
|
||||
/* Pull in the real xce_sched_core_init()/xce_core_push_events() under test
|
||||
* 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_events.c"
|
||||
#include "../src/resource.c"
|
||||
|
||||
void kill_sched_job(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_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* queues[]/resources[]/resvals[] arrays into core state -- not just store
|
||||
* 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_with_null_val_does_not_clobber_existing_resval);
|
||||
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_push_events_rejects_with_ebusy_when_session_active_no_mutation);
|
||||
RUN_TEST(test_push_events_null_core_returns_einval);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/
|
||||
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's
|
||||
|
|
|
|||
|
|
@ -68,6 +68,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/
|
||||
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's
|
||||
|
|
|
|||
|
|
@ -168,6 +168,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/
|
||||
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's
|
||||
|
|
|
|||
|
|
@ -66,6 +66,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* name (verbatim logic), needed because core_events.c's RESVALS_FULL/
|
||||
* RESVALS_DELTA handlers now call it (bug-1585 fix) and this file's
|
||||
|
|
|
|||
|
|
@ -113,6 +113,19 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
|
|||
* invoked (no worker is ever added here). */
|
||||
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()/
|
||||
* sched_publish_pend_reason() -- never actually invoked (this fixture
|
||||
* pushes no jobs, so the driver's decision-drain loop never observes a
|
||||
|
|
|
|||
|
|
@ -99,6 +99,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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; }
|
||||
|
||||
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,
|
||||
|
|
|
|||
|
|
@ -148,6 +148,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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; }
|
||||
|
||||
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,
|
||||
|
|
|
|||
|
|
@ -113,6 +113,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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; }
|
||||
|
||||
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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; }
|
||||
|
||||
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,18 @@ void kill_sched_resval(xce_val_t* 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
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
/* 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,
|
||||
xlist_t* limits)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -175,6 +175,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* invoked (no worker is ever added here). */
|
||||
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
|
||||
|
|
|
|||
|
|
@ -122,6 +122,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* test_core_full_cycle.c's own file header comment for the same stub;
|
||||
* never invoked (no worker is ever added here). */
|
||||
|
|
|
|||
|
|
@ -93,6 +93,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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; }
|
||||
|
||||
int sched_fill_limit_requests(xce_scheduler_t* sched, xvec_idval_t* vec,
|
||||
|
|
|
|||
|
|
@ -162,6 +162,19 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
|
|||
* invoked (no worker is ever added here). */
|
||||
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
|
||||
* invoked (this fixture never drives real resource-matching allocation --
|
||||
* same rationale test_sim_equivalence.c's own copy documents). */
|
||||
|
|
|
|||
|
|
@ -117,6 +117,20 @@ void kill_sched_resval(xce_val_t* val) { (void)val; }
|
|||
* added here). */
|
||||
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)
|
||||
* linker dependency -- never invoked (this file never drives real
|
||||
* allocation). */
|
||||
|
|
|
|||
|
|
@ -113,6 +113,18 @@ void kill_sched_user(void* arg) { (void)arg; }
|
|||
void kill_sched_project(void* arg) { (void)arg; }
|
||||
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
|
||||
* test_sim_event_loop.c/test_core_full_cycle.c already establish; never
|
||||
* invoked (no worker is ever added here). */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue