feat(scheduler-sim-diagnostics): display live usage for cluster-wide limit instances
repl_info_limit() now displays accounted-usage/capacity for GLOBAL/SHARED limit instances: iterates limit_get_usage_instances(), filters by vres->limit == matched_limit, reads capacity from core.sharedInst[idx] and accounted usage from core.sharedInUse[idx]. Existence-of-instance and zero-usage are kept distinct per design.md: no matching instance (or one with no populated capacity) prints "no active usage instance yet"; a matched-but-never-charged instance correctly shows accounted=0 instead. Self-caught during implementation and independently confirmed by review: a negative or stale vres->idx (possible per add_vres()'s allocate-then-assign pattern) is not safely rejected by zarray_get_ex()'s idx>=caps check alone -- the new code adds an explicit idx<0 guard rather than copying repl_info_resource_one()'s existing .count-based pre-check (which is itself imprecise for a sparsely-populated zarray, a pre-existing issue left out of scope here). Calling limit_get_usage_instances() for the first time from repl_info.c reproduced the same ~24-file link-stub ripple task 2.1 established for limit_get_configured_limits() -- fixed with the identical pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
parent
5876716eee
commit
6148cb0569
27 changed files with 677 additions and 3 deletions
|
|
@ -29,7 +29,7 @@
|
|||
- _Requirements: 1.6_
|
||||
|
||||
- [ ] 3. Core: Live accounted-usage display
|
||||
- [ ] 3.1 Display usage for cluster-wide (non-host-scoped) limit instances
|
||||
- [x] 3.1 Display usage for cluster-wide (non-host-scoped) limit instances
|
||||
- Iterate `limit_get_usage_instances()`, filter by `vres->limit == matched_limit`; for a GLOBAL/SHARED `vres`, read capacity from `core.sharedInst[idx]` and accounted usage from `core.sharedInUse[idx]`
|
||||
- Existence-of-instance and zero-usage are distinct: zero matching `xce_vres_t` (no capacity entry at all) prints "no active usage instance yet" (Requirement 2.2); a matched `xce_vres_t` whose `sharedInUse[idx]` is `NULL`/absent instead displays a genuine `accounted=0` (it has been evaluated and has a real capacity, just nothing charged against it yet) — existence is gated on the capacity read, never on the in-use read
|
||||
- Observable: a global limit that has matched at least one job shows an accounted/capacity pair reflecting current state; a configured-but-never-evaluated limit shows the explicit no-instance message instead; a matched-but-never-charged limit shows `accounted=0` rather than the no-instance message
|
||||
|
|
|
|||
|
|
@ -1245,6 +1245,123 @@ static void repl_print_limit_host_scope_note_if_implicit(
|
|||
"does not show an explicit host scope\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* repl_print_limit_usage - task 3.1, Requirement 1.4/2.1/2.2/2.3/3.3:
|
||||
* prints `limit`'s live accounted usage against its configured capacity,
|
||||
* one line per distinct GLOBAL/SHARED xce_vres_t instance found in
|
||||
* limit_get_usage_instances() whose `->limit` pointer-equals `limit`.
|
||||
* A host-scoped instance (`vres->vres` not flagged GLOBAL/SHARED) is
|
||||
* task 3.2's job and is silently skipped here, per design.md's own
|
||||
* per-instance filter ("skip -- do not display -- any per-host-scoped
|
||||
* vres in this task").
|
||||
*
|
||||
* Existence-of-instance is gated ONLY on the matched vres's CAPACITY entry
|
||||
* (core.sharedInst[idx]) being present -- never on the in-use entry
|
||||
* (core.sharedInUse[idx]). instantiate_limit() and update_limit_res_value()
|
||||
* run back-to-back inside the same match_job_global_limit_() call
|
||||
* (research.md's "Additional Findings"), so a genuinely existing vres
|
||||
* always has a real capacity by the time it is observable here; only its
|
||||
* in-use entry can legitimately be absent, and an absent in-use entry
|
||||
* means genuine zero usage (accounted=0), never "no instance yet". This
|
||||
* distinction is this task's single most important correctness property
|
||||
* (design.md's own explicit callout) -- do not gate existence on the
|
||||
* in-use read.
|
||||
*/
|
||||
static void repl_print_limit_usage(xce_sched_sim_driver_t* sim,
|
||||
xce_limit_t* limit)
|
||||
{
|
||||
var instances = limit_get_usage_instances(&(sim->core));
|
||||
iterator_t it;
|
||||
int rc;
|
||||
int n_shown = 0;
|
||||
|
||||
if (instances == NULL) {
|
||||
fprintf(stdout, "[sim] no active usage instance yet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rc = iter_make(&it, instances);
|
||||
if (rc < 0) {
|
||||
fprintf(stdout, "[sim] no active usage instance yet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
xce_vres_t* vres = NULL;
|
||||
xce_val_t* cap_v = NULL;
|
||||
|
||||
rc = iter_next(&it, (void**)&vres);
|
||||
if ((rc < 0) || (rc == RTTI_ITER_NO_DATA) || (vres == NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (vres->limit != limit) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((vres->vres->flags & (XCE_RESF_GLOBAL | XCE_RESF_SHARED)) == 0) {
|
||||
/* Host-scoped instance -- task 3.2's branch, not this one. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vres->vres->idx < 0) {
|
||||
/* No capacity entry at all -- this vres has never actually
|
||||
* been evaluated to a usable capacity; do not fabricate a
|
||||
* display for it (Requirement 2.2). */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* zarray_get()/zarray_get_ex() (zarray.c) already bounds-check
|
||||
* `idx` against the array's real capacity (`.caps`) and safely
|
||||
* return NULL for anything out of range -- unlike
|
||||
* repl_info_resource_one()'s own pre-check, this deliberately does
|
||||
* NOT gate on `.count` first: `.count` tracks how many slots have
|
||||
* ever been written (non-NULL), not the array's size, so a sparse
|
||||
* array (a high idx populated while lower ones never were --
|
||||
* exactly this task's own "matched but different resources
|
||||
* populated in different orders" reality) would otherwise be
|
||||
* misread as absent even though zarray_get() itself would return
|
||||
* the real, present entry. */
|
||||
cap_v = (xce_val_t*)zarray_get(&(sim->core.sharedInst),
|
||||
vres->vres->idx);
|
||||
if ((cap_v == NULL) || (cap_v->which != Value_u_fvalue)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
xce_val_t* used_v = NULL;
|
||||
double used = 0.0;
|
||||
char value_str[80];
|
||||
char used_str[80];
|
||||
|
||||
used_v = (xce_val_t*)zarray_get(&(sim->core.sharedInUse),
|
||||
vres->vres->idx);
|
||||
if ((used_v != NULL) && (used_v->which == Value_u_fvalue)) {
|
||||
used = used_v->u.fvalue;
|
||||
}
|
||||
/* used_v == NULL (or wrong-typed) here is genuine zero usage,
|
||||
* never "no instance" -- the capacity check above already
|
||||
* gated existence; existence must not be re-derived from this
|
||||
* read. */
|
||||
|
||||
repl_format_consumable_value_and_used(
|
||||
repl_current_units_mode(sim), vres->vres->name,
|
||||
cap_v->u.fvalue, used, value_str, sizeof(value_str),
|
||||
used_str, sizeof(used_str));
|
||||
|
||||
fprintf(stdout, "[sim] usage %s: accounted=%s capacity=%s\n",
|
||||
vres->vres->name, used_str, value_str);
|
||||
}
|
||||
|
||||
n_shown++;
|
||||
}
|
||||
iter_destroy(&it);
|
||||
|
||||
if (n_shown == 0) {
|
||||
fprintf(stdout, "[sim] no active usage instance yet\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* repl_info_limit - `info limit <name|all>` name/all resolution (task 2.1)
|
||||
* plus, once a genuine match is found, printing that limit's configured
|
||||
|
|
@ -1302,7 +1419,7 @@ static void repl_info_limit(xce_sched_sim_driver_t* sim, const char* arg)
|
|||
}
|
||||
}
|
||||
repl_print_limit_host_scope_note_if_implicit(&(sim->core), limit);
|
||||
/* task 3 adds this limit's live usage. */
|
||||
repl_print_limit_usage(sim, limit);
|
||||
n_shown++;
|
||||
}
|
||||
iter_destroy(&it);
|
||||
|
|
@ -1333,7 +1450,7 @@ static void repl_info_limit(xce_sched_sim_driver_t* sim, const char* arg)
|
|||
}
|
||||
}
|
||||
repl_print_limit_host_scope_note_if_implicit(&(sim->core), match);
|
||||
/* task 3 adds this limit's live usage. */
|
||||
repl_print_limit_usage(sim, match);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sched_reconcile_job_resource_usage(xce_sched_core_t* c,
|
||||
xce_job_account_t* a,
|
||||
xce_job_rusages_t* r)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -165,6 +165,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -133,6 +133,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -130,6 +130,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -125,6 +125,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -513,6 +513,91 @@ static void add_configured_percent_limit_explicit_per_host(
|
|||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Live-usage fixture helpers (task 3.1, Requirement 2.1/2.2/2.3/3.3/1.4) */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* instantiate_and_register_global_vres - drives the real, already-linked
|
||||
* instantiate_limit() (xcelimit.c, part of libxce -- NOT plugins/limit.c,
|
||||
* so no new link dependency) directly against `matched_limit` to create a
|
||||
* genuine xce_vres_t exactly the way match_job_global_limit_()
|
||||
* (plugins/limit.c) would on a real job match, then key_add()s it into
|
||||
* `plugin`'s privdata->instances -- this TU has direct access to
|
||||
* limit_plugin_data_t since it white-box #includes ../src/plugins/limit.c
|
||||
* itself, so this is the same table entry limit_get_usage_instances()
|
||||
* exposes, populated the same way production code populates it.
|
||||
*
|
||||
* `matched_limit` must be configured the way add_configured_limit() shapes
|
||||
* it (absolute value, i.e. percent=0, on "mem") so is_host_based_limit()
|
||||
* returns 0 and instantiate_limit()'s internal `shared` local stays 1 --
|
||||
* add_vres() then flags the resulting vres->vres XCE_RESF_SHARED|
|
||||
* XCE_RESF_GLOBAL, the exact case task 3.1's own scope covers (a per-host
|
||||
* vres is task 3.2's job, deliberately not exercised here).
|
||||
*
|
||||
* user/queue/project are passed as empty strings, never NULL --
|
||||
* instantiate_limit()/build_vres_name() both reject NULL outright (see
|
||||
* xcelimit.c). Since this fixture's limit has no per-user/queue/project
|
||||
* scoping configured (per_consumer=0 for all three, add_configured_limit()'s
|
||||
* own shape), build_vres_name() never actually reads these values into the
|
||||
* vresname it builds anyway -- only "limit=<name>" is ever produced for
|
||||
* this fixture family.
|
||||
*/
|
||||
static xce_vres_t* instantiate_and_register_global_vres(
|
||||
xce_sched_sim_driver_t* sim, xce_sched_plugin_t* plugin,
|
||||
xce_limit_t* matched_limit)
|
||||
{
|
||||
limit_plugin_data_t* privdata = (limit_plugin_data_t*)plugin->data;
|
||||
xce_vres_t* vres = NULL;
|
||||
int rc;
|
||||
|
||||
rc = instantiate_limit(&vres, sim->core.resmgr, matched_limit, "", "",
|
||||
"");
|
||||
/* instantiate_limit() returns its own final key_find()'s positive
|
||||
* result on success (matching match_job_global_limit_()'s own
|
||||
* `if (rc < 0) return rc;` success convention, plugins/limit.c), not
|
||||
* literally 0 -- do not assert rc == 0 here. */
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
TEST_ASSERT_NOT_NULL(vres);
|
||||
TEST_ASSERT_NOT_NULL(vres->vres);
|
||||
TEST_ASSERT_TRUE(vres->vres->idx >= 0);
|
||||
TEST_ASSERT_TRUE_MESSAGE(
|
||||
(vres->vres->flags & (XCE_RESF_GLOBAL | XCE_RESF_SHARED)) != 0,
|
||||
"fixture sanity: this helper only ever produces a GLOBAL/SHARED "
|
||||
"vres -- a per-host vres would mean the fixture's own limit shape "
|
||||
"drifted from add_configured_limit()'s absolute-value contract");
|
||||
|
||||
rc = key_add(privdata->instances, (void*)vres->vres->name, (void*)vres);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
return vres;
|
||||
}
|
||||
|
||||
/*
|
||||
* put_shared_fvalue - manually populates sim->core.sharedInst or
|
||||
* core.sharedInUse at `idx` with a Value_u_fvalue xce_val_t -- the exact
|
||||
* shape put_resvals() (resource.c, deliberately NOT linked into this TU,
|
||||
* see this file's own header comment) would build. Constructed by hand
|
||||
* here rather than driving the real put_resvals()/update_limit_res_value()
|
||||
* so this fixture does not need to link resource.c for real -- a
|
||||
* deliberate, simpler-and-equally-valid choice this task's own brief calls
|
||||
* out ("directly construct an xce_vres_t ... and manually populate
|
||||
* core.sharedInst/core.sharedInUse via zarray_put() ... matching how
|
||||
* update_limit_res_value()/put_resvals() do it").
|
||||
*/
|
||||
static void put_shared_fvalue(zarray_t* array, int idx, double val)
|
||||
{
|
||||
xce_val_t* v = (xce_val_t*)calloc(1, sizeof(*v));
|
||||
int rc;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(v);
|
||||
v->which = Value_u_fvalue;
|
||||
v->u.fvalue = val;
|
||||
|
||||
rc = zarray_put(array, idx, (void*)v);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Tests */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
|
@ -961,6 +1046,160 @@ test_info_limit_named_does_not_duplicate_host_scope_note_when_per_host_explicitl
|
|||
"per_host_explicitly_configured: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Task 3.1's own central Observable #1 (Requirement 2.1, 1.4, 3.3): a
|
||||
* GLOBAL/SHARED limit instance that has genuinely been matched AND charged
|
||||
* shows an accounted/capacity pair reflecting that real state -- not a
|
||||
* placeholder or the no-instance message.
|
||||
*/
|
||||
static void
|
||||
test_info_limit_named_shows_accounted_and_capacity_for_matched_and_charged_global_instance(
|
||||
void)
|
||||
{
|
||||
xce_sched_sim_driver_t sim;
|
||||
xce_sched_plugin_t plugin;
|
||||
xce_scheduler_t group_sched;
|
||||
xce_limit_t* matched = NULL;
|
||||
var limits_handle;
|
||||
xce_vres_t* vres;
|
||||
char* captured;
|
||||
int rc;
|
||||
|
||||
memset(&sim, 0, sizeof(sim));
|
||||
rc = xce_sched_core_init(&(sim.core));
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
register_per_host_resource(&sim, "mem");
|
||||
register_limit_plugin(&sim, &plugin, &group_sched);
|
||||
add_configured_limit(&plugin, "charged_limit");
|
||||
|
||||
limits_handle = limit_get_configured_limits(&(sim.core));
|
||||
rc = key_find(limits_handle, (void*)"charged_limit", (void**)&matched);
|
||||
TEST_ASSERT_TRUE(rc > 0);
|
||||
TEST_ASSERT_NOT_NULL(matched);
|
||||
|
||||
vres = instantiate_and_register_global_vres(&sim, &plugin, matched);
|
||||
put_shared_fvalue(&(sim.core.sharedInst), vres->vres->idx, 10.0);
|
||||
put_shared_fvalue(&(sim.core.sharedInUse), vres->vres->idx, 4.0);
|
||||
|
||||
captured = capture_info_limit(&sim, "charged_limit");
|
||||
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "accounted=4.00"),
|
||||
"Requirement 2.1: a global limit matched and charged must show its "
|
||||
"accounted usage");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "capacity=10.00"),
|
||||
"Requirement 2.1: ... alongside its configured capacity");
|
||||
TEST_ASSERT_NULL_MESSAGE(
|
||||
strstr(captured, "no active usage instance yet"),
|
||||
"a genuinely matched+charged instance must not report 'no active "
|
||||
"usage instance yet'");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_named_shows_accounted_and_capacity_for_matched_"
|
||||
"and_charged_global_instance: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Task 3.1's own central Observable #2 (Requirement 2.2): a configured
|
||||
* limit that has NEVER been evaluated against any job (no xce_vres_t at
|
||||
* all in privdata->instances for it) must report the explicit no-instance
|
||||
* message, never a fabricated zero-usage line.
|
||||
*/
|
||||
static void
|
||||
test_info_limit_named_shows_no_active_usage_instance_for_never_matched_limit(
|
||||
void)
|
||||
{
|
||||
xce_sched_sim_driver_t sim;
|
||||
xce_sched_plugin_t plugin;
|
||||
xce_scheduler_t group_sched;
|
||||
char* captured;
|
||||
int rc;
|
||||
|
||||
memset(&sim, 0, sizeof(sim));
|
||||
rc = xce_sched_core_init(&(sim.core));
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
register_limit_plugin(&sim, &plugin, &group_sched);
|
||||
add_configured_limit(&plugin, "never_matched_limit");
|
||||
/* Deliberately no instantiate_and_register_global_vres() call -- this
|
||||
* limit has never been evaluated against any job, so
|
||||
* privdata->instances has no xce_vres_t at all for it. */
|
||||
|
||||
captured = capture_info_limit(&sim, "never_matched_limit");
|
||||
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "no active usage instance yet"),
|
||||
"Requirement 2.2: a configured-but-never-evaluated limit must "
|
||||
"report no active usage instance, not a fabricated zero");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_named_shows_no_active_usage_instance_for_never_"
|
||||
"matched_limit: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Task 3.1's own central Observable #3 -- THE existence-vs-zero-usage
|
||||
* distinction (Requirement 2.2's own most important correctness property,
|
||||
* per design.md's explicit callout): a vres that genuinely exists AND has
|
||||
* a real capacity entry, but has never been charged (no core.sharedInUse
|
||||
* entry), must display a genuine accounted=0 -- NOT the no-instance
|
||||
* message, since the instance itself (and its capacity) both genuinely
|
||||
* exist.
|
||||
*/
|
||||
static void
|
||||
test_info_limit_named_shows_accounted_zero_for_matched_but_never_charged_instance(
|
||||
void)
|
||||
{
|
||||
xce_sched_sim_driver_t sim;
|
||||
xce_sched_plugin_t plugin;
|
||||
xce_scheduler_t group_sched;
|
||||
xce_limit_t* matched = NULL;
|
||||
var limits_handle;
|
||||
xce_vres_t* vres;
|
||||
char* captured;
|
||||
int rc;
|
||||
|
||||
memset(&sim, 0, sizeof(sim));
|
||||
rc = xce_sched_core_init(&(sim.core));
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
register_per_host_resource(&sim, "mem");
|
||||
register_limit_plugin(&sim, &plugin, &group_sched);
|
||||
add_configured_limit(&plugin, "uncharged_limit");
|
||||
|
||||
limits_handle = limit_get_configured_limits(&(sim.core));
|
||||
rc = key_find(limits_handle, (void*)"uncharged_limit", (void**)&matched);
|
||||
TEST_ASSERT_TRUE(rc > 0);
|
||||
TEST_ASSERT_NOT_NULL(matched);
|
||||
|
||||
vres = instantiate_and_register_global_vres(&sim, &plugin, matched);
|
||||
put_shared_fvalue(&(sim.core.sharedInst), vres->vres->idx, 10.0);
|
||||
/* Deliberately no put_shared_fvalue() into core.sharedInUse -- a
|
||||
* genuinely matched vres with a real capacity entry, but nothing
|
||||
* charged against it yet. */
|
||||
|
||||
captured = capture_info_limit(&sim, "uncharged_limit");
|
||||
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "accounted=0.00"),
|
||||
"the existence-vs-zero-usage distinction: a matched vres with a "
|
||||
"real capacity entry but an absent in-use entry must display a "
|
||||
"genuine accounted=0, not the no-instance message");
|
||||
TEST_ASSERT_NULL_MESSAGE(
|
||||
strstr(captured, "no active usage instance yet"),
|
||||
"must NOT report 'no active usage instance yet' -- the vres and "
|
||||
"its capacity both genuinely exist");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_named_shows_accounted_zero_for_matched_but_"
|
||||
"never_charged_instance: PASS\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
|
@ -985,5 +1224,11 @@ int main(void)
|
|||
test_info_limit_named_does_not_show_host_scope_note_for_absolute_value_limit);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_does_not_duplicate_host_scope_note_when_per_host_explicitly_configured);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_shows_accounted_and_capacity_for_matched_and_charged_global_instance);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_shows_no_active_usage_instance_for_never_matched_limit);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_shows_accounted_zero_for_matched_but_never_charged_instance);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Link-satisfying stubs -- same rationale as every sibling in this file
|
||||
* family (see test_repl_execution_control.c's own copies for the full
|
||||
* per-stub doc comments). */
|
||||
|
|
|
|||
|
|
@ -96,6 +96,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -92,6 +92,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -105,6 +105,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -146,6 +146,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -123,6 +123,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
|
|
|
|||
|
|
@ -208,6 +208,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* xce_sched_driver_on_decision()'s (driver.c) publish-side linker
|
||||
* dependencies -- never actually invoked: this file never registers a
|
||||
* decision callback. Same rationale test_sim_resource_contention.c's own
|
||||
|
|
|
|||
|
|
@ -231,6 +231,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource.c's sched_try_alloc_on_host_()'s own link-time dependency --
|
||||
* never actually invoked (this file calls sched_check_host_satisfy()/
|
||||
* sched_charge_account()/sched_commit_job_alloc() directly). Same stub
|
||||
|
|
|
|||
|
|
@ -192,6 +192,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -139,6 +139,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -151,6 +151,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -154,6 +154,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* sched_worker_release_host_ctx() is now a REAL (non-stub) symbol pulled in
|
||||
* from resource.c (task 2.1 addition, below) -- no local stand-in needed or
|
||||
* permitted (a local definition here would collide at link time). Unused by
|
||||
|
|
|
|||
|
|
@ -110,6 +110,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
|
|
@ -175,6 +175,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* xce_sched_driver_run_normal_mode_round()'s (driver.c) linker dependency --
|
||||
* a no-op stand-in, same rationale test_sim_equivalence.c's own copy
|
||||
* documents (this file drives its own resource accounting directly via
|
||||
|
|
|
|||
|
|
@ -143,6 +143,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource.c's sched_try_alloc_on_host_()'s own link-time dependency --
|
||||
* never actually invoked (this file calls sched_check_host_satisfy()
|
||||
* directly, never sched_try_alloc_on_hosts()/sched_try_alloc_on_host_()
|
||||
|
|
|
|||
|
|
@ -175,6 +175,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* core_reset_workers()'s (core_session.c) linker dependency -- never
|
||||
* invoked (no worker is ever added here). */
|
||||
void sched_worker_release_host_ctx(xce_sched_worker_t* w) { (void)w; }
|
||||
|
|
|
|||
|
|
@ -129,6 +129,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* core_reset_workers()'s (core_session.c) linker dependency -- same stub
|
||||
* test_sim_verify.c already establishes; never invoked (no worker is ever
|
||||
* added here). */
|
||||
|
|
|
|||
|
|
@ -130,6 +130,19 @@ var limit_get_configured_limits(xce_sched_core_t* core)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* scheduler-sim-diagnostics spec, task 3.1: repl_info.c now also calls
|
||||
* limit_get_usage_instances() (plugins/limit.c, not part of this TU) to
|
||||
* read a limit's live usage instances -- identical link-satisfying stub,
|
||||
* same rationale as limit_get_configured_limits() immediately above; this
|
||||
* file's own fixtures never register the limit plugin, so NULL
|
||||
* (limit_get_usage_instances()'s own documented "plugin absent" return) is
|
||||
* also the behaviorally correct answer here, not just a link placeholder. */
|
||||
var limit_get_usage_instances(xce_sched_core_t* core)
|
||||
{
|
||||
(void)core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resource-accounting.md's reconciliation (resource.c, not linked here --
|
||||
* this file only #includes core_events.c). core_events.c's
|
||||
* XCE_CORE_EVENT_JOB_RUSAGE handler calls this whenever job->accounts !=
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue