feat(scheduler-sim-live-allocation): thread core state through allocation context and host search (task 2.1)

Retypes xce_sched_ctx_t.sched (sched/types.h) from void* to
xce_sched_core_t* outright, and sched_try_alloc_on_host_() (resource.c)
to take xce_sched_core_t* directly -- completing what tasks 1.2/1.3
left as temporary &(sched->core) call-site wraps. Removes the two
resulting struct-prefix casts entirely (schedobj.c's
sched_ctx_set_primary(), host_iter.c's sched_host_iter_next()): both
now pass core state through honestly, with no cast.

Updates every sched_ctx_init()/sched_try_alloc_on_host_() call site
tree-wide (scheduler.c, parjob_allocator.c, seqjob_allocator.c) with
zero change to host_iter/parjob/seqjob's own host-iteration/
bucket-construction algorithm.

Adds a driver-parity test for sched_try_alloc_on_host_() proving
identical grant/deny results from normal-mode-shaped and
simulation-mode-shaped core state.

Flags (for task 2.3) a confirmed-dead, type-confused write at
plugins/limit.c:319 (ctx.sched = plugin->sched) -- never read today,
left untouched since limit.c is task 2.3's boundary, not this one's.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
Rongsong Shen 2026-09-18 13:52:14 +00:00
parent 55173fca27
commit d52c78e4be
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
14 changed files with 229 additions and 54 deletions

View file

@ -25,7 +25,7 @@
- _Boundary: Core-Safe Allocation Chain_
- [ ] 2. Core: driver-agnostic allocation search and dispatch
- [ ] 2.1 Thread shared core state through the per-job allocation context and the per-host allocation attempt
- [x] 2.1 Thread shared core state through the per-job allocation context and the per-host allocation attempt
- Change the per-job allocation context's driver-reference field to carry shared core state instead of a normal-mode-only pointer, updating its handful of existing cast sites
- Re-type the per-host allocation-attempt function (which calls the three capacity checks from 1.3 and the prepare-allocation hook from 1.2) to take shared core state directly
- Thread the same change through the existing multi-host allocation search's entry points, preserving their host-iteration and bucket/plan-construction algorithm exactly as-is
@ -47,6 +47,7 @@
- [ ] 2.3 (P) Make global and host-scoped resource-limit matching driver-agnostic
- Change the limit plugin's global-limit and host-scoped-limit matching functions to read the new honest core-state reference from 1.2 instead of deriving anything from the plugin's normal-mode-only field
- Also address the confirmed-dead, type-confused write at plugins/limit.c:319 (`ctx.sched = plugin->sched;`, flagged during task 2.1's review — never read back today, but stores an `xce_scheduler_t*`-shaped value into a field that is now genuinely `xce_sched_core_t*`-typed): either populate it honestly from the plugin's new core-state reference, or remove the dead write entirely if nothing in the migrated code path needs it
- Keep the existing plugin-hook-registered entry points' external signature unchanged; have them resolve core state from the new field and delegate to the now-driver-agnostic matching logic
- TDD: extend the limit plugin's existing test suite with a case that registers the plugin via the simulation-mode entry point and confirms a match still succeeds and still registers the matched limit's usage, where today it would silently no-op
- Observable: a limit configured on a job registered via the simulation-mode plugin path is matched and its usage instance created, verifiable by reading the plugin's own configured-limits/usage-instances accessors

View file

@ -30,6 +30,16 @@ typedef struct {
struct xce_sched_obj_;
typedef struct xce_sched_obj_ xce_sched_obj_t;
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation
* Chain): forward declaration only -- the full definition lives in core.h.
* Needed here so xce_sched_ctx_t.sched below can be honestly typed
* xce_sched_core_t* instead of a bare void* + cast at every read site. Same
* idiom already used by plugin.h/core.h (an identical repeated typedef is
* valid C11/gnu17 -- see bug-1489 -- so include order relative to core.h/
* plugin.h doesn't matter here either). */
struct xce_sched_core_s;
typedef struct xce_sched_core_s xce_sched_core_t;
/* Req 7.1 (scheduler-allocation spec): pre-computed resreq portion of the
* unsatisfiable-resreq cache key -- resource-usage shape only, independent
* of job identity (user/queue/project, which the full xce_cache_key_t adds
@ -157,7 +167,18 @@ typedef enum {
} xce_alloc_mode_t;
typedef struct {
void* sched;
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation
* Chain): honestly typed as shared core state -- populated by
* sched_ctx_init()'s `arg` parameter (still void* there, since that
* init function is intentionally generic; the implicit void*-to-typed-
* pointer assignment needs no cast). Every caller of sched_ctx_init()
* now passes &(sched->core) (or an already-core-typed pointer, e.g. a
* simulation driver's own &(sim->core)) rather than a bare
* xce_scheduler_t* -- see resource.c's sched_try_alloc_on_host_(),
* host_iter.c's sched_host_iter_next(), and schedobj.c's
* sched_ctx_set_primary() for the leaf/middle consumers this replaces
* a void*+cast with a direct, honest read. */
xce_sched_core_t* sched;
xce_sched_worker_t* worker;
xce_sched_obj_t* schedobj;
xce_primary_resreq_t* primary;

View file

@ -360,8 +360,17 @@ extern xce_alloc_t** sched_make_allocs(xce_scheduler_t*, char*, int, int*,
* 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. */
/* 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
* 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. */
extern int sched_try_alloc_on_host_(xce_sched_worker_t*,
xce_scheduler_t*,
xce_sched_core_t*,
xce_sched_ctx_t*);
extern int get_resvals(zarray_t*, int, int*, float*);
extern int put_resvals(zarray_t*, int, int*, float*);

View file

@ -86,7 +86,7 @@ xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter)
{
host_iter_priv_t* priv;
xce_sched_ctx_t* ctx;
xce_scheduler_t* sched;
xce_sched_core_t* core;
/* Req 3 AC 6: a real cancellation point at least once per invocation
* -- scanning/filtering candidate hosts is fast, non-blocking pure
@ -105,8 +105,11 @@ xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter)
return NULL;
}
ctx = priv->plan->ctx;
sched = (xce_scheduler_t*)ctx->sched;
ctx = priv->plan->ctx;
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation
* Chain): ctx->sched is now honestly typed xce_sched_core_t* -- no
* xce_scheduler_t* cast needed to reach it any more. */
core = ctx->sched;
for (;;) {
xce_sched_worker_t* w = NULL;
@ -129,14 +132,9 @@ xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter)
continue;
}
/* 1. Select-expression filter -- existing evaluator, unchanged.
* scheduler-sim-live-allocation task 1.3: sched_meet_host_
* selection() is now core-typed -- minimal &(sched->core) wrap;
* `sched` itself (derived from ctx->sched) keeps its existing
* xce_scheduler_t* type here, since that field's own migration to
* shared core state is task 2.1's job. */
/* 1. Select-expression filter -- existing evaluator, unchanged. */
if (!sched_meet_host_selection(
&(sched->core), w,
core, w,
(ctx->primary != NULL) ? ctx->primary->select : NULL)) {
continue;
}
@ -157,9 +155,7 @@ xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter)
continue;
}
/* task 1.3: sched_check_host_satisfy() is now core-typed too --
* same minimal &(sched->core) wrap as above. */
rc = sched_check_host_satisfy(&(sched->core), w, uncomit,
rc = sched_check_host_satisfy(core, w, uncomit,
&(ctx->alloc_req.host),
&(ctx->unmeet));
if (rc <= 0) {

View file

@ -487,7 +487,14 @@ static int parjob_try_plan_(xce_scheduler_t* sched, xce_sched_ctx_t* ctx,
ctx->nslots = plan->bucket_slots[b];
ctx->nhosts = 1;
if (sched_try_alloc_on_host_(cand, sched, ctx) > 0) {
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe
* Allocation Chain): sched_try_alloc_on_host_() is now
* core-typed -- minimal &(sched->core) wrap; `sched`
* itself keeps its existing xce_scheduler_t* type here
* (derived from plugin->sched via my_alloc(), the
* plugin's own separate, untouched driver-reference
* field), unchanged by this task. */
if (sched_try_alloc_on_host_(cand, &(sched->core), ctx) > 0) {
int rc = parjob_snapshot_host_req_(
&(claimed[nclaimed].host_req), &(ctx->alloc_req.host));

View file

@ -304,7 +304,14 @@ static int my_alloc(xce_sched_plugin_t* plugin, xce_sched_ctx_t* ctx)
xce_sched_worker_t* cand;
while ((cand = host_iter->next(host_iter)) != NULL) {
if (sched_try_alloc_on_host_(cand, sched, ctx) > 0) {
/* scheduler-sim-live-allocation spec, task 2.1
* (Core-Safe Allocation Chain): sched_try_alloc_on_
* host_() is now core-typed -- minimal &(sched->core)
* wrap; `sched` itself keeps its existing
* xce_scheduler_t* type here (derived from
* plugin->sched), unchanged by this task. */
if (sched_try_alloc_on_host_(cand, &(sched->core), ctx)
> 0) {
w = cand;
break;
}

View file

@ -494,7 +494,7 @@ static int sched_update_res_accounts(xce_sched_core_t* core, zarray_t* array,
* committed want), 0 if this host does not work (a pend reason is
* recorded), <0 on infrastructure error.
*/
int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_scheduler_t* sched,
int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_sched_core_t* core,
xce_sched_ctx_t* ctx)
{
xce_sched_obj_t* schedobj = ctx->schedobj;
@ -502,13 +502,12 @@ int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_scheduler_t* sched,
int rc;
xvec_t* uncomit = NULL;
/* scheduler-sim-live-allocation spec, task 1.3: sched_meet_host_
* selection() is now core-typed -- pass &(sched->core), the same
* minimal call-site update task 1.2 made for plugin_prepare_
* allocation() just below. sched_try_alloc_on_host_() itself keeps its
* existing xce_scheduler_t* sched parameter unchanged (that retyping
* is task 2.1's job, "Core-Safe Allocation Chain"). */
rc = sched_meet_host_selection(&(sched->core), w, primary->select);
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation
* Chain): sched_try_alloc_on_host_() itself is now core-typed, so its
* calls into sched_meet_host_selection()/plugin_prepare_allocation()/
* sched_check_host_satisfy() (all already core-typed, tasks 1.2/1.3)
* pass `core` straight through -- no more &(sched->core) wrap. */
rc = sched_meet_host_selection(core, w, primary->select);
if (rc == 0) {
if (ctx->reason == NULL) {
ctx->reason = make_pendreason(0);
@ -531,23 +530,14 @@ int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_scheduler_t* sched,
ctx->worker = w;
/* scheduler-sim-live-allocation spec, task 1.2: plugin_prepare_
* allocation() is now core-typed -- pass &(sched->core), not sched,
* the same minimal call-site update plugin_begin_session()/
* plugin_end_session()'s own earlier migration made at their call
* sites. sched_try_alloc_on_host_() itself keeps its existing
* xce_scheduler_t* sched parameter unchanged (that retyping is a
* separate task's scope, "Core-Safe Allocation Chain"). */
rc = plugin_prepare_allocation(&(sched->core), ctx);
rc = plugin_prepare_allocation(core, ctx);
if (rc < 0) {
ctx->worker = NULL;
return rc;
}
/* task 1.3: sched_check_host_satisfy() is now core-typed too -- same
* minimal &(sched->core) wrap as sched_meet_host_selection() above. */
rc = sched_check_host_satisfy(&(sched->core), w, uncomit,
rc = sched_check_host_satisfy(core, w, uncomit,
&(ctx->alloc_req.host), &(ctx->unmeet));
if (rc < 0) {
/* FIXME: */
@ -561,7 +551,7 @@ int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_scheduler_t* sched,
for (i = 0; i < ctx->unmeet.count; i++) {
xce_resource_t* r = NULL;
rc = vget(sched->core.resmgr, ((int*)ctx->unmeet.idxs.data)[i],
rc = vget(core->resmgr, ((int*)ctx->unmeet.idxs.data)[i],
(void**)&r);
if (rc < 0) {
continue;

View file

@ -459,6 +459,11 @@ int sched_ctx_init(xce_sched_ctx_t* ctx, void* arg, xce_sched_obj_t* obj)
}
ctx->schedobj = obj;
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation
* Chain): `arg` stays void* here (this init function is intentionally
* generic), but every caller now passes an xce_sched_core_t* (e.g.
* &(sched->core)) rather than a bare xce_scheduler_t* -- the implicit
* void*-to-typed-pointer assignment below needs no cast either way. */
ctx->sched = arg;
ctx->uncomitted.shared = (xvec_t*)calloc(1, sizeof(xvec_t));
@ -503,13 +508,12 @@ void sched_ctx_set_primary(xce_sched_ctx_t* ctx, xce_primary_resreq_t* primary)
{
ctx->primary = primary;
/* scheduler-sim-live-allocation spec, task 1.2: plugin_prepare_
* allocation() is now core-typed -- ctx->sched itself keeps its
* existing void* meaning and cast (xce_scheduler_t* today; retyping
* ctx->sched to carry core state directly is a separate task's scope,
* "Core-Safe Allocation Chain", task 2.1); this call site only adds
* the trailing &(...->core) needed for the now-core-typed callee. */
plugin_prepare_allocation(&(((xce_scheduler_t*)ctx->sched)->core), ctx);
/* scheduler-sim-live-allocation spec, task 2.1 (Core-Safe Allocation
* Chain): ctx->sched is now honestly typed xce_sched_core_t* (set by
* sched_ctx_init() above), so this call needs no cast at all --
* plugin_prepare_allocation() itself was already made core-typed by
* task 1.2. */
plugin_prepare_allocation(ctx->sched, ctx);
return;
}

View file

@ -321,7 +321,14 @@ static int sched_make_primary_allocation(xce_scheduler_t* sched,
return -EINVAL;
}
sched_ctx_init(&ctx, sched, obj);
/* 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_set_primary(&ctx, primary);
rc = sched_make_primary_alloc_(sched, &ctx);
if (ctx.alloc != NULL) {
@ -345,7 +352,10 @@ static int sched_make_compound_allocation(xce_scheduler_t* sched,
xce_sched_ctx_t ctx;
int rc = 0;
sched_ctx_init(&ctx, sched, obj);
/* 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);
for (i = 0; i < resreq->primaries.count; i++) {
xce_primary_resreq_t* primary

View file

@ -49,6 +49,14 @@
#include "sched/alloc_iter.h"
#include "scheduler.h"
/* scheduler-sim-live-allocation spec, task 2.1: sim.h only depends on
* core.h (+ stdbool/stdint/stdio, per its own header comment), so it is
* safe to pull in here just for xce_sched_sim_driver_t -- needed to build
* a simulation-mode-shaped container for the driver-parity test added by
* this task (mirrors test.c's own test_core_safe_allocation_chain_driver_
* parity(), task 1.3). */
#include "sim.h"
/* Pull in the real xce_sched_core_init()/sched_add_worker() (core.c),
* sched_meet_host_selection()/sched_check_host_satisfy()/put_resvals()
* (resource.c, the evaluator + availability check under test), the real
@ -178,7 +186,9 @@ static void make_rack_eq_select(xce_select_node_t* resname,
static void init_ctx(xce_sched_ctx_t* ctx, xce_scheduler_t* sched,
xce_sched_obj_t* obj, xce_primary_resreq_t* primary)
{
int rc = sched_ctx_init(ctx, sched, obj);
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched->core), not sched. */
int rc = sched_ctx_init(ctx, &(sched->core), obj);
TEST_ASSERT_EQUAL_INT(0, rc);
ctx->primary = primary;
}
@ -610,6 +620,112 @@ static void test_init_rejects_missing_ctx(void)
TEST_ASSERT_EQUAL_INT(-EINVAL, host_iter->init(host_iter, NULL, NULL));
}
/*
* 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
* 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
* simulation-mode-shaped (xce_sched_sim_driver_t) core container, proving
* identical grant/deny results regardless of which driver's core state is
* passed in -- mirrors test.c's own
* test_core_safe_allocation_chain_driver_parity() (task 1.3) for the one
* function that test doesn't itself cover.
*
* RED (before task 2.1): fails to compile -- sched_try_alloc_on_host_()
* still takes xce_scheduler_t*, so passing xce_sched_core_t* directly is
* an incompatible-pointer-type error (this toolchain treats
* -Wincompatible-pointer-types as fatal, not a warning).
*/
static int try_alloc_once(xce_sched_core_t* core, xce_sched_worker_t* w,
float host_wanted)
{
xce_sched_ctx_t ctx;
xce_sched_obj_t obj;
xce_primary_resreq_t primary;
int rc;
memset(&primary, 0, sizeof(primary));
primary.minTasks = 1;
primary.maxTasks = 1;
primary.select = NULL;
init_primary_obj(&obj);
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, core, &obj));
ctx.primary = &primary;
/* 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
* 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
* already established for the identical reason. */
ctx.reason = make_pendreason(0);
TEST_ASSERT_NOT_NULL(ctx.reason);
set_wanted_slots(&ctx, host_wanted);
rc = sched_try_alloc_on_host_(w, core, &ctx);
sched_ctx_fini(&ctx);
return rc;
}
static void
test_try_alloc_on_host_grants_and_denies_identically_for_both_driver_shapes(
void)
{
xce_scheduler_t sched_normal;
xce_sched_sim_driver_t sim_shape;
xce_sched_core_t* core_normal = &(sched_normal.core);
xce_sched_core_t* core_sim = &(sim_shape.core);
xce_sched_worker_t* w_normal;
xce_sched_worker_t* w_sim;
int rc_normal, rc_sim;
memset(&sched_normal, 0, sizeof(sched_normal));
memset(&sim_shape, 0, sizeof(sim_shape));
TEST_ASSERT_EQUAL_INT(0, xce_sched_core_init(core_normal));
TEST_ASSERT_EQUAL_INT(0, xce_sched_core_init(core_sim));
add_worker(core_normal, "only", 4.0f, 0.0f, 0.0);
add_worker(core_sim, "only", 4.0f, 0.0f, 0.0);
w_normal = sched_get_worker(core_normal, "only");
w_sim = sched_get_worker(core_sim, "only");
TEST_ASSERT_NOT_NULL(w_normal);
TEST_ASSERT_NOT_NULL(w_sim);
/* Grant: wants 3 of 4 free slots. */
rc_normal = try_alloc_once(core_normal, w_normal, 3.0f);
rc_sim = try_alloc_once(core_sim, w_sim, 3.0f);
TEST_ASSERT_EQUAL_INT(1, rc_normal);
TEST_ASSERT_EQUAL_INT_MESSAGE(
rc_normal, rc_sim,
"sched_try_alloc_on_host_() must grant identically for a "
"normal-mode-shaped and a simulation-mode-shaped core");
/* Deny: wants 8, only 4 free -- the per-ctx uncommitted debit tracked
* by the grant above never touches the worker's own resInUse, so this
* second, fresh-ctx attempt against the SAME worker still sees all 4
* free, exactly like test.c's own driver-parity test reuses one
* worker across a grant then a deny sub-case. */
rc_normal = try_alloc_once(core_normal, w_normal, 8.0f);
rc_sim = try_alloc_once(core_sim, w_sim, 8.0f);
TEST_ASSERT_EQUAL_INT(0, rc_normal);
TEST_ASSERT_EQUAL_INT_MESSAGE(
rc_normal, rc_sim,
"sched_try_alloc_on_host_() must deny identically for a "
"normal-mode-shaped and a simulation-mode-shaped core");
}
int main(void)
{
UNITY_BEGIN();
@ -620,5 +736,7 @@ int main(void)
test_host_too_small_for_larger_search_remains_candidate_for_smaller_search);
RUN_TEST(test_next_has_a_real_cancellation_point);
RUN_TEST(test_init_rejects_missing_ctx);
RUN_TEST(
test_try_alloc_on_host_grants_and_denies_identically_for_both_driver_shapes);
return UNITY_END();
}

View file

@ -394,7 +394,9 @@ test_ctx_init_defaults_alloc_mode_to_normal(void)
obj.tag = XCE_RESREQ_PRIMARY;
xce_sched_ctx_t ctx;
int rc = sched_ctx_init(&ctx, &sched, &obj);
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched.core), not &sched. */
int rc = sched_ctx_init(&ctx, &(sched.core), &obj);
TEST_ASSERT_EQUAL_INT(0, rc);
TEST_ASSERT_EQUAL_INT(XCE_ALLOC_NORMAL, ctx.alloc_mode);

View file

@ -304,7 +304,9 @@ static int drive_my_alloc(xce_scheduler_t* sched, xce_sched_obj_t* obj,
{
xce_sched_plugin_t plugin;
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(ctx, sched, obj));
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched->core), not sched. */
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(ctx, &(sched->core), obj));
sched_ctx_set_primary(ctx, primary);
memset(&plugin, 0, sizeof(plugin));
@ -790,7 +792,9 @@ static void test_descending_bucket_order_succeeds_where_ascending_fails(void)
primary.select = NULL;
init_primary_obj(&obj, &primary_obj, &primary);
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, &sched, &obj));
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched.core), not &sched. */
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, &(sched.core), &obj));
sched_ctx_set_primary(&ctx, &primary);
/* my_alloc() always lazily creates ctx->reason before ever reaching

View file

@ -270,7 +270,9 @@ test_my_alloc_allocates_single_matching_host_through_shared_iterators(void)
init_primary_obj(&obj, &primary_obj, &primary);
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, &sched, &obj));
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched.core), not &sched. */
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. */
@ -325,7 +327,9 @@ test_seqjob_prepare_allocation_guards_against_maxtasks_gt_1_fanout(void)
init_primary_obj(&obj, &primary_obj, &primary);
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, &sched, &obj));
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched.core), not &sched. */
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(&ctx, &(sched.core), &obj));
ctx.primary = &primary;
/* Simulate parjob_prepare_allocation() having already staged this

View file

@ -307,7 +307,9 @@ static int drive_my_alloc(xce_scheduler_t* sched, xce_sched_obj_t* obj,
{
xce_sched_plugin_t plugin;
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(ctx, sched, obj));
/* scheduler-sim-live-allocation spec, task 2.1: ctx->sched is now
* honestly typed xce_sched_core_t* -- pass &(sched->core), not sched. */
TEST_ASSERT_EQUAL_INT(0, sched_ctx_init(ctx, &(sched->core), obj));
sched_ctx_set_primary(ctx, primary);
memset(&plugin, 0, sizeof(plugin));