feat(scheduler-sim-live-allocation): make capacity checks core-safe (task 1.3)
Re-types sched_meet_host_selection(), sched_check_shared_satisfy() (+its _ helper), sched_check_host_satisfy() (+its _ helper), and the private unsatisfy_() helper they share, from xce_scheduler_t* to xce_sched_core_t*, in resource.c. Fixes every call site this forces (a C signature migration cannot keep the build green otherwise): sched_try_alloc_on_host_() (2 sites, already partially touched by task 1.2), host_iter.c's sched_host_iter_next() (2 sites), and parjob_allocator.c/ seqjob_allocator.c's my_alloc() (1 site each) -- each fix is a minimal &(sched->core) argument wrap, no algorithm change, preserving host_iter/parjob/seqjob's own allocation algorithm exactly as-is. Adds test_core_safe_allocation_chain_driver_parity, proving all three functions produce identical grant/deny results whether given normal-mode-shaped or simulation-mode-shaped core state. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
parent
e8866641a6
commit
55173fca27
13 changed files with 345 additions and 53 deletions
|
|
@ -336,11 +336,17 @@ extern int sched_publish_dispatch(xce_scheduler_t*, xce_job_dispatch_t*);
|
|||
* function for the chicken-and-egg deadlock this closes. */
|
||||
extern void sched_check_pending_rejoin(xce_scheduler_t*);
|
||||
extern void sched_worker_release_host_ctx(xce_sched_worker_t*);
|
||||
extern int sched_meet_host_selection(xce_scheduler_t*, xce_sched_worker_t*,
|
||||
/* scheduler-sim-live-allocation spec, task 1.3: retyped from
|
||||
* xce_scheduler_t* to xce_sched_core_t* -- these three now operate on
|
||||
* shared core state directly, callable identically from either driver
|
||||
* (both xce_scheduler_t and xce_sched_sim_driver_t embed xce_sched_core_t
|
||||
* core as their first member). Body unchanged besides sched->core.X ->
|
||||
* core->X field-access updates. */
|
||||
extern int sched_meet_host_selection(xce_sched_core_t*, xce_sched_worker_t*,
|
||||
xce_select_t*);
|
||||
extern int sched_check_shared_satisfy(xce_scheduler_t*, xvec_t*, xvec_idval_t*,
|
||||
extern int sched_check_shared_satisfy(xce_sched_core_t*, xvec_t*, xvec_idval_t*,
|
||||
xvec_idval_t*);
|
||||
extern int sched_check_host_satisfy(xce_scheduler_t*, xce_sched_worker_t*,
|
||||
extern int sched_check_host_satisfy(xce_sched_core_t*, xce_sched_worker_t*,
|
||||
xvec_t*, xvec_idval_t*, xvec_idval_t*);
|
||||
extern int sched_collect_workers(xce_scheduler_t*, xlist_t*,
|
||||
zarray_iter_skip_fn_t,
|
||||
|
|
|
|||
|
|
@ -129,9 +129,14 @@ xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* 1. Select-expression filter -- existing evaluator, unchanged. */
|
||||
/* 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. */
|
||||
if (!sched_meet_host_selection(
|
||||
sched, w,
|
||||
&(sched->core), w,
|
||||
(ctx->primary != NULL) ? ctx->primary->select : NULL)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -152,7 +157,9 @@ xce_sched_worker_t* sched_host_iter_next(xce_host_iter_t* iter)
|
|||
continue;
|
||||
}
|
||||
|
||||
rc = sched_check_host_satisfy(sched, w, uncomit,
|
||||
/* 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,
|
||||
&(ctx->alloc_req.host),
|
||||
&(ctx->unmeet));
|
||||
if (rc <= 0) {
|
||||
|
|
|
|||
|
|
@ -587,8 +587,12 @@ static int my_alloc(xce_sched_plugin_t* plugin, xce_sched_ctx_t* ctx)
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = sched_check_shared_satisfy(sched, uncomit, &(ctx->alloc_req.shared),
|
||||
&(ctx->unmeet));
|
||||
/* scheduler-sim-live-allocation task 1.3: sched_check_shared_satisfy()
|
||||
* 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. */
|
||||
rc = sched_check_shared_satisfy(&(sched->core), uncomit,
|
||||
&(ctx->alloc_req.shared), &(ctx->unmeet));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,8 +225,12 @@ static int my_alloc(xce_sched_plugin_t* plugin, xce_sched_ctx_t* ctx)
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = sched_check_shared_satisfy(sched, uncomit, &(ctx->alloc_req.shared),
|
||||
&(ctx->unmeet));
|
||||
/* scheduler-sim-live-allocation task 1.3: sched_check_shared_satisfy()
|
||||
* 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. */
|
||||
rc = sched_check_shared_satisfy(&(sched->core), uncomit,
|
||||
&(ctx->alloc_req.shared), &(ctx->unmeet));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ int put_resvals(zarray_t* array, int nres, int* idxs, float* vals)
|
|||
return nres;
|
||||
}
|
||||
|
||||
static int unsatisfy_(xce_scheduler_t* sched, int nres, int* idxs, float* total,
|
||||
static int unsatisfy_(xce_sched_core_t* core, int nres, int* idxs, float* total,
|
||||
float* inuse, float* uncomitted, float* wanted,
|
||||
int* unmeet_idxs, float* unmeet_vals)
|
||||
{
|
||||
|
|
@ -142,7 +142,7 @@ static int unsatisfy_(xce_scheduler_t* sched, int nres, int* idxs, float* total,
|
|||
xce_resource_t* r = NULL;
|
||||
float need = inuse[i] + uncomitted[i] + wanted[i] - total[i];
|
||||
|
||||
vget(sched->core.resmgr, idxs[i], (void**)&r);
|
||||
vget(core->resmgr, idxs[i], (void**)&r);
|
||||
TRACE("%s unmet resource %d (%s) shortfall %f", __func__, idxs[i],
|
||||
r ? r->name : "?", need);
|
||||
|
||||
|
|
@ -218,7 +218,7 @@ void sched_worker_release_host_ctx(xce_sched_worker_t* w)
|
|||
w->host_eval_ctx = NULL;
|
||||
}
|
||||
|
||||
int sched_meet_host_selection(xce_scheduler_t* sched, xce_sched_worker_t* w,
|
||||
int sched_meet_host_selection(xce_sched_core_t* core, xce_sched_worker_t* w,
|
||||
xce_select_t* s)
|
||||
{
|
||||
if (s == NULL || s->root == NULL)
|
||||
|
|
@ -235,12 +235,12 @@ int sched_meet_host_selection(xce_scheduler_t* sched, xce_sched_worker_t* w,
|
|||
}
|
||||
|
||||
/* Fast path: use session-level memoisation context when available. */
|
||||
if (sched->core.sel_eval_ctx != NULL) {
|
||||
if (core->sel_eval_ctx != NULL) {
|
||||
/* Reset memoisation bitmap only when moving to a different host. */
|
||||
if (sched->core.sel_eval_ctx->host != w->host_eval_ctx)
|
||||
select_eval_ctx_reset(sched->core.sel_eval_ctx, w->host_eval_ctx);
|
||||
if (core->sel_eval_ctx->host != w->host_eval_ctx)
|
||||
select_eval_ctx_reset(core->sel_eval_ctx, w->host_eval_ctx);
|
||||
|
||||
int rc = eval_select(s->root, sched->core.sel_eval_ctx);
|
||||
int rc = eval_select(s->root, core->sel_eval_ctx);
|
||||
return (rc > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
|
@ -250,7 +250,7 @@ int sched_meet_host_selection(xce_scheduler_t* sched, xce_sched_worker_t* w,
|
|||
return (rc > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int sched_check_shared_satisfy_(xce_scheduler_t* sched, xvec_t* total,
|
||||
static int sched_check_shared_satisfy_(xce_sched_core_t* core, xvec_t* total,
|
||||
xvec_t* inuse, xvec_t* uncomitted,
|
||||
xvec_idval_t* wanted,
|
||||
xvec_idval_t* unmeet)
|
||||
|
|
@ -273,19 +273,19 @@ static int sched_check_shared_satisfy_(xce_scheduler_t* sched, xvec_t* total,
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = get_resvals(&(sched->core.sharedInst), nres, (int*)wanted->idxs.data,
|
||||
rc = get_resvals(&(core->sharedInst), nres, (int*)wanted->idxs.data,
|
||||
(float*)total->data);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = get_resvals(&(sched->core.sharedInUse), nres, (int*)wanted->idxs.data,
|
||||
rc = get_resvals(&(core->sharedInUse), nres, (int*)wanted->idxs.data,
|
||||
(float*)inuse->data);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = unsatisfy_(sched, nres, (int*)wanted->idxs.data, (float*)total->data,
|
||||
rc = unsatisfy_(core, nres, (int*)wanted->idxs.data, (float*)total->data,
|
||||
(float*)inuse->data, (float*)uncomitted->data,
|
||||
(float*)wanted->vals.data, (int*)unmeet->idxs.data,
|
||||
(float*)unmeet->vals.data);
|
||||
|
|
@ -302,7 +302,7 @@ static int sched_check_shared_satisfy_(xce_scheduler_t* sched, xvec_t* total,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int sched_check_shared_satisfy(xce_scheduler_t* sched, xvec_t* uncomitted,
|
||||
int sched_check_shared_satisfy(xce_sched_core_t* core, xvec_t* uncomitted,
|
||||
xvec_idval_t* wanted, xvec_idval_t* unmeet)
|
||||
{
|
||||
xvec_t total;
|
||||
|
|
@ -313,7 +313,7 @@ int sched_check_shared_satisfy(xce_scheduler_t* sched, xvec_t* uncomitted,
|
|||
return 1;
|
||||
}
|
||||
|
||||
rc = sched_check_shared_satisfy_(sched, &total, &inuse, uncomitted, wanted,
|
||||
rc = sched_check_shared_satisfy_(core, &total, &inuse, uncomitted, wanted,
|
||||
unmeet);
|
||||
if (rc < 0) {
|
||||
xvec_idval_fini(unmeet);
|
||||
|
|
@ -325,7 +325,7 @@ int sched_check_shared_satisfy(xce_scheduler_t* sched, xvec_t* uncomitted,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int sched_check_host_satisfy_(xce_scheduler_t* sched,
|
||||
static int sched_check_host_satisfy_(xce_sched_core_t* core,
|
||||
xce_sched_worker_t* w, xvec_t* total,
|
||||
xvec_t* inuse, xvec_t* uncomitted,
|
||||
xvec_idval_t* wanted, xvec_idval_t* unmeet)
|
||||
|
|
@ -360,7 +360,7 @@ static int sched_check_host_satisfy_(xce_scheduler_t* sched,
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = unsatisfy_(sched, nres, (int*)wanted->idxs.data, (float*)total->data,
|
||||
rc = unsatisfy_(core, nres, (int*)wanted->idxs.data, (float*)total->data,
|
||||
(float*)inuse->data, (float*)uncomitted->data,
|
||||
(float*)wanted->vals.data, (int*)unmeet->idxs.data,
|
||||
(float*)unmeet->vals.data);
|
||||
|
|
@ -375,7 +375,7 @@ static int sched_check_host_satisfy_(xce_scheduler_t* sched,
|
|||
|
||||
return 1;
|
||||
}
|
||||
int sched_check_host_satisfy(xce_scheduler_t* sched, xce_sched_worker_t* w,
|
||||
int sched_check_host_satisfy(xce_sched_core_t* core, xce_sched_worker_t* w,
|
||||
xvec_t* uncomitted, xvec_idval_t* wanted,
|
||||
xvec_idval_t* unmeet)
|
||||
{
|
||||
|
|
@ -387,7 +387,7 @@ int sched_check_host_satisfy(xce_scheduler_t* sched, xce_sched_worker_t* w,
|
|||
return 1;
|
||||
}
|
||||
|
||||
rc = sched_check_host_satisfy_(sched, w, &total, &inuse, uncomitted, wanted,
|
||||
rc = sched_check_host_satisfy_(core, w, &total, &inuse, uncomitted, wanted,
|
||||
unmeet);
|
||||
if (rc < 0) {
|
||||
xvec_idval_fini(unmeet);
|
||||
|
|
@ -502,7 +502,13 @@ int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_scheduler_t* sched,
|
|||
int rc;
|
||||
xvec_t* uncomit = NULL;
|
||||
|
||||
rc = sched_meet_host_selection(sched, w, primary->select);
|
||||
/* 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);
|
||||
if (rc == 0) {
|
||||
if (ctx->reason == NULL) {
|
||||
ctx->reason = make_pendreason(0);
|
||||
|
|
@ -539,8 +545,10 @@ int sched_try_alloc_on_host_(xce_sched_worker_t* w, xce_scheduler_t* sched,
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = sched_check_host_satisfy(sched, w, uncomit, &(ctx->alloc_req.host),
|
||||
&(ctx->unmeet));
|
||||
/* 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,
|
||||
&(ctx->alloc_req.host), &(ctx->unmeet));
|
||||
if (rc < 0) {
|
||||
/* FIXME: */
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@
|
|||
* This also brings in scheduler.h (with the real xce_scheduler_t) and all deps. */
|
||||
#include "../src/resource.c"
|
||||
|
||||
/* scheduler-sim-live-allocation spec, task 1.3: 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 below. */
|
||||
#include "sim.h"
|
||||
|
||||
/* Stubs for symbols used by resource.c functions not under test.
|
||||
* sched_get_worker/sched_get_queue relocated to core.h (scheduler-core
|
||||
* spec, task 4.1) -- now operate on xce_sched_core_t*, not
|
||||
|
|
@ -167,7 +173,7 @@ test_meet_host_selection_null_select_passes(void)
|
|||
memset(&w, 0, sizeof(w));
|
||||
zarray_init(&w.resvals, 4, NULL);
|
||||
|
||||
int rc = sched_meet_host_selection(&sched, &w, NULL);
|
||||
int rc = sched_meet_host_selection(&(sched.core), &w, NULL);
|
||||
TEST_ASSERT_EQUAL_INT(1, rc);
|
||||
|
||||
zarray_fini(&w.resvals);
|
||||
|
|
@ -190,7 +196,7 @@ test_meet_host_selection_always_true_passes(void)
|
|||
TEST_ASSERT_NOT_NULL(root);
|
||||
|
||||
xce_select_t sel = { .root = root };
|
||||
int rc = sched_meet_host_selection(&sched, &w, &sel);
|
||||
int rc = sched_meet_host_selection(&(sched.core), &w, &sel);
|
||||
TEST_ASSERT_EQUAL_INT(1, rc);
|
||||
|
||||
sched_worker_release_host_ctx(&w);
|
||||
|
|
@ -218,7 +224,7 @@ test_meet_host_selection_always_false_fails(void)
|
|||
TEST_ASSERT_NOT_NULL(root);
|
||||
|
||||
xce_select_t sel = { .root = root };
|
||||
int rc = sched_meet_host_selection(&sched, &w, &sel);
|
||||
int rc = sched_meet_host_selection(&(sched.core), &w, &sel);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
sched_worker_release_host_ctx(&w);
|
||||
|
|
@ -323,7 +329,7 @@ test_meet_host_selection_numeric_match(void)
|
|||
v8.u.fvalue = 8.0f;
|
||||
zarray_put(&w8.resvals, 0, &v8);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, sched_meet_host_selection(&sched, &w8, &sel));
|
||||
TEST_ASSERT_EQUAL_INT(1, sched_meet_host_selection(&(sched.core), &w8, &sel));
|
||||
|
||||
/* Worker with 2.0 at res_idx=0 — must fail */
|
||||
xce_sched_worker_t w2;
|
||||
|
|
@ -336,7 +342,7 @@ test_meet_host_selection_numeric_match(void)
|
|||
v2.u.fvalue = 2.0f;
|
||||
zarray_put(&w2.resvals, 0, &v2);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, sched_meet_host_selection(&sched, &w2, &sel));
|
||||
TEST_ASSERT_EQUAL_INT(0, sched_meet_host_selection(&(sched.core), &w2, &sel));
|
||||
|
||||
sched_worker_release_host_ctx(&w8);
|
||||
sched_worker_release_host_ctx(&w2);
|
||||
|
|
@ -382,7 +388,7 @@ test_meet_host_selection_string_match(void)
|
|||
vgpu.u.svalue = "gpu";
|
||||
zarray_put(&wgpu.resvals, 1, &vgpu);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, sched_meet_host_selection(&sched, &wgpu, &sel));
|
||||
TEST_ASSERT_EQUAL_INT(1, sched_meet_host_selection(&(sched.core), &wgpu, &sel));
|
||||
|
||||
/* Worker with "cpu" at res_idx=1 — must fail */
|
||||
xce_sched_worker_t wcpu;
|
||||
|
|
@ -395,7 +401,7 @@ test_meet_host_selection_string_match(void)
|
|||
vcpu.u.svalue = "cpu";
|
||||
zarray_put(&wcpu.resvals, 1, &vcpu);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, sched_meet_host_selection(&sched, &wcpu, &sel));
|
||||
TEST_ASSERT_EQUAL_INT(0, sched_meet_host_selection(&(sched.core), &wcpu, &sel));
|
||||
|
||||
sched_worker_release_host_ctx(&wgpu);
|
||||
sched_worker_release_host_ctx(&wcpu);
|
||||
|
|
@ -477,6 +483,248 @@ test_dead_pushmsg_symbols_absent(void)
|
|||
TEST_PASS();
|
||||
}
|
||||
|
||||
/* ── scheduler-sim-live-allocation task 1.3: Core-Safe Allocation Chain ── */
|
||||
|
||||
/*
|
||||
* sched_meet_host_selection()/sched_check_shared_satisfy()/
|
||||
* sched_check_host_satisfy() are re-typed to take xce_sched_core_t* core
|
||||
* directly instead of a normal-mode-only xce_scheduler_t* sched, so they
|
||||
* must be callable identically from either driver's core state --
|
||||
* xce_scheduler_t (this file's own `sched` variables above) and
|
||||
* xce_sched_sim_driver_t (sim.h) both embed xce_sched_core_t core as their
|
||||
* first member (scheduler.h / sim.h). This test drives IDENTICAL inputs
|
||||
* through all three functions against &(normal.core) and &(sim.core) and
|
||||
* asserts identical results -- proving driver-agnosticism, not merely a
|
||||
* retyped signature.
|
||||
*
|
||||
* RED (before this task): fails to compile -- the three functions take
|
||||
* 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).
|
||||
*
|
||||
* No sched_sim_driver_run() call here -- this fixture never spawns a
|
||||
* thread against xce_sched_sim_driver_t, only reads/writes its embedded
|
||||
* `core` synchronously within this function's own lifetime, so bug-1598's
|
||||
* stack-use-after-return hazard (a stack-local sim driver outliving a
|
||||
* never-joined thread) does not apply.
|
||||
*/
|
||||
static void init_test_resmgr(xce_sched_core_t* core)
|
||||
{
|
||||
kvmgr_params_t resmgr_params = { .key_type = KVMGR_KEY_STRING,
|
||||
.nslots = 8,
|
||||
.delta = 4,
|
||||
.datakiller = NULL };
|
||||
|
||||
core->resmgr = makeInstance(&xkvmgr_type, &resmgr_params);
|
||||
TEST_ASSERT_NOT_NULL(core->resmgr);
|
||||
}
|
||||
|
||||
static void
|
||||
test_core_safe_allocation_chain_driver_parity(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);
|
||||
|
||||
memset(&sched_normal, 0, sizeof(sched_normal));
|
||||
memset(&sim_shape, 0, sizeof(sim_shape));
|
||||
init_test_resmgr(core_normal);
|
||||
init_test_resmgr(core_sim);
|
||||
|
||||
/* --- sched_meet_host_selection(): NULL select always passes -------- */
|
||||
{
|
||||
xce_sched_worker_t w;
|
||||
int rc_normal, rc_sim;
|
||||
|
||||
memset(&w, 0, sizeof(w));
|
||||
zarray_init(&w.resvals, 4, NULL);
|
||||
|
||||
rc_normal = sched_meet_host_selection(core_normal, &w, NULL);
|
||||
rc_sim = sched_meet_host_selection(core_sim, &w, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, rc_normal);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
rc_normal, rc_sim,
|
||||
"sched_meet_host_selection() must return identically for a "
|
||||
"normal-mode-shaped and a simulation-mode-shaped core");
|
||||
|
||||
zarray_fini(&w.resvals);
|
||||
}
|
||||
|
||||
/* --- sched_check_shared_satisfy(): identical grant/deny ------------- */
|
||||
{
|
||||
xvec_t uncomitted_n, uncomitted_s;
|
||||
xvec_idval_t wanted_n, wanted_s, unmeet_n, unmeet_s;
|
||||
xce_val_t total, inuse;
|
||||
int rc_normal, rc_sim;
|
||||
|
||||
zarray_init(&core_normal->sharedInst, 4, NULL);
|
||||
zarray_init(&core_normal->sharedInUse, 4, NULL);
|
||||
zarray_init(&core_sim->sharedInst, 4, NULL);
|
||||
zarray_init(&core_sim->sharedInUse, 4, NULL);
|
||||
|
||||
memset(&total, 0, sizeof(total));
|
||||
total.which = Value_u_fvalue;
|
||||
total.u.fvalue = 10.0f;
|
||||
memset(&inuse, 0, sizeof(inuse));
|
||||
inuse.which = Value_u_fvalue;
|
||||
inuse.u.fvalue = 3.0f;
|
||||
|
||||
zarray_put(&core_normal->sharedInst, 0, &total);
|
||||
zarray_put(&core_normal->sharedInUse, 0, &inuse);
|
||||
zarray_put(&core_sim->sharedInst, 0, &total);
|
||||
zarray_put(&core_sim->sharedInUse, 0, &inuse);
|
||||
|
||||
/* Grant: wants 5.0, only 3.0 in use out of 10.0 total. */
|
||||
xvec_init(&uncomitted_n, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_n, 1);
|
||||
xvec_idval_store(&wanted_n, 0, 5.0f);
|
||||
xvec_init(&uncomitted_s, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_s, 1);
|
||||
xvec_idval_store(&wanted_s, 0, 5.0f);
|
||||
|
||||
rc_normal = sched_check_shared_satisfy(core_normal, &uncomitted_n,
|
||||
&wanted_n, &unmeet_n);
|
||||
rc_sim = sched_check_shared_satisfy(core_sim, &uncomitted_s,
|
||||
&wanted_s, &unmeet_s);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, rc_normal);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
rc_normal, rc_sim,
|
||||
"sched_check_shared_satisfy() must grant identically for a "
|
||||
"normal-mode-shaped and a simulation-mode-shaped core");
|
||||
|
||||
xvec_fini(&uncomitted_n);
|
||||
xvec_idval_fini(&wanted_n);
|
||||
xvec_idval_fini(&unmeet_n);
|
||||
xvec_fini(&uncomitted_s);
|
||||
xvec_idval_fini(&wanted_s);
|
||||
xvec_idval_fini(&unmeet_s);
|
||||
|
||||
/* Deny: wants 8.0, only 7.0 of headroom remains (10.0 - 3.0). */
|
||||
xvec_init(&uncomitted_n, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_n, 1);
|
||||
xvec_idval_store(&wanted_n, 0, 8.0f);
|
||||
xvec_init(&uncomitted_s, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_s, 1);
|
||||
xvec_idval_store(&wanted_s, 0, 8.0f);
|
||||
|
||||
rc_normal = sched_check_shared_satisfy(core_normal, &uncomitted_n,
|
||||
&wanted_n, &unmeet_n);
|
||||
rc_sim = sched_check_shared_satisfy(core_sim, &uncomitted_s,
|
||||
&wanted_s, &unmeet_s);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, rc_normal);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
rc_normal, rc_sim,
|
||||
"sched_check_shared_satisfy() must deny identically for a "
|
||||
"normal-mode-shaped and a simulation-mode-shaped core");
|
||||
|
||||
xvec_fini(&uncomitted_n);
|
||||
xvec_idval_fini(&wanted_n);
|
||||
xvec_idval_fini(&unmeet_n);
|
||||
xvec_fini(&uncomitted_s);
|
||||
xvec_idval_fini(&wanted_s);
|
||||
xvec_idval_fini(&unmeet_s);
|
||||
|
||||
zarray_fini(&core_normal->sharedInst);
|
||||
zarray_fini(&core_normal->sharedInUse);
|
||||
zarray_fini(&core_sim->sharedInst);
|
||||
zarray_fini(&core_sim->sharedInUse);
|
||||
}
|
||||
|
||||
/* --- sched_check_host_satisfy(): identical grant/deny --------------- */
|
||||
{
|
||||
xce_sched_worker_t w_normal, w_sim;
|
||||
xvec_t uncomitted_n, uncomitted_s;
|
||||
xvec_idval_t wanted_n, wanted_s, unmeet_n, unmeet_s;
|
||||
xce_val_t total, inuse;
|
||||
int rc_normal, rc_sim;
|
||||
|
||||
memset(&w_normal, 0, sizeof(w_normal));
|
||||
memset(&w_sim, 0, sizeof(w_sim));
|
||||
zarray_init(&w_normal.resvals, 4, NULL);
|
||||
zarray_init(&w_normal.resInUse, 4, NULL);
|
||||
zarray_init(&w_sim.resvals, 4, NULL);
|
||||
zarray_init(&w_sim.resInUse, 4, NULL);
|
||||
|
||||
memset(&total, 0, sizeof(total));
|
||||
total.which = Value_u_fvalue;
|
||||
total.u.fvalue = 10.0f;
|
||||
memset(&inuse, 0, sizeof(inuse));
|
||||
inuse.which = Value_u_fvalue;
|
||||
inuse.u.fvalue = 3.0f;
|
||||
|
||||
zarray_put(&w_normal.resvals, 0, &total);
|
||||
zarray_put(&w_normal.resInUse, 0, &inuse);
|
||||
zarray_put(&w_sim.resvals, 0, &total);
|
||||
zarray_put(&w_sim.resInUse, 0, &inuse);
|
||||
|
||||
/* Grant */
|
||||
xvec_init(&uncomitted_n, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_n, 1);
|
||||
xvec_idval_store(&wanted_n, 0, 5.0f);
|
||||
xvec_init(&uncomitted_s, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_s, 1);
|
||||
xvec_idval_store(&wanted_s, 0, 5.0f);
|
||||
|
||||
rc_normal = sched_check_host_satisfy(core_normal, &w_normal,
|
||||
&uncomitted_n, &wanted_n,
|
||||
&unmeet_n);
|
||||
rc_sim = sched_check_host_satisfy(core_sim, &w_sim, &uncomitted_s,
|
||||
&wanted_s, &unmeet_s);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(1, rc_normal);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
rc_normal, rc_sim,
|
||||
"sched_check_host_satisfy() must grant identically for a "
|
||||
"normal-mode-shaped and a simulation-mode-shaped core");
|
||||
|
||||
xvec_fini(&uncomitted_n);
|
||||
xvec_idval_fini(&wanted_n);
|
||||
xvec_idval_fini(&unmeet_n);
|
||||
xvec_fini(&uncomitted_s);
|
||||
xvec_idval_fini(&wanted_s);
|
||||
xvec_idval_fini(&unmeet_s);
|
||||
|
||||
/* Deny */
|
||||
xvec_init(&uncomitted_n, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_n, 1);
|
||||
xvec_idval_store(&wanted_n, 0, 8.0f);
|
||||
xvec_init(&uncomitted_s, 1, sizeof(float));
|
||||
xvec_idval_init(&wanted_s, 1);
|
||||
xvec_idval_store(&wanted_s, 0, 8.0f);
|
||||
|
||||
rc_normal = sched_check_host_satisfy(core_normal, &w_normal,
|
||||
&uncomitted_n, &wanted_n,
|
||||
&unmeet_n);
|
||||
rc_sim = sched_check_host_satisfy(core_sim, &w_sim, &uncomitted_s,
|
||||
&wanted_s, &unmeet_s);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, rc_normal);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
rc_normal, rc_sim,
|
||||
"sched_check_host_satisfy() must deny identically for a "
|
||||
"normal-mode-shaped and a simulation-mode-shaped core");
|
||||
|
||||
xvec_fini(&uncomitted_n);
|
||||
xvec_idval_fini(&wanted_n);
|
||||
xvec_idval_fini(&unmeet_n);
|
||||
xvec_fini(&uncomitted_s);
|
||||
xvec_idval_fini(&wanted_s);
|
||||
xvec_idval_fini(&unmeet_s);
|
||||
|
||||
zarray_fini(&w_normal.resvals);
|
||||
zarray_fini(&w_normal.resInUse);
|
||||
zarray_fini(&w_sim.resvals);
|
||||
zarray_fini(&w_sim.resInUse);
|
||||
}
|
||||
|
||||
destroy(core_normal->resmgr);
|
||||
destroy(core_sim->resmgr);
|
||||
}
|
||||
|
||||
#define TEST(x) \
|
||||
do { \
|
||||
if (check_test(&arguments, #x)) { \
|
||||
|
|
@ -505,6 +753,7 @@ int main(int argc, char* argv[])
|
|||
TEST(test_new_sched_op_enum_values_exist);
|
||||
TEST(test_sched_update_existing_queue_null_payload);
|
||||
TEST(test_dead_pushmsg_symbols_absent);
|
||||
TEST(test_core_safe_allocation_chain_driver_parity);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,19 +136,22 @@ int __wrap_xcecli_join(xcecli_ctx_t c, int role, hostattrs_t* attrs)
|
|||
* the decisive "did the real allocator run" signal.
|
||||
* ════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
extern int __real_sched_meet_host_selection(xce_scheduler_t*,
|
||||
/* scheduler-sim-live-allocation task 1.3: sched_meet_host_selection() is
|
||||
* now core-typed (xce_sched_core_t*, not xce_scheduler_t*) -- the linker
|
||||
* --wrap= interposition must match the real symbol's current signature. */
|
||||
extern int __real_sched_meet_host_selection(xce_sched_core_t*,
|
||||
xce_sched_worker_t*,
|
||||
xce_select_t*);
|
||||
|
||||
static int g_select_calls = 0;
|
||||
|
||||
int __wrap_sched_meet_host_selection(xce_scheduler_t* sched,
|
||||
int __wrap_sched_meet_host_selection(xce_sched_core_t* core,
|
||||
xce_sched_worker_t* w,
|
||||
xce_select_t* select)
|
||||
{
|
||||
g_select_calls++;
|
||||
|
||||
return __real_sched_meet_host_selection(sched, w, select);
|
||||
return __real_sched_meet_host_selection(core, w, select);
|
||||
}
|
||||
|
||||
void setUp(void) { return; }
|
||||
|
|
|
|||
|
|
@ -101,19 +101,22 @@ int __wrap_xcecli_join(xcecli_ctx_t c, int role, hostattrs_t* attrs)
|
|||
* identical wrap for rationale.
|
||||
* ════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
extern int __real_sched_meet_host_selection(xce_scheduler_t*,
|
||||
/* scheduler-sim-live-allocation task 1.3: sched_meet_host_selection() is
|
||||
* now core-typed (xce_sched_core_t*, not xce_scheduler_t*) -- the linker
|
||||
* --wrap= interposition must match the real symbol's current signature. */
|
||||
extern int __real_sched_meet_host_selection(xce_sched_core_t*,
|
||||
xce_sched_worker_t*,
|
||||
xce_select_t*);
|
||||
|
||||
static int g_select_calls = 0;
|
||||
|
||||
int __wrap_sched_meet_host_selection(xce_scheduler_t* sched,
|
||||
int __wrap_sched_meet_host_selection(xce_sched_core_t* core,
|
||||
xce_sched_worker_t* w,
|
||||
xce_select_t* select)
|
||||
{
|
||||
g_select_calls++;
|
||||
|
||||
return __real_sched_meet_host_selection(sched, w, select);
|
||||
return __real_sched_meet_host_selection(core, w, select);
|
||||
}
|
||||
|
||||
void setUp(void) { return; }
|
||||
|
|
|
|||
|
|
@ -815,7 +815,7 @@ static void* capacity_aware_allocator_thread_fn(void* arg)
|
|||
rc = xvec_idval_store(&wanted, g_slots_residx_normal, want);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(sched, w, &uncomitted, &wanted, &unmeet);
|
||||
rc = sched_check_host_satisfy(core, w, &uncomitted, &wanted, &unmeet);
|
||||
|
||||
xvec_fini(&uncomitted);
|
||||
xvec_idval_fini(&wanted);
|
||||
|
|
@ -1404,7 +1404,7 @@ test_contention_parity_matches_real_normal_mode_recording_round_by_round(
|
|||
rc = xvec_idval_store(&wanted, residx_normal, JOBB_WANT);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(&sched, w_normal, &uncomitted, &wanted,
|
||||
rc = sched_check_host_satisfy(&(sched.core), w_normal, &uncomitted, &wanted,
|
||||
&unmeet);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
0, rc,
|
||||
|
|
@ -1425,7 +1425,7 @@ test_contention_parity_matches_real_normal_mode_recording_round_by_round(
|
|||
rc = xvec_idval_store(&wanted, residx_sim, JOBB_WANT);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(&wrapper_sim, w_sim, &uncomitted,
|
||||
rc = sched_check_host_satisfy(&(wrapper_sim.core), w_sim, &uncomitted,
|
||||
&wanted, &unmeet);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
0, rc,
|
||||
|
|
@ -1661,7 +1661,7 @@ static int check_host_satisfy_want(xce_sched_sim_driver_t* sim, float want)
|
|||
rc = xvec_idval_store(&wanted, residx, want);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(&wrapper, w, &uncomitted, &wanted, &unmeet);
|
||||
rc = sched_check_host_satisfy(&(wrapper.core), w, &uncomitted, &wanted, &unmeet);
|
||||
|
||||
xvec_fini(&uncomitted);
|
||||
xvec_idval_fini(&wanted);
|
||||
|
|
|
|||
|
|
@ -826,7 +826,9 @@ static xce_decision_t* decide_one_candidate(xce_scheduler_t* sched,
|
|||
rc = xvec_idval_store(&wanted, g_slots_residx, want);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(sched, w, &uncomitted, &wanted, &unmeet);
|
||||
/* scheduler-sim-live-allocation task 1.3: sched_check_host_satisfy()
|
||||
* is now core-typed -- pass the already-derived `core` local. */
|
||||
rc = sched_check_host_satisfy(core, w, &uncomitted, &wanted, &unmeet);
|
||||
|
||||
xvec_fini(&uncomitted);
|
||||
xvec_idval_fini(&wanted);
|
||||
|
|
@ -915,7 +917,9 @@ static void* preexist_prelude_allocator_thread_fn(void* arg)
|
|||
rc = xvec_idval_store(&wanted, g_slots_residx, PREEXIST_WANT);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(sched, w2, &uncomitted, &wanted, &unmeet);
|
||||
/* task 1.3: sched_check_host_satisfy() is now core-typed -- pass
|
||||
* the already-derived `core` local. */
|
||||
rc = sched_check_host_satisfy(core, w2, &uncomitted, &wanted, &unmeet);
|
||||
|
||||
xvec_fini(&uncomitted);
|
||||
xvec_idval_fini(&wanted);
|
||||
|
|
|
|||
|
|
@ -661,7 +661,10 @@ static void* capacity_aware_allocator_thread_fn(void* arg)
|
|||
rc = xvec_idval_store(&wanted, SLOTS_RESIDX, want);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(sched, w, &uncomitted, &wanted, &unmeet);
|
||||
/* scheduler-sim-live-allocation task 1.3: sched_check_host_
|
||||
* satisfy() is now core-typed -- pass the already-derived `core`
|
||||
* local. */
|
||||
rc = sched_check_host_satisfy(core, w, &uncomitted, &wanted, &unmeet);
|
||||
|
||||
xvec_fini(&uncomitted);
|
||||
xvec_idval_fini(&wanted);
|
||||
|
|
|
|||
|
|
@ -764,7 +764,7 @@ test_reconciled_job_charges_resinuse_before_live_capacity_check(void)
|
|||
rc = xvec_idval_store(&wanted, residx, 5.0f); /* > 2.0 remaining */
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(&wrapper, w, &uncomitted, &wanted, &unmeet);
|
||||
rc = sched_check_host_satisfy(&(wrapper.core), w, &uncomitted, &wanted, &unmeet);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
0, rc,
|
||||
"a job wanting more than the 2.0-unit remaining headroom must be "
|
||||
|
|
@ -782,7 +782,7 @@ test_reconciled_job_charges_resinuse_before_live_capacity_check(void)
|
|||
rc = xvec_idval_store(&wanted, residx, 2.0f); /* == 2.0 remaining, exact fit */
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = sched_check_host_satisfy(&wrapper, w, &uncomitted, &wanted, &unmeet);
|
||||
rc = sched_check_host_satisfy(&(wrapper.core), w, &uncomitted, &wanted, &unmeet);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
1, rc,
|
||||
"a job wanting exactly the 2.0-unit remaining headroom must be "
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue