From d006de385308d156a262421849408e088af887ef Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Wed, 30 Sep 2026 10:02:46 +0000 Subject: [PATCH] refactor(scheduler-allocator-runner): describe the framework runner, not the removed my_alloc() (task 5.1) Comments in scheduler sources and tests that presented the deleted my_alloc()/parjob claim helpers as current code now name sched_allocator_run() and its runner helpers; test helpers and tests named after my_alloc are renamed. No logic or expectation changes. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../specs/scheduler-allocator-runner/tasks.md | 2 +- src/scheduler/include/scheduler.h | 10 ++-- src/scheduler/src/scheduler.c | 4 +- src/scheduler/src/sim_alloc.c | 12 ++-- src/scheduler/testsuite/meson.build | 22 +++---- src/scheduler/testsuite/test_host_iter.c | 8 +-- .../testsuite/test_parjob_combinatorial.c | 58 +++++++++---------- .../testsuite/test_parjob_e2e_multislot.c | 7 ++- .../test_sched_election_sim_fixture.c | 10 ++-- .../testsuite/test_seqjob_allocator.c | 33 +++++------ .../test_seqjob_rewrap_equivalence.c | 37 ++++++------ .../testsuite/test_sim_alloc_limit_fanout.c | 4 +- 12 files changed, 104 insertions(+), 103 deletions(-) diff --git a/.kiro/specs/scheduler-allocator-runner/tasks.md b/.kiro/specs/scheduler-allocator-runner/tasks.md index 84260f17..4ae2f41b 100644 --- a/.kiro/specs/scheduler-allocator-runner/tasks.md +++ b/.kiro/specs/scheduler-allocator-runner/tasks.md @@ -78,7 +78,7 @@ - _Requirements: 1.1, 1.2, 1.5, 1.6, 3.6, 3.7, 5.1, 5.3, 5.5, 7.1_ - [ ] 5. Validation and closure -- [ ] 5.1 Remove stale references to the removed routines +- [x] 5.1 Remove stale references to the removed routines - Rewrite comments in both allocator plugins and the simulation allocator bootstrap that describe the removed private routines, so they describe the framework routine - Rewrite testsuite comments that describe current behaviour in terms of the removed routines (host-iterator, simulation limit fan-out, election simulation fixture and parjob end-to-end multi-slot tests); comments that record history may keep the old names - Done when no scheduler source or test comment presents the removed routines as current code, and the suite still passes diff --git a/src/scheduler/include/scheduler.h b/src/scheduler/include/scheduler.h index 2f6194f6..2513bd30 100644 --- a/src/scheduler/include/scheduler.h +++ b/src/scheduler/include/scheduler.h @@ -408,13 +408,13 @@ extern xce_alloc_t** sched_make_allocs(xce_scheduler_t*, char*, int, int*, * seqjob_allocator.c's pre-rewrap xlist_find() call site -- both now * deleted) so both seqjob_allocator.c and parjob_allocator.c can call this * shared Composition-Algorithm try_alloc leaf directly with real - * parameters, instead of each carrying its own private copy. */ + * parameters, instead of each carrying its own private copy (today its + * one allocator caller is the framework routine in alloc_runner.c). */ /* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation * Chain): retyped from xce_scheduler_t* to xce_sched_core_t* -- callers - * still owning an xce_scheduler_t* (e.g. seqjob_allocator.c's/parjob_ - * allocator.c's my_alloc()/parjob_try_plan_(), which derive their own - * `sched` from the plugin's separate, untouched xce_sched_plugin_t.sched - * field) pass &(sched->core); both xce_scheduler_t and + * still owning an xce_scheduler_t* pass &(sched->core) (the framework + * routine sched_allocator_run(), alloc_runner.c, instead passes the + * plugin's own `core` field straight through); both xce_scheduler_t and * xce_sched_sim_driver_t embed xce_sched_core_t core as their first-class * field, so either driver's own core state satisfies this signature * identically. */ diff --git a/src/scheduler/src/scheduler.c b/src/scheduler/src/scheduler.c index 2ff1762b..e538c20e 100644 --- a/src/scheduler/src/scheduler.c +++ b/src/scheduler/src/scheduler.c @@ -162,8 +162,8 @@ sched_primary_cache_obj_(xce_sched_ctx_t* ctx, * every allocator-exhaustion path already uses to create/populate a pend * reason (make_pendreason() + add_job_preason(), never a direct calloc()/ * field write -- see preason.h/preason.c and e.g. resource.c's - * sched_try_alloc_on_host_() or seqjob_allocator.c's/parjob_allocator.c's - * my_alloc(), all of which follow this exact "if (ctx->reason == NULL) { + * sched_try_alloc_on_host_() or alloc_runner.c's sched_allocator_run(), + * all of which follow this exact "if (ctx->reason == NULL) { * ctx->reason = make_pendreason(0); }" pattern). add_job_preason(reasons, * code, NULL, NULL) is that same function's own "set main reason" branch * (preason.c) -- the identical call shape design.md's cache_insert() diff --git a/src/scheduler/src/sim_alloc.c b/src/scheduler/src/sim_alloc.c index 8f07507d..e9c4a094 100644 --- a/src/scheduler/src/sim_alloc.c +++ b/src/scheduler/src/sim_alloc.c @@ -33,7 +33,7 @@ * needed a genuine xce_scheduler_t*. Because that registration path * (plugin_register()) also sets the plugin instance's own `core` field * (task 1.2) to `&(wrapper.core)`, every later prepare_allocation_hook - * fan-out reached during a real dispatch attempt (my_alloc() -> + * fan-out reached during a real dispatch attempt (then my_alloc() -> * sched_try_alloc_on_host_() -> plugin_prepare_allocation(), resource.c/ * plugin.c) iterated the WRAPPER's own separate core->plugins registry -- * which held only the allocator plugin itself -- never reaching a plugin @@ -44,8 +44,8 @@ * * ── The fix (task 4.3) ──────────────────────────────────────────────────── * seqjob_allocator_init()/parjob_allocator_init() (and every runtime hook - * these plugins register -- seqjob_prepare_allocation()/my_alloc(), - * parjob_prepare_allocation()/my_alloc()/parjob_try_plan_()) now read the + * these plugins register, plus the framework routine sched_allocator_run() + * in alloc_runner.c that both allocate through today) read the * plugin's own honestly-typed `core` field (task 1.2) instead of deriving * an `xce_scheduler_t*` from `plugin->sched` -- mirroring task 2.3's * plugins/limit.c migration exactly. `core` is set by BOTH registration @@ -59,14 +59,14 @@ * separate wrapper registry stands in for the fan-out anymore. * * A narrow exception remains, by necessity, not oversight: - * seqjob_allocator.c's/parjob_allocator.c's own my_alloc() still calls + * the framework routine sched_allocator_run() (alloc_runner.c) still calls * sched_make_allocs() (scheduler.c, out of this task's file boundary) to * build the final xce_alloc_t records for the winning host -- a pre- * existing, real dependency this task did not introduce and cannot retype * (scheduler.c is off-limits). sched_make_allocs()'s own body only ever * reads `sched->core.resmgr` (to resolve a resource idx to its name) and * calls sched_get_id(sched) (`sched->core.lock`/`.nextid`, a fresh - * allocation-id counter) -- both my_alloc()'s own honest `core` parameter + * allocation-id counter) -- both the runner's own honest `core` argument * AND this narrow legacy need are satisfied by keeping a small, * long-lived throwaway `xce_scheduler_t` wrapper (bug-1884: only `lock`, * `nextid` and `resmgr` are set up -- a full xce_sched_core_init() here @@ -172,7 +172,7 @@ void sim_bootstrap_seqjob_allocator(xce_sched_sim_driver_t* sim) /* plugin->sched: deliberately set AFTER registration -- init_fn no * longer reads it (see seqjob_allocator_init()). Narrow, remaining use: - * my_alloc()'s own sched_make_allocs() calls only (never the plugin + * sched_allocator_run()'s sched_make_allocs() calls only (never the plugin * registry/fan-out path fixed above). */ plugin->sched = wrapper; } diff --git a/src/scheduler/testsuite/meson.build b/src/scheduler/testsuite/meson.build index 4c5546d8..c8c0c51d 100644 --- a/src/scheduler/testsuite/meson.build +++ b/src/scheduler/testsuite/meson.build @@ -1795,8 +1795,8 @@ sched_alloc_runner_result_test = executable( install: false) # Task 3.2 (scheduler-allocation spec, Req 9.1): the dedicated pre/post- -# rewrap host-selection EQUIVALENCE proof for seqjob_allocator.c's -# my_alloc() -- fixture states task 3.1's own smoke test does not cover +# rewrap host-selection EQUIVALENCE proof for seqjob allocation (today via +# sched_allocator_run()) -- fixture states task 3.1's smoke test does not cover # (multiple candidate hosts with only one resource-satisfying, a host # failing the select filter specifically despite abundant resources, # iteration-order sensitivity across two equally-valid hosts, and a @@ -1817,14 +1817,14 @@ sched_seqjob_rewrap_equivalence_test = executable( # ceil/floor partition per host-count, descending bucket order within # each plan, a stable exhaustion signal, and a real pthread_testcancel() # cancellation point. White-box #include of -# ../src/plugins/parjob_allocator.c itself (the file under test) -- -# simpler than sched_seqjob_allocator_test's own white-box stack since -# parjob_allocator.c's still-stubbed my_alloc()/parjob_prepare_allocation() -# bodies (untouched by this task -- task 4.2's job) make no calls into -# core.c/resource.c/schedobj.c/host_iter.c at all, so none of those need -# to be pulled in here. Only my_alloc()/prepare_allocation() themselves -# are never called by this file's tests -- they exercise -# parjob_plan_iter_init()/_next()/_fini() directly. +# ../src/plugins/parjob_allocator.c itself (the file under test). Task 4.2 +# added the per-bucket allocation loop tests, which pull in core.c/ +# resource.c/schedobj.c/host_iter.c the same way +# sched_seqjob_allocator_test does; since scheduler-allocator-runner task +# 4.1 that loop is the framework routine sched_allocator_run(), so +# ../src/alloc_runner.c is white-box included too. Task 4.1's own tests +# still exercise parjob_plan_iter_init()/_next()/_fini() directly +# (see the file's header comment). sched_parjob_combinatorial_test = executable( 'sched_parjob_combinatorial_test', ['test_parjob_combinatorial.c'], @@ -2096,7 +2096,7 @@ test('scheduler cache dispatch compound test', # maxTasks>1 parallel job through the full production dispatch path # (sched_init()'s real, live sched_allocator() thread -> the real, `static` # sched_make_allocation()/sched_make_primary_alloc_() choke point -> the -# real parjob_allocator.c my_alloc() -> the real host_iter.c host iterator +# real sched_allocator_run() (parjob's entry) -> the real host_iter.c host iterator # -> a real multi-host xce_job_alloc_t commit), asserting the resulting # job->allocs/decision->u.alloc spans exactly 2 hosts with the correct # per-host slot counts. Same real-scheduler_srcs link technique as diff --git a/src/scheduler/testsuite/test_host_iter.c b/src/scheduler/testsuite/test_host_iter.c index be016062..19573697 100644 --- a/src/scheduler/testsuite/test_host_iter.c +++ b/src/scheduler/testsuite/test_host_iter.c @@ -624,8 +624,8 @@ static void test_init_rejects_missing_ctx(void) * scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation * Chain): sched_try_alloc_on_host_() (resource.c) -- the per-host * allocation-attempt leaf that both host_iter.c's own capacity checks - * ultimately mirror and that parjob_allocator.c's/seqjob_allocator.c's - * my_alloc() call once per candidate -- is now core-typed. This drives it + * ultimately mirror and that the framework routine sched_allocator_run() + * calls once per candidate -- is now core-typed. This drives it * end to end (real sched_ctx_get_uncomit_host()/sched_check_host_satisfy(), * schedobj.c+resource.c, this file's own plugin_prepare_allocation() no-op * stub above) against BOTH a normal-mode-shaped (xce_scheduler_t) and a @@ -659,10 +659,10 @@ static int try_alloc_once(xce_sched_core_t* core, xce_sched_worker_t* w, /* sched_try_alloc_on_host_()'s resource-unmet branch assumes * ctx->reason already exists (unlike its select-mismatch branch, which - * lazily creates one) -- my_alloc() always creates one before ever + * lazily creates one) -- the runner always creates one before ever * reaching this leaf in production; this test calls the leaf directly, * bypassing that step, so it must set one up itself. Same pattern - * test_parjob_combinatorial.c's own direct parjob_try_plan_() call + * test_parjob_combinatorial.c's own direct sched_try_plan_() call * already established for the identical reason. */ ctx.reason = make_pendreason(0); TEST_ASSERT_NOT_NULL(ctx.reason); diff --git a/src/scheduler/testsuite/test_parjob_combinatorial.c b/src/scheduler/testsuite/test_parjob_combinatorial.c index 774f4ea7..31767c2c 100644 --- a/src/scheduler/testsuite/test_parjob_combinatorial.c +++ b/src/scheduler/testsuite/test_parjob_combinatorial.c @@ -2,11 +2,11 @@ * test_parjob_combinatorial.c - tasks 4.1 + 4.2 (scheduler-allocation * spec): unit tests for parjob_allocator.c's REAL combinatorial * xce_alloc_plan_iter_t implementation (Req 2 AC 1-6, Req 4 AC 1) AND - * (task 4.2, this pass) the real per-bucket allocation loop - * (my_alloc()/parjob_try_plan_()/parjob_prepare_allocation(), Req 4 AC - * 2/4/5/6/7). + * (task 4.2) the real per-bucket allocation loop (then my_alloc()/ + * parjob_try_plan_(); today sched_allocator_run()/sched_try_plan_() in + * alloc_runner.c, plus parjob_prepare_allocation(), Req 4 AC 2/4/5/6/7). * - * Task 4.1's own tests below never call my_alloc() -- they drive + * Task 4.1's own tests below never call the allocator -- they drive * parjob_plan_iter_init()/_next()/_fini() (static, hence the white-box * #include) directly, and needed no fixture beyond a bare * xce_primary_resreq_t, since the pre-4.2 my_alloc()/parjob_prepare_ @@ -49,11 +49,11 @@ * test_host_iter.c already established for host_iter_next(). * * Covers (task 4.2, new): - * - multi-bucket success through the real my_alloc() end to end (Req + * - multi-bucket success through the real runner end to end (Req * 4 AC 2/AC 3), including per-bucket resource want scaling with that * bucket's own slot count, not a fixed value (Req 4 AC 5/AC 6) * - the descending-vs-ascending worked example from requirements.md's - * Composition Algorithm, driven directly through parjob_try_plan_() + * Composition Algorithm, driven directly through sched_try_plan_() * with a hand-built plan for each order against the identical host * pool (Req 4 AC 2) * - a mid-plan bucket failure correctly reversing the earlier @@ -103,8 +103,8 @@ /* plugin_register()/plugin_unregister() are referenced by * register_parjob_allocator() (parjob_allocator.c) and core.c * respectively, but no test below calls register_parjob_allocator() -- - * the plan iterator and my_alloc()/parjob_try_plan_() are exercised - * directly. Never actually invoked by anything this file's tests + * the plan iterator and sched_allocator_run()/sched_try_plan_() are + * exercised directly. Never invoked by anything this file's tests * exercise; provided only so the TU links. */ int plugin_register(void* sched, void* plugin) { @@ -177,7 +177,7 @@ int plugin_job_rusage_update(void* s, xce_sched_job_t* j, xce_job_rusages_t* r) } /* Avoids white-box-including the rest of scheduler.c just to build the - * leaf xce_alloc_t records my_alloc()'s success path constructs -- same + * leaf xce_alloc_t records the runner's success path constructs -- same * rationale/shape as test_seqjob_allocator.c's identical stub. This * file's own quantitative per-host assertions go through * assert_uncommitted_host_debit() (real ctx->uncomitted state, untouched @@ -310,7 +310,7 @@ static void init_primary_obj(xce_sched_obj_t* obj, obj->u.primary = primary_obj; } -/* drive_my_alloc - the exact production sequence a job's allocation +/* drive_allocator - the exact production sequence a job's allocation * attempt runs: sched_ctx_init() -> sched_ctx_set_primary() (the real * call that stages ctx->alloc_req.shared via plugin_prepare_allocation()'s * ctx->worker==NULL branch, exactly as sched_make_primary_allocation() @@ -318,8 +318,8 @@ static void init_primary_obj(xce_sched_obj_t* obj, * sched_allocator_run(). Returns its return code; ctx is left * initialized (caller must sched_ctx_fini()). Identical to * test_seqjob_rewrap_equivalence.c's own helper. */ -static int drive_my_alloc(xce_scheduler_t* sched, xce_sched_obj_t* obj, - xce_primary_resreq_t* primary, xce_sched_ctx_t* ctx) +static int drive_allocator(xce_scheduler_t* sched, xce_sched_obj_t* obj, + xce_primary_resreq_t* primary, xce_sched_ctx_t* ctx) { xce_sched_plugin_t plugin; @@ -665,7 +665,7 @@ static void test_next_has_a_real_cancellation_point(void) /* * Req 4 AC 2/AC 3/AC 5/AC 6: a real multi-bucket plan, driven end to end - * through the real my_alloc() (not parjob_try_plan_() directly). Two + * through the real sched_allocator_run() (not sched_try_plan_()). Two * hosts are engineered so the outcome is deterministic REGARDLESS of * sched->core.workers' own hash-based iteration order: host-A has exactly * 2 free slots (only it can satisfy a "need 2" bucket -- host-B's 1 free @@ -679,7 +679,7 @@ static void test_next_has_a_real_cancellation_point(void) * fixed-value bug would either allocate nothing or debit the wrong * amount, and assert_uncommitted_host_debit() below would catch either. */ -static void test_multi_bucket_plan_succeeds_through_real_my_alloc(void) +static void test_multi_bucket_plan_succeeds_through_real_runner(void) { xce_scheduler_t sched; xce_resource_t* slots_res; @@ -712,7 +712,7 @@ static void test_multi_bucket_plan_succeeds_through_real_my_alloc(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); @@ -749,7 +749,7 @@ static void test_multi_bucket_plan_succeeds_through_real_my_alloc(void) * onto the job whatever the rc). ASAN catches a double free or use after * free on the cleanup path. */ -static void test_my_alloc_reports_enomem_when_allocs_cannot_be_built(void) +static void test_allocator_reports_enomem_when_allocs_cannot_be_built(void) { int fail_at; @@ -779,7 +779,7 @@ static void test_my_alloc_reports_enomem_when_allocs_cannot_be_built(void) g_make_allocs_calls = 0; g_make_allocs_fail_at = fail_at; - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); g_make_allocs_fail_at = -1; TEST_ASSERT_EQUAL_INT(-ENOMEM, rc); @@ -803,13 +803,13 @@ static void test_my_alloc_reports_enomem_when_allocs_cannot_be_built(void) * for a small bucket greedily claims whatever it encounters first that * already satisfies it). * - * Driven directly through parjob_try_plan_() (not the real plan + * Driven directly through sched_try_plan_() (not the real plan * iterator, which only ever generates descending order) with a * hand-built xce_alloc_plan_t for each order, against the SAME * unmodified host pool (the descending attempt's claims are rolled back - * before the ascending attempt runs) -- this is the seam task 4.2's own - * bucket-loop factoring (out of my_alloc()) exists to make testable - * without reimplementing the loop in the test. + * before the ascending attempt runs) -- the seam the runner's + * per-plan helper exists to make testable without reimplementing the + * loop in the test. */ static void test_descending_bucket_order_succeeds_where_ascending_fails(void) { @@ -993,7 +993,7 @@ test_mid_plan_bucket_failure_rolls_back_before_later_plan_succeeds(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); @@ -1035,7 +1035,7 @@ test_mid_plan_bucket_failure_rolls_back_before_later_plan_succeeds(void) /* * Req 4 AC 4: when every candidate plan is exhausted without a full - * success, my_alloc() returns the same not-satisfied signal (0) the old + * success, the runner returns the same not-satisfied signal (0) the old * stub always returned, unconditionally -- pend-reason handling * downstream is unaffected by this task's change. */ @@ -1067,7 +1067,7 @@ static void test_returns_zero_when_every_plan_is_exhausted(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(0, rc); TEST_ASSERT_NULL(ctx.alloc); @@ -1081,7 +1081,7 @@ static void test_returns_zero_when_every_plan_is_exhausted(void) * many hosts were used." Task 4.2's fixtures only ever used a per-host * ("slots") resource -- this test drives a job carrying BOTH a per-host * resource AND a genuinely job-level/shared (XCE_RESF_GLOBAL) resource - * through a real multi-host my_alloc() success and asserts the shared + * through a real multi-host runner success and asserts the shared * resource is debited exactly ONCE at the job level, not once per claimed * host/bucket. * @@ -1109,7 +1109,7 @@ static void test_returns_zero_when_every_plan_is_exhausted(void) * by direct dynamic count rather than code inspection alone, that the * job-level (ctx->worker == NULL) prepare pass fires exactly once for this * whole 4-host allocation attempt -- confirming sched_ctx_set_primary()'s - * single call site (schedobj.c), not my_alloc()'s plan/bucket loop, is what + * single call site (schedobj.c), not the runner's plan/bucket loop, is what * drives it. */ static void test_shared_resource_debited_once_regardless_of_host_count(void) @@ -1170,7 +1170,7 @@ static void test_shared_resource_debited_once_regardless_of_host_count(void) init_primary_obj(&obj, &primary_obj, &primary); g_job_level_prepare_calls = 0; - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); @@ -1229,8 +1229,8 @@ int main(void) RUN_TEST(test_plan_generation_ignores_core_state); RUN_TEST(test_init_rejects_invalid_input); RUN_TEST(test_next_has_a_real_cancellation_point); - RUN_TEST(test_multi_bucket_plan_succeeds_through_real_my_alloc); - RUN_TEST(test_my_alloc_reports_enomem_when_allocs_cannot_be_built); + RUN_TEST(test_multi_bucket_plan_succeeds_through_real_runner); + RUN_TEST(test_allocator_reports_enomem_when_allocs_cannot_be_built); RUN_TEST(test_descending_bucket_order_succeeds_where_ascending_fails); RUN_TEST( test_mid_plan_bucket_failure_rolls_back_before_later_plan_succeeds); diff --git a/src/scheduler/testsuite/test_parjob_e2e_multislot.c b/src/scheduler/testsuite/test_parjob_e2e_multislot.c index 1c2c49ea..b69934e9 100644 --- a/src/scheduler/testsuite/test_parjob_e2e_multislot.c +++ b/src/scheduler/testsuite/test_parjob_e2e_multislot.c @@ -5,7 +5,7 @@ * test_host_iter.c, test_alloc_cache.c, test_seqjob_rewrap_equivalence.c, * test_scheduler_cache_dispatch*.c) is white-box: it either #includes the * unit under test directly, or hand-builds an `xce_sched_ctx_t`/worker set - * and calls a plugin's `my_alloc()`/`prepare_allocation_hook` directly. This + * and calls the allocator routine/`prepare_allocation_hook` directly. This * file does neither. It links the REAL, whole `scheduler_srcs` object list * (meson.build's `scheduler_deps`) and drives a real job from submission to * a committed allocation through the SAME functions production jobs use: @@ -26,7 +26,8 @@ * sched_make_primary_alloc_() [task 5.1's * cache-wrapped choke point] -> * sched_make_parjob_allocation() -> the REAL - * parjob_allocator.c my_alloc() -> the REAL + * sched_allocator_run() (alloc_runner.c, + * parjob's registered entry) -> the REAL * host_iter.c host iterator -> the REAL * resource.c sched_try_alloc_on_host_() -> * a REAL multi-host xce_job_alloc_t commit @@ -135,7 +136,7 @@ * 2-host combinatorial split can. This is the same "no host alone * suffices, but two together do" shape task 4.2's own worked example * establishes, now proven through the REAL production dispatch path - * instead of a direct parjob_try_plan_() call. + * instead of a direct sched_try_plan_() call. */ #include #include diff --git a/src/scheduler/testsuite/test_sched_election_sim_fixture.c b/src/scheduler/testsuite/test_sched_election_sim_fixture.c index 12520e27..7e0fa41d 100644 --- a/src/scheduler/testsuite/test_sched_election_sim_fixture.c +++ b/src/scheduler/testsuite/test_sched_election_sim_fixture.c @@ -221,13 +221,13 @@ test_sched_election_thread_pair_runs_against_bare_core_fixture(void) * carries no task-count clause. A maxTasks of 0 (not 1) routes * sched_make_primary_alloc_()'s dispatch (scheduler.c) to * sched_make_parjob_allocation() instead of sched_make_seqjob_ - * allocation() -- and parjob_allocator.c's own my_alloc() deliberately - * bails out for maxTasks <= 1 BEFORE ever creating a pend reason (its - * own "Bailing out here, before ctx->reason is ever created" comment), + * allocation() -- and parjob's acceptance guard (parjob_accepts()) + * rejects maxTasks <= 1, which sched_allocator_run() checks BEFORE + * ever creating a pend reason, * exactly reproducing the "pend reason is NULL" WARN this test is * written to avoid. Set both fields directly so this fixture - * deterministically exercises the seqjob path instead, whose own - * my_alloc() unconditionally creates a reason at entry. */ + * deterministically exercises the seqjob path instead, which has no + * guard, so the runner always creates a reason for it. */ TEST_ASSERT_EQUAL_INT(XCE_RESREQ_PRIMARY, job->schedobj->tag); job->schedobj->u.primary->resreq->minTasks = 1; job->schedobj->u.primary->resreq->maxTasks = 1; diff --git a/src/scheduler/testsuite/test_seqjob_allocator.c b/src/scheduler/testsuite/test_seqjob_allocator.c index e1af08e5..72add1a2 100644 --- a/src/scheduler/testsuite/test_seqjob_allocator.c +++ b/src/scheduler/testsuite/test_seqjob_allocator.c @@ -5,7 +5,7 @@ * seqjob_prepare_allocation() (Req 4.6). * * This is the task-3.1-level smoke coverage only -- proving the rewrapped - * my_alloc() actually runs end to end through the shared iterators (not + * allocator actually runs end to end through the shared iterators (not * just that it compiles) and that the guard closes the fan-out gap Req * 4.6 describes. The exhaustive pre/post-rewrap equivalence proof across * multiple candidate hosts (including a select-filter failure) is task @@ -15,10 +15,10 @@ * White-box #include convention: same combination test_host_iter.c (task * 2.1) already established (core.c + resource.c + schedobj.c + * host_iter.c) for a real worker/resmgr/select/availability fixture, plus - * ../src/plugins/seqjob_allocator.c itself so this file can call its - * `static` my_alloc()/seqjob_prepare_allocation() directly. + * ../src/plugins/seqjob_allocator.c and ../src/alloc_runner.c so this file + * can call sched_allocator_run()/seqjob_prepare_allocation() directly. * - * seqjob_allocator.c's my_alloc() calls the real, exported + * The runner, sched_allocator_run(), calls the real, exported * plugin_prepare_allocation() (plugin.c) to (re-)populate * ctx->alloc_req.host per candidate host -- plugin.c itself is NOT * white-box included here (it needs the full plugins kvmgr/registration @@ -58,7 +58,7 @@ /* plugin_register()/plugin_unregister() are referenced by * register_seqjob_allocator()/core.c respectively, but this file never - * calls register_seqjob_allocator() (it calls my_alloc()/ + * calls register_seqjob_allocator() (it calls sched_allocator_run()/ * seqjob_prepare_allocation() directly, avoiding the full plugins kvmgr * this codebase's real plugin_register() needs) -- never actually * invoked by anything this file's tests exercise. */ @@ -129,7 +129,7 @@ int plugin_job_rusage_update(void* s, xce_sched_job_t* j, xce_job_rusages_t* r) /* Link-satisfying stub for sched_make_allocs() (scheduler.c) -- avoids * white-box-including the rest of that 1382-line file (job/queue/picker * machinery unrelated to seqjob_allocator.c) just to build the leaf - * xce_alloc_t records my_alloc()'s success path constructs. Returns one + * xce_alloc_t records the runner's success path constructs. Returns one * non-NULL, zeroed xce_alloc_t per requested resource index -- sufficient * for this file's assertions, which check WHICH host got allocated and * how many resource entries it carries, not the internal xce_alloc_t @@ -253,14 +253,14 @@ static void init_primary_obj(xce_sched_obj_t* obj, /* * Req 9.1: a maxTasks==1 job with one available, matching host is still - * allocated correctly through the REWRAPPED my_alloc() -- driven through + * allocated correctly through the framework runner -- driven through * the real shared plan_iter -> host_iter composition (seqjob_plan_iter_*, * sched_host_iter_*), not a re-implementation of any of it. Proves the * rewrap actually runs end to end (host selected, resource debited, * ctx->alloc populated), not just that it compiles. */ static void -test_my_alloc_allocates_single_matching_host_through_shared_iterators(void) +test_allocator_allocates_single_matching_host_through_shared_iterators(void) { xce_scheduler_t sched; xce_resource_t* slots_res; @@ -291,15 +291,14 @@ test_my_alloc_allocates_single_matching_host_through_shared_iterators(void) TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, &(sched.core), &obj)); /* Real call -- exercises plugin_prepare_allocation()'s ctx->worker == * NULL branch exactly as sched_make_primary_allocation() does today, - * populating ctx->alloc_req.shared before my_alloc() ever runs. */ + * populating ctx->alloc_req.shared before the runner ever runs. */ sched_ctx_set_primary(&ctx, &primary); memset(&plugin, 0, sizeof(plugin)); plugin.sched = &sched; - /* scheduler-sim-live-allocation spec, task 4.3: my_alloc() now reads - * plugin->core (honestly typed, task 1.2) for every core-safe call, - * alongside the still-needed plugin->sched (sched_make_allocs(), - * scheduler.c, unchanged). */ + /* the runner reads plugin->core (honestly typed) for every core-safe + * call, plugin->sched (sched_make_allocs(), scheduler.c) and seqjob's + * allocator contract. */ plugin.core = &(sched.core); plugin.allocator_iface = &seqjob_alloc_iface; @@ -392,11 +391,11 @@ test_seqjob_prepare_allocation_guards_against_maxtasks_gt_1_fanout(void) /* * bug-1882: when the allocation records cannot be built (sched_make_allocs() - * returns NULL), my_alloc() must report -ENOMEM and leave ctx->alloc NULL + * returns NULL), the runner must report -ENOMEM and leave ctx->alloc NULL * -- sched_make_primary_allocation() moves ctx.alloc onto the job whatever * the rc, so a half-built allocation there would be dispatched. */ -static void test_my_alloc_reports_enomem_when_allocs_cannot_be_built(void) +static void test_allocator_reports_enomem_when_allocs_cannot_be_built(void) { xce_scheduler_t sched; xce_resource_t* slots_res; @@ -440,9 +439,9 @@ static void test_my_alloc_reports_enomem_when_allocs_cannot_be_built(void) int main(void) { UNITY_BEGIN(); - RUN_TEST(test_my_alloc_reports_enomem_when_allocs_cannot_be_built); + RUN_TEST(test_allocator_reports_enomem_when_allocs_cannot_be_built); RUN_TEST( - test_my_alloc_allocates_single_matching_host_through_shared_iterators); + test_allocator_allocates_single_matching_host_through_shared_iterators); RUN_TEST(test_seqjob_prepare_allocation_guards_against_maxtasks_gt_1_fanout); return UNITY_END(); } diff --git a/src/scheduler/testsuite/test_seqjob_rewrap_equivalence.c b/src/scheduler/testsuite/test_seqjob_rewrap_equivalence.c index c7030c17..62b937b2 100644 --- a/src/scheduler/testsuite/test_seqjob_rewrap_equivalence.c +++ b/src/scheduler/testsuite/test_seqjob_rewrap_equivalence.c @@ -1,10 +1,11 @@ /* * test_seqjob_rewrap_equivalence.c - task 3.2 (scheduler-allocation spec): * the dedicated pre/post-rewrap host-selection EQUIVALENCE proof for - * seqjob_allocator.c's my_alloc() (Req 9.1). + * seqjob allocation (Req 9.1) -- then seqjob_allocator.c's my_alloc(), + * today the framework routine sched_allocator_run() (alloc_runner.c). * * task 3.1's own test_seqjob_allocator.c only proves the rewrapped - * my_alloc() still runs end to end through the shared plan_iter/host_iter + * allocator still runs end to end through the shared plan_iter/host_iter * composition (a single-obvious-host smoke case) and that the new * maxTasks==1 guard (Req 4.6) works. Req 9.1's actual claim is narrower * and harder to prove: "which host a job lands on, given the same @@ -22,7 +23,7 @@ * derives the expected pick from the two well-defined, already-unit-tested * primitives the composition is built from -- sched_meet_host_selection() * and sched_check_host_satisfy() (both resource.c, unmodified by the - * rewrap) -- and asserts my_alloc()'s real behavior against that + * rewrap) -- and asserts the allocator's real behavior against that * derivation. This is valid because both the old and new code paths are * confirmed (by reading resource.c) to funnel every host decision through * the exact same leaf, sched_try_alloc_on_host_(): pre-rewrap it was @@ -158,7 +159,7 @@ int plugin_job_rusage_update(void* s, xce_sched_job_t* j, xce_job_rusages_t* r) /* Same rationale as test_seqjob_allocator.c's identical stub: avoids * white-box-including the rest of scheduler.c just to build the leaf - * xce_alloc_t records my_alloc()'s success path constructs. */ + * xce_alloc_t records the runner's success path constructs. */ xce_alloc_t** sched_make_allocs(xce_scheduler_t* sched, char* reserve, int nres, int* idxs, float* vals, int* duration) @@ -303,14 +304,15 @@ static void init_primary_obj(xce_sched_obj_t* obj, obj->u.primary = primary_obj; } -/* drive_my_alloc - the exact production sequence a job's allocation +/* drive_allocator - the exact production sequence a job's allocation * attempt runs: sched_ctx_init() -> sched_ctx_set_primary() (the real * call that stages ctx->alloc_req.shared via plugin_prepare_allocation()'s * ctx->worker==NULL branch, exactly as sched_make_primary_allocation() - * does today) -> my_alloc(). Returns my_alloc()'s return code; ctx is left + * does today) -> seqjob's registered entry point, the framework routine + * sched_allocator_run(). Returns its return code; ctx is left * initialized (caller must sched_ctx_fini()). */ -static int drive_my_alloc(xce_scheduler_t* sched, xce_sched_obj_t* obj, - xce_primary_resreq_t* primary, xce_sched_ctx_t* ctx) +static int drive_allocator(xce_scheduler_t* sched, xce_sched_obj_t* obj, + xce_primary_resreq_t* primary, xce_sched_ctx_t* ctx) { xce_sched_plugin_t plugin; @@ -321,10 +323,9 @@ static int drive_my_alloc(xce_scheduler_t* sched, xce_sched_obj_t* obj, memset(&plugin, 0, sizeof(plugin)); plugin.sched = sched; - /* scheduler-sim-live-allocation spec, task 4.3: my_alloc() now reads - * plugin->core (honestly typed, task 1.2) for every core-safe call, - * alongside the still-needed plugin->sched (sched_make_allocs(), - * scheduler.c, unchanged). */ + /* the runner reads plugin->core (honestly typed) for every core-safe + * call, plugin->sched (sched_make_allocs(), scheduler.c) and seqjob's + * allocator contract. */ plugin.core = &(sched->core); plugin.allocator_iface = &seqjob_alloc_iface; @@ -394,7 +395,7 @@ test_three_hosts_only_resource_satisfying_host_is_chosen_and_debited(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); @@ -458,7 +459,7 @@ test_host_failing_select_filter_is_skipped_despite_plenty_of_resources(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); @@ -472,7 +473,7 @@ test_host_failing_select_filter_is_skipped_despite_plenty_of_resources(void) /* * Req 9.1, fixture 3 (iteration-order sensitivity): two hosts that are - * BOTH select-matching and resource-satisfying -- my_alloc() must pick + * BOTH select-matching and resource-satisfying -- the allocator must pick * whichever one sched->core.workers' own iteration mechanism visits * FIRST. That mechanism -- iter_make()/iter_next() over the RTTI `var` * sched->core.workers -- is the exact same primitive the deleted @@ -483,7 +484,7 @@ test_host_failing_select_filter_is_skipped_despite_plenty_of_resources(void) * identical pre- and post-rewrap. This test derives that order directly * (an independent iter_make()/iter_next() scan below) rather than * assuming worker-insertion order happens to match it, then asserts - * my_alloc()'s pick against the derived value. + * the allocator's pick against the derived value. */ static void test_pick_matches_first_host_in_the_shared_workers_iteration_order(void) @@ -526,7 +527,7 @@ test_pick_matches_first_host_in_the_shared_workers_iteration_order(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); @@ -585,7 +586,7 @@ test_select_fail_then_resource_fail_then_success_does_not_short_circuit(void) init_primary_obj(&obj, &primary_obj, &primary); - rc = drive_my_alloc(&sched, &obj, &primary, &ctx); + rc = drive_allocator(&sched, &obj, &primary, &ctx); TEST_ASSERT_EQUAL_INT(1, rc); TEST_ASSERT_NOT_NULL(ctx.alloc); diff --git a/src/scheduler/testsuite/test_sim_alloc_limit_fanout.c b/src/scheduler/testsuite/test_sim_alloc_limit_fanout.c index d2fb2b37..46554ba7 100644 --- a/src/scheduler/testsuite/test_sim_alloc_limit_fanout.c +++ b/src/scheduler/testsuite/test_sim_alloc_limit_fanout.c @@ -12,7 +12,7 @@ * allocator()'s own init_fn (seqjob_allocator_init()/parjob_allocator_init(), * plugins/seqjob_allocator.c/parjob_allocator.c) still read plugin->sched, * needing a real xce_scheduler_t*. seqjob_allocator.c's/parjob_allocator.c's - * own my_alloc() then resolves its plugin-hook fan-out (plugin_prepare_ + * then-private my_alloc() resolved its plugin-hook fan-out (plugin_prepare_ * allocation()) via THAT SAME plugin instance's own plugin->core field, not * the core parameter threaded down from sched_make_allocation() -- so with * plugin->core pointing at the wrapper's own core, the fan-out iterates the @@ -38,7 +38,7 @@ * Same technique test_sched_election_sim_fixture.c/test_sim_live_ * allocation.c already establish (see those files' own header comments): * links the REAL, unmodified `scheduler_srcs` object list (minus - * src/main.c) so my_alloc()'s real fan-out through the real plugin.c/ + * src/main.c) so the runner's real fan-out through the real plugin.c/ * resource.c/plugins/limit.c chain is genuinely exercised, not stubbed. * * ── Fixture shape ──────────────────────────────────────────────────────