diff --git a/.kiro/specs/scheduler-sim-live-allocation/tasks.md b/.kiro/specs/scheduler-sim-live-allocation/tasks.md index 479d84eb..e3c4f7cd 100644 --- a/.kiro/specs/scheduler-sim-live-allocation/tasks.md +++ b/.kiro/specs/scheduler-sim-live-allocation/tasks.md @@ -35,7 +35,7 @@ - _Requirements: 1.3, 3.1, 3.2_ - _Boundary: Core-Safe Allocation Chain_ -- [ ] 2.2 Make primary/compound/alter allocation dispatch and decision commit driver-agnostic +- [x] 2.2 Make primary/compound/alter allocation dispatch and decision commit driver-agnostic - Re-type the top-level allocation dispatch switch and its primary/compound/alter sub-functions, and the decision-commit function, to take shared core state directly - Wire the one genuine normal-mode-only touch point (the unsatisfiable-resreq cache) through the seam built in 1.1 instead of reading it directly - Confirm by reading each sub-function's body before migrating it that it touches nothing beyond core state, worker/context fields, and the one cache touch point. If a sub-function is found to touch additional normal-mode-only state, stop and split that state's seam into a new follow-up task (mirroring 1.1's pattern) rather than designing and building it within this task diff --git a/src/scheduler/include/scheduler.h b/src/scheduler/include/scheduler.h index de34d8d5..99789b31 100644 --- a/src/scheduler/include/scheduler.h +++ b/src/scheduler/include/scheduler.h @@ -326,7 +326,15 @@ extern void sched_end_session(xce_scheduler_t*); extern int sched_update_existing_queue(xce_scheduler_t*, xce_queue_t*); extern int sched_update_existing_job(xce_scheduler_t*, xce_job_t*); extern int sched_apply_job_rusage(xce_scheduler_t*, xce_job_rusages_t*); -extern int sched_commit_decision(xce_scheduler_t*, xce_decision_t*); +/* scheduler-sim-live-allocation spec, task 2.2 (Core-Safe Allocation + * Chain): sched_commit_decision() is now core-typed (xce_sched_core_t*), + * not xce_scheduler_t* -- it, plugin_commit_decision(), sched_get_job() + * and sched_commit_job_alloc() (the latter two already relocated to + * core.h) are all core-safe now, so the whole DISPATCH-commit path is + * callable from either driver. Its sole production caller, + * commit_decision() (scheduler.c, static), wraps its own still- + * xce_scheduler_t*-typed argument as &(sched->core) at the call site. */ +extern int sched_commit_decision(xce_sched_core_t*, xce_decision_t*); extern int sched_publish_pend_reason(xce_scheduler_t*, xce_preason_set_t*); extern int sched_publish_dispatch(xce_scheduler_t*, xce_job_dispatch_t*); /* bug-1760: exposed (was `static sched_publish_check_rejoin`) so diff --git a/src/scheduler/src/scheduler.c b/src/scheduler/src/scheduler.c index b2c2c963..87957073 100644 --- a/src/scheduler/src/scheduler.c +++ b/src/scheduler/src/scheduler.c @@ -138,12 +138,20 @@ static void* sched_job_picker(void* arg) return NULL; } -static int sched_make_seqjob_allocation(xce_scheduler_t* sched, +/* scheduler-sim-live-allocation spec, task 2.2 (Core-Safe Allocation + * Chain): both retyped to xce_sched_core_t* -- neither ever touched + * anything beyond core->seqjob_allocator/core->parjob_allocator (already + * genuinely core-scoped fields, just previously read via sched->core.*). + * Their only callers are sched_make_primary_alloc_()'s two branches below, + * also migrated in this task -- mirrors task 1.3's "a private static + * helper with no other callers besides the functions being migrated + * should be migrated alongside them" precedent. */ +static int sched_make_seqjob_allocation(xce_sched_core_t* core, xce_sched_ctx_t* ctx) { xce_sched_plugin_t* plugin = NULL; - plugin = sched->core.seqjob_allocator; + plugin = core->seqjob_allocator; if (plugin->job_alloc_fn == NULL) { ERROR("%s plugin %s has no allocation function", __func__, plugin->name); @@ -153,12 +161,12 @@ static int sched_make_seqjob_allocation(xce_scheduler_t* sched, return plugin->job_alloc_fn(plugin, ctx); } -static int sched_make_parjob_allocation(xce_scheduler_t* sched, +static int sched_make_parjob_allocation(xce_sched_core_t* core, xce_sched_ctx_t* ctx) { xce_sched_plugin_t* plugin = NULL; - plugin = sched->core.parjob_allocator; + plugin = core->parjob_allocator; if (plugin->job_alloc_fn == NULL) { ERROR("%s plugin %s has no allocation function", __func__, plugin->name); @@ -269,7 +277,7 @@ static void sched_pend_from_cached_reason_(xce_sched_ctx_t* ctx, int category) add_job_preason(ctx->reason->reasons, category, NULL, NULL); } -static int sched_make_primary_alloc_(xce_scheduler_t* sched, +static int sched_make_primary_alloc_(xce_sched_core_t* core, xce_sched_ctx_t* ctx) { xce_primary_resreq_t* primary = ctx->primary; @@ -281,17 +289,24 @@ static int sched_make_primary_alloc_(xce_scheduler_t* sched, cache_obj = sched_primary_cache_obj_(ctx, &scratch_primary, &scratch_obj); - /* Req 7.4: a cache hit pends the job immediately, without invoking - * either allocator for this attempt. */ - if (cache_lookup(sched, cache_obj, &reason_category) == 1) { + /* Req 7.4 / scheduler-sim-live-allocation spec, task 2.2 + * (Unsatisfiable-Cache Callback Seam): consult the driver-registered + * lookup hook instead of calling cache_lookup() directly -- a NULL + * hook (simulation mode, which never registers one) means "always + * compute fresh", never an error, so this is the one primary-resreq + * dispatch chokepoint the seam exists for. A cache hit pends the job + * immediately, without invoking either allocator for this attempt. */ + if ((core->unsatisfiable_lookup_cb != NULL) + && (core->unsatisfiable_lookup_cb(core, cache_obj, &reason_category) + == 1)) { sched_pend_from_cached_reason_(ctx, reason_category); return 0; } if (primary->maxTasks == 1) { - rc = sched_make_seqjob_allocation(sched, ctx); + rc = sched_make_seqjob_allocation(core, ctx); } else { - rc = sched_make_parjob_allocation(sched, ctx); + rc = sched_make_parjob_allocation(core, ctx); } /* Req 7.3: once the chosen allocator has exhausted every candidate @@ -299,18 +314,34 @@ static int sched_make_primary_alloc_(xce_scheduler_t* sched, * this resreq's fingerprint + identity and the exhausted attempt's own * final pend-reason category, before the caller pends the job. A * negative rc is an infrastructure error, not an unsatisfiable - * determination, so it is never cached; a positive rc is success. */ + * determination, so it is never cached; a positive rc is success. + * Routed through the same NULL-safe seam as the lookup above -- a NULL + * populate hook is simply a no-op, not an error. */ if (rc == 0) { int category = (ctx->reason != NULL) ? ctx->reason->reasons->main_reason : 0; - cache_insert(sched, cache_obj, category); + if (core->unsatisfiable_populate_cb != NULL) { + core->unsatisfiable_populate_cb(core, cache_obj, category); + } } return rc; } -static int sched_make_primary_allocation(xce_scheduler_t* sched, +/* scheduler-sim-live-allocation spec, task 2.2 (Core-Safe Allocation + * Chain): sched_make_primary_allocation()/sched_make_compound_allocation()/ + * sched_make_alter_allocation()/sched_make_allocation() below are now all + * retyped to xce_sched_core_t* core -- read in full before migrating (per + * this task's own escalation clause): each touches nothing beyond + * core->*, ctx/obj fields, and (via sched_make_primary_alloc_() above) the + * one already-seamed cache touch point. No additional normal-mode-only + * state was found, so no escalation is needed. sched_allocator() (this + * file, task 3.1's future home) is the sole caller of sched_make_ + * allocation() and stays xce_scheduler_t*-typed for now -- its call site + * below wraps &(sched->core), the same minimal-argument-wrap pattern + * task 1.2/2.1 already established. */ +static int sched_make_primary_allocation(xce_sched_core_t* core, xce_sched_obj_t* obj) { xce_primary_resreq_t* primary = obj->u.primary->resreq; @@ -321,16 +352,9 @@ static int sched_make_primary_allocation(xce_scheduler_t* sched, return -EINVAL; } - /* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation - * Chain): ctx->sched is now honestly typed xce_sched_core_t* -- pass - * &(sched->core), not sched, the same minimal call-site update - * plugin_prepare_allocation()'s own callers made at task 1.2. This - * function's own xce_scheduler_t* sched parameter stays unchanged - * (retyping sched_make_primary_allocation() itself is task 2.2's - * scope, the dispatch chain). */ - sched_ctx_init(&ctx, &(sched->core), obj); + sched_ctx_init(&ctx, core, obj); sched_ctx_set_primary(&ctx, primary); - rc = sched_make_primary_alloc_(sched, &ctx); + rc = sched_make_primary_alloc_(core, &ctx); if (ctx.alloc != NULL) { MOVE_PTR(obj->alloc, ctx.alloc); } @@ -344,7 +368,7 @@ static int sched_make_primary_allocation(xce_scheduler_t* sched, return rc; } -static int sched_make_compound_allocation(xce_scheduler_t* sched, +static int sched_make_compound_allocation(xce_sched_core_t* core, xce_sched_obj_t* obj) { int i; @@ -352,17 +376,14 @@ static int sched_make_compound_allocation(xce_scheduler_t* sched, xce_sched_ctx_t ctx; int rc = 0; - /* scheduler-sim-live-allocation spec, task 2.1: same minimal - * &(sched->core) call-site update as sched_make_primary_allocation() - * above. */ - sched_ctx_init(&ctx, &(sched->core), obj); + sched_ctx_init(&ctx, core, obj); for (i = 0; i < resreq->primaries.count; i++) { xce_primary_resreq_t* primary = (xce_primary_resreq_t*)xlist_get(&(resreq->primaries), i); sched_ctx_set_primary(&ctx, primary); - rc = sched_make_primary_alloc_(sched, &ctx); + rc = sched_make_primary_alloc_(core, &ctx); if (rc <= 0) { break; } @@ -381,7 +402,7 @@ static int sched_make_compound_allocation(xce_scheduler_t* sched, return rc; } -static int sched_make_alter_allocation(xce_scheduler_t* sched, +static int sched_make_alter_allocation(xce_sched_core_t* core, xce_sched_obj_t* obj) { int i; @@ -395,7 +416,7 @@ static int sched_make_alter_allocation(xce_scheduler_t* sched, continue; } - rc = sched_make_compound_allocation(sched, obj1); + rc = sched_make_compound_allocation(core, obj1); if (rc > 0) { if (obj1->alloc != NULL) { MOVE_PTR(obj->alloc, obj1->alloc); @@ -410,19 +431,19 @@ static int sched_make_alter_allocation(xce_scheduler_t* sched, return 0; } -static int sched_make_allocation(xce_scheduler_t* sched, xce_sched_obj_t* obj) +static int sched_make_allocation(xce_sched_core_t* core, xce_sched_obj_t* obj) { int rc = 0; switch (obj->tag) { case XCE_RESREQ_PRIMARY: - rc = sched_make_primary_allocation(sched, obj); + rc = sched_make_primary_allocation(core, obj); break; case XCE_RESREQ_COMPOUND: - rc = sched_make_compound_allocation(sched, obj); + rc = sched_make_compound_allocation(core, obj); break; case XCE_RESREQ_ALTER: - rc = sched_make_alter_allocation(sched, obj); + rc = sched_make_alter_allocation(core, obj); break; default: rc = -EINVAL; @@ -431,9 +452,13 @@ static int sched_make_allocation(xce_scheduler_t* sched, xce_sched_obj_t* obj) return rc; } +/* commit_decision() stays xce_scheduler_t*-typed: its sole caller, + * sched_allocator() below, is task 3.1's job, not this one. Minimal + * call-site wrap into the now-core-typed sched_commit_decision() -- + * same pattern as every other call site this task touches. */ static int commit_decision(xce_scheduler_t* sched, xce_decision_t* decision) { - return sched_commit_decision(sched, decision); + return sched_commit_decision(&(sched->core), decision); } static void* sched_allocator(void* arg) @@ -497,7 +522,12 @@ static void* sched_allocator(void* arg) plugin_job_election(&(sched->core), job); /* calculate decision for jobid */ - alloc_rc = sched_make_allocation(sched, job->schedobj); + /* scheduler-sim-live-allocation spec, task 2.2: sched_make_ + * allocation() is now core-typed -- pass &(sched->core), the same + * minimal call-site wrap this file's other driver-agnostic call + * sites already use. sched_allocator() itself stays + * xce_scheduler_t*-typed (task 3.1's job). */ + alloc_rc = sched_make_allocation(&(sched->core), job->schedobj); if (alloc_rc < 0) { /* something wrong */ continue; @@ -1620,27 +1650,31 @@ void sched_end_session(xce_scheduler_t* sched) memory_order_release); } -int sched_commit_decision(xce_scheduler_t* sched, xce_decision_t* decision) +/* scheduler-sim-live-allocation spec, task 2.2 (Core-Safe Allocation + * Chain): retyped to xce_sched_core_t* core -- its body already only + * touched plugin_commit_decision()/sched_get_job()/sched_commit_job_alloc() + * (all three already core-typed, tasks 1.2/2.1's "original 6-function + * migration") via &(sched->core), so this is a pure signature migration at + * the top of the function, no body-logic change. Its sole production + * caller, commit_decision() (this file, static), now wraps its own + * still-xce_scheduler_t*-typed argument at the call site instead. */ +int sched_commit_decision(xce_sched_core_t* core, xce_decision_t* decision) { int rc = 0; xce_sched_job_t* job = NULL; - /* scheduler-sim-live-allocation spec, task 1.2: plugin_commit_decision() - * is now core-typed -- pass &(sched->core), same minimal call-site - * update as plugin_job_election()'s own call site (sched_allocator(), - * this file). */ - rc = plugin_commit_decision(&(sched->core), decision); + rc = plugin_commit_decision(core, decision); if (rc < 0) { return rc; } if (decision->op == XCE_DECISION_DISPATCH) { - job = sched_get_job(&(sched->core), decision->u.alloc->jobid); + job = sched_get_job(core, decision->u.alloc->jobid); job->allocs = decision->u.alloc; job->accounts = make_job_account(job->allocs); job->state = JOB_STAT_RUN; - return sched_commit_job_alloc(&(sched->core), job); + return sched_commit_job_alloc(core, job); } return 0; diff --git a/src/scheduler/testsuite/test_scheduler_cache_dispatch.c b/src/scheduler/testsuite/test_scheduler_cache_dispatch.c index a69bbf18..d52a8cb4 100644 --- a/src/scheduler/testsuite/test_scheduler_cache_dispatch.c +++ b/src/scheduler/testsuite/test_scheduler_cache_dispatch.c @@ -95,6 +95,7 @@ #include "preason.h" #include "resobj.h" #include "resreq.h" +#include "sched/alloc_cache.h" #include "scheduler.h" #include "xce/cluster.h" #include "xstring.h" @@ -154,6 +155,42 @@ int __wrap_sched_meet_host_selection(xce_sched_core_t* core, return __real_sched_meet_host_selection(core, w, select); } +/* ════════════════════════════════════════════════════════════════════════ + * spy_unsatisfiable_lookup_cb / spy_unsatisfiable_populate_cb - + * scheduler-sim-live-allocation spec, task 2.2 (Unsatisfiable-Cache + * Callback Seam consumer wiring): registered on sched->core in place of + * the real xce_alloc_cache_lookup_cb()/xce_alloc_cache_populate_cb() + * adapters (main.c's own normal-mode registration, sched_init() itself + * never registers either), so this fixture can count real invocations + * while still delegating to the real cache implementation for correct + * hit/miss behavior. Before this task, sched_make_primary_alloc_() + * (scheduler.c) read sched->unsatisfiable_cache directly and never + * touched core->unsatisfiable_lookup_cb/unsatisfiable_populate_cb at all + * -- these counters staying at 0 through both dispatches is the genuine + * RED signal proving the seam is not yet wired. + * ════════════════════════════════════════════════════════════════════════ */ + +static int g_lookup_cb_calls = 0; +static int g_populate_cb_calls = 0; + +static int spy_unsatisfiable_lookup_cb(xce_sched_core_t* core, + xce_sched_obj_t* obj, + int* out_reason_category) +{ + g_lookup_cb_calls++; + + return xce_alloc_cache_lookup_cb(core, obj, out_reason_category); +} + +static void spy_unsatisfiable_populate_cb(xce_sched_core_t* core, + xce_sched_obj_t* obj, + int reason_category) +{ + g_populate_cb_calls++; + + xce_alloc_cache_populate_cb(core, obj, reason_category); +} + void setUp(void) { return; } void tearDown(void) { return; } @@ -248,6 +285,16 @@ static xce_scheduler_t* start_sched(void) * unsatisfiable for any job (see file header). */ add_worker_with_slots(&(sched->core), WORKER_NAME, slots_res->idx, 0.0f); + /* scheduler-sim-live-allocation spec, task 2.2: sched_init() itself + * never registers the unsatisfiable-cache seam (main.c's normal-mode + * branch is the only production registrant) -- register the spy + * adapters here so this fixture's cache-hit proof genuinely exercises + * the new seam, not just the underlying cache_lookup()/cache_insert() + * calls a pre-migration sched_make_primary_alloc_() would reach some + * other way. */ + sched->core.unsatisfiable_lookup_cb = spy_unsatisfiable_lookup_cb; + sched->core.unsatisfiable_populate_cb = spy_unsatisfiable_populate_cb; + return sched; } @@ -372,6 +419,16 @@ static void test_standalone_primary_cache_hit_skips_allocator(void) calls_job1 > 0, "job 1 (cache miss) must genuinely run the allocator's host " "selection check at least once"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 1, g_lookup_cb_calls, + "job 1's cache miss must be consulted through core->" + "unsatisfiable_lookup_cb (Unsatisfiable-Cache Callback Seam), not " + "a direct cache_lookup() call"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 1, g_populate_cb_calls, + "job 1's exhausted attempt must populate the cache through " + "core->unsatisfiable_populate_cb, not a direct cache_insert() " + "call"); /* Job 2: identical fingerprint + identity -- cache HIT. Must pend * immediately, with zero additional sched_meet_host_selection() @@ -394,6 +451,14 @@ static void test_standalone_primary_cache_hit_skips_allocator(void) decision2->u.reason->reasons->main_reason, "a cache hit must attribute the SAME pend reason category as the " "original unsatisfiable determination (Req 7.5)"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 2, g_lookup_cb_calls, + "job 2's cache hit must also be consulted through core->" + "unsatisfiable_lookup_cb (one more call than after job 1)"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 1, g_populate_cb_calls, + "a cache HIT must never re-populate the cache -- " + "unsatisfiable_populate_cb call count stays at job 1's count"); } int main(void) diff --git a/src/scheduler/testsuite/test_scheduler_cache_dispatch_compound.c b/src/scheduler/testsuite/test_scheduler_cache_dispatch_compound.c index 93713545..706598c7 100644 --- a/src/scheduler/testsuite/test_scheduler_cache_dispatch_compound.c +++ b/src/scheduler/testsuite/test_scheduler_cache_dispatch_compound.c @@ -66,6 +66,7 @@ #include "preason.h" #include "resobj.h" #include "resreq.h" +#include "sched/alloc_cache.h" #include "scheduler.h" #include "xce/cluster.h" #include "xstring.h" @@ -119,6 +120,36 @@ int __wrap_sched_meet_host_selection(xce_sched_core_t* core, return __real_sched_meet_host_selection(core, w, select); } +/* ════════════════════════════════════════════════════════════════════════ + * spy_unsatisfiable_lookup_cb / spy_unsatisfiable_populate_cb -- see + * test_scheduler_cache_dispatch.c's identical spies for the full + * rationale (scheduler-sim-live-allocation spec, task 2.2). Delegates to + * the real xce_alloc_cache_lookup_cb()/xce_alloc_cache_populate_cb() + * adapters so this file's compound-nested-primary cache-hit proof stays + * functionally correct while also counting real seam invocations. + * ════════════════════════════════════════════════════════════════════════ */ + +static int g_lookup_cb_calls = 0; +static int g_populate_cb_calls = 0; + +static int spy_unsatisfiable_lookup_cb(xce_sched_core_t* core, + xce_sched_obj_t* obj, + int* out_reason_category) +{ + g_lookup_cb_calls++; + + return xce_alloc_cache_lookup_cb(core, obj, out_reason_category); +} + +static void spy_unsatisfiable_populate_cb(xce_sched_core_t* core, + xce_sched_obj_t* obj, + int reason_category) +{ + g_populate_cb_calls++; + + xce_alloc_cache_populate_cb(core, obj, reason_category); +} + void setUp(void) { return; } void tearDown(void) { return; } @@ -209,6 +240,12 @@ static xce_scheduler_t* start_sched(void) * unsatisfiable for any job. */ add_worker_with_slots(&(sched->core), WORKER_NAME, slots_res->idx, 0.0f); + /* scheduler-sim-live-allocation spec, task 2.2: see + * test_scheduler_cache_dispatch.c's identical registration for why + * sched_init() alone never wires this seam. */ + sched->core.unsatisfiable_lookup_cb = spy_unsatisfiable_lookup_cb; + sched->core.unsatisfiable_populate_cb = spy_unsatisfiable_populate_cb; + return sched; } @@ -343,6 +380,16 @@ static void test_compound_nested_primary_cache_hit_skips_allocator(void) calls_jobA > 0, "job A (cache miss) must genuinely run the allocator's host " "selection check at least once for its nested primary"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 1, g_lookup_cb_calls, + "job A's cache miss must be consulted through core->" + "unsatisfiable_lookup_cb (Unsatisfiable-Cache Callback Seam), not " + "a direct cache_lookup() call, even for a compound-nested primary"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 1, g_populate_cb_calls, + "job A's exhausted attempt must populate the cache through " + "core->unsatisfiable_populate_cb, not a direct cache_insert() " + "call"); /* Job B: a different job, but its one nested primary shares an * identical fingerprint (same resreq string) and identity (same @@ -365,6 +412,14 @@ static void test_compound_nested_primary_cache_hit_skips_allocator(void) "a cache hit must attribute the SAME pend reason category as the " "original unsatisfiable determination (Req 7.5), even across a " "compound-nested primary"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 2, g_lookup_cb_calls, + "job B's cache hit must also be consulted through core->" + "unsatisfiable_lookup_cb (one more call than after job A)"); + TEST_ASSERT_EQUAL_INT_MESSAGE( + 1, g_populate_cb_calls, + "a cache HIT must never re-populate the cache -- " + "unsatisfiable_populate_cb call count stays at job A's count"); FREEUP(errmsg); } diff --git a/src/scheduler/testsuite/test_scheduler_dispatch_commit.c b/src/scheduler/testsuite/test_scheduler_dispatch_commit.c index 3a1b3969..fdafadc2 100644 --- a/src/scheduler/testsuite/test_scheduler_dispatch_commit.c +++ b/src/scheduler/testsuite/test_scheduler_dispatch_commit.c @@ -162,7 +162,7 @@ static void test_dispatch_commit_transitions_job_to_run(void) decision = make_dispatch_decision(alloc); TEST_ASSERT_NOT_NULL(decision); - rc = sched_commit_decision(&sched, decision); + rc = sched_commit_decision(&(sched.core), decision); TEST_ASSERT_TRUE(rc >= 0); /* the new behavior this task adds */ @@ -218,7 +218,7 @@ static void test_dispatch_commit_survives_round_boundary_before_confirmation(voi decision = make_dispatch_decision(alloc); TEST_ASSERT_NOT_NULL(decision); - rc = sched_commit_decision(&sched, decision); + rc = sched_commit_decision(&(sched.core), decision); TEST_ASSERT_TRUE(rc >= 0); TEST_ASSERT_EQUAL_UINT(JOB_STAT_RUN, job->state); TEST_ASSERT_NOT_NULL(job->accounts); @@ -264,7 +264,7 @@ static void test_pend_decision_does_not_touch_job_state(void) decision = make_pend_decision(reason); TEST_ASSERT_NOT_NULL(decision); - rc = sched_commit_decision(&sched, decision); + rc = sched_commit_decision(&(sched.core), decision); TEST_ASSERT_TRUE(rc >= 0); TEST_ASSERT_EQUAL_UINT(JOB_STAT_PEND, job->state); @@ -316,7 +316,7 @@ static void test_dispatch_commit_survives_several_rounds_before_confirmation(voi decision = make_dispatch_decision(alloc); TEST_ASSERT_NOT_NULL(decision); - rc = sched_commit_decision(&sched, decision); + rc = sched_commit_decision(&(sched.core), decision); TEST_ASSERT_TRUE(rc >= 0); TEST_ASSERT_EQUAL_UINT(JOB_STAT_RUN, job->state); @@ -396,7 +396,7 @@ static float run_dispatch_then_n_rounds(int nrounds) decision = make_dispatch_decision(alloc); TEST_ASSERT_NOT_NULL(decision); - rc = sched_commit_decision(&sched, decision); + rc = sched_commit_decision(&(sched.core), decision); TEST_ASSERT_TRUE(rc >= 0); TEST_ASSERT_EQUAL_UINT(JOB_STAT_RUN, job->state);