feat(scheduler-allocator-runner): plan generators initialise from the scheduling core (task 1.1)
xce_alloc_plan_iter_t.init takes xce_sched_core_t* instead of xce_scheduler_t*; both built-in generators, both allocators' call sites and the contract-test stub follow. The parjob purity test now shows an identical plan sequence for a NULL and a poisoned core. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e2266582b2
commit
86ee3491dd
6 changed files with 32 additions and 32 deletions
|
|
@ -21,7 +21,7 @@
|
|||
* is usable, not just that a struct literal type-checks.
|
||||
*
|
||||
* Both stub implementations ignore the real xce_primary_resreq_t/
|
||||
* xce_scheduler_t/plan/workers arguments (ok, per the header's own
|
||||
* xce_sched_core_t/plan/workers arguments (ok, per the header's own
|
||||
* "each concrete plan-iterator implementation carries whatever it needs"
|
||||
* note) and always yield exactly one candidate before signaling stable
|
||||
* exhaustion.
|
||||
|
|
@ -45,15 +45,15 @@ typedef struct {
|
|||
|
||||
static int stub_plan_iter_init(xce_alloc_plan_iter_t* iter,
|
||||
xce_primary_resreq_t* resreq,
|
||||
xce_scheduler_t* sched)
|
||||
xce_sched_core_t* core)
|
||||
{
|
||||
stub_plan_priv_t* priv;
|
||||
|
||||
/* Stub: ignores the real resreq/sched state -- a real implementation
|
||||
/* Stub: ignores the real resreq/core state -- a real implementation
|
||||
* (parjob's combinatorial one, seqjob's trivial one) would derive its
|
||||
* plan space from resreq->maxTasks here. */
|
||||
(void)resreq;
|
||||
(void)sched;
|
||||
(void)core;
|
||||
|
||||
if (iter == NULL) {
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* - purity: plan shape/order is a pure function of maxTasks alone,
|
||||
* never inspecting live worker/scheduler state (Req 4 AC 1's "never
|
||||
* inspects live worker state" clause) -- proved by passing a NULL
|
||||
* xce_scheduler_t* to init() and confirming plans still generate
|
||||
* xce_sched_core_t* to init() and confirming plans still generate
|
||||
* correctly
|
||||
* - fini() releases the iterator's private state (Req 2 AC 5)
|
||||
* - Req 2 AC 6: next() calls pthread_testcancel() (or an equivalent
|
||||
|
|
@ -521,21 +521,21 @@ static void test_single_task_yields_single_plan(void)
|
|||
/*
|
||||
* Req 4 AC 1 ("never inspects live worker state" / "pure function of the
|
||||
* task count alone"): the SAME maxTasks value must yield IDENTICAL plan
|
||||
* sequences regardless of what (if anything) `sched` points to --
|
||||
* including a NULL scheduler, and a garbage-but-non-NULL one whose
|
||||
* fields are never touched. Since parjob_plan_iter_init()/_next() never
|
||||
* dereference `sched` at all, a non-NULL "poisoned" scheduler pointer
|
||||
* that would crash on any real field access is a stronger proof of
|
||||
* purity than merely passing NULL.
|
||||
* sequences regardless of what (if anything) `core` points to --
|
||||
* including a NULL core, and a garbage-but-non-NULL one whose fields are
|
||||
* never touched. Since parjob_plan_iter_init()/_next() never dereference
|
||||
* `core` at all, a non-NULL "poisoned" core pointer that would crash on
|
||||
* any real field access is a stronger proof of purity than merely
|
||||
* passing NULL.
|
||||
*/
|
||||
static void test_plan_generation_ignores_scheduler_state(void)
|
||||
static void test_plan_generation_ignores_core_state(void)
|
||||
{
|
||||
xce_primary_resreq_t resreq;
|
||||
xce_alloc_plan_iter_t iter_a_storage;
|
||||
xce_alloc_plan_iter_t* iter_a = &iter_a_storage;
|
||||
xce_alloc_plan_iter_t iter_b_storage;
|
||||
xce_alloc_plan_iter_t* iter_b = &iter_b_storage;
|
||||
xce_scheduler_t* poisoned_sched = (xce_scheduler_t*)0x1;
|
||||
xce_alloc_plan_iter_t* iter_b = &iter_b_storage;
|
||||
xce_sched_core_t* poisoned_core = (xce_sched_core_t*)0x1;
|
||||
int k;
|
||||
|
||||
memset(&resreq, 0, sizeof(resreq));
|
||||
|
|
@ -549,7 +549,7 @@ static void test_plan_generation_ignores_scheduler_state(void)
|
|||
/* A deliberately invalid, non-dereferenceable pointer -- init()/
|
||||
* next() must never read through it, or this test would crash
|
||||
* instead of merely failing an assertion. */
|
||||
TEST_ASSERT_EQUAL_INT(0, iter_b->init(iter_b, &resreq, poisoned_sched));
|
||||
TEST_ASSERT_EQUAL_INT(0, iter_b->init(iter_b, &resreq, poisoned_core));
|
||||
|
||||
for (k = 1; k <= 7; k++) {
|
||||
xce_alloc_plan_t* plan_a = iter_a->next(iter_a);
|
||||
|
|
@ -1229,7 +1229,7 @@ int main(void)
|
|||
RUN_TEST(test_plans_ordered_ascending_host_count_with_balanced_partitions);
|
||||
RUN_TEST(test_plans_for_evenly_divisible_task_count);
|
||||
RUN_TEST(test_single_task_yields_single_plan);
|
||||
RUN_TEST(test_plan_generation_ignores_scheduler_state);
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue