feat(scheduler-sim-diagnostics): promote byte-unit formatting to shared lib (task 7)
Adds Requirement 6 (Human-Readable Units for Byte-Valued Limit Amounts) to the spec: requirements, design, research, and tasks 7-10. Task 7 (Foundation): promotes the REPL's byte-unit scaling algorithm and byte-valued-resource classifier into src/lib/utils.c/utils.h (xce_format_bytes_human, xce_is_bytes_valued_resource), alongside a new display-mode-aware composer (xce_format_units_value, xce_units_mode_t) -- following the fmt_jobid()/fmt_jobid_ex() precedent. repl_fmt.c's scheduler-only functions become one-line delegating wrappers. repl_info.c's repl_format_numeric_resource_value() (shared by info worker/info resource, not just the upcoming info limit) is retyped to delegate to the new shared composer via a small translate_units_mode() bridge, so every consumer benefits from one implementation going forward. No existing symbol's signature changed; only new symbols were added. Confirmed behavior-preserving: full scheduler suite 85/85 unchanged, including info worker/info resource's own regression tests. One narrow, untested, out-of-requirement-scope corner case found and documented (swp's RAW/BOTH mode rendering under the new single-value composer interface) -- logged in tasks.md's Implementation Notes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
parent
8c363de75f
commit
eb23c158ae
10 changed files with 535 additions and 85 deletions
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <capnp_c.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tlog.h>
|
||||
|
|
@ -211,6 +212,51 @@ extern int fmt_jobid(char*, size_t, uint64_t);
|
|||
extern int parse_jobid(uint64_t*, char*);
|
||||
extern uint64_t array_jobid(uint64_t);
|
||||
extern uint64_t array_idx(uint64_t);
|
||||
|
||||
/*
|
||||
* xce_units_mode_t / xce_format_bytes_human() / xce_is_bytes_valued_resource()
|
||||
* / xce_format_units_value() -- scheduler-sim-diagnostics spec, task 7 (Req
|
||||
* 6.1, 6.3, 6.5). Shared-library promotion of the scheduler REPL's
|
||||
* byte-unit scaling algorithm (formerly repl_fmt.c's
|
||||
* repl_format_bytes_human()), its byte-valued-resource classification
|
||||
* (formerly repl_fmt.c's repl_is_bytes_valued_resource()), and a
|
||||
* display-mode-aware value composer (formerly repl_info.c's
|
||||
* repl_format_numeric_resource_value()'s byte-valued branch), so any
|
||||
* `libxce` consumer -- not only the scheduler's REPL -- can reach this
|
||||
* display-only formatting. `fmt_jobid()`/`fmt_jobid_ex()` immediately above
|
||||
* are the precedent this follows: a small, generic, cross-component
|
||||
* display-formatting helper with no domain coupling.
|
||||
*
|
||||
* All three functions are pure and display-only -- none of them ever
|
||||
* mutate a caller-supplied value or feed back into a stored/wire value.
|
||||
* `xce_is_bytes_valued_resource()` is a fixed 5-name list (`mem`, `tmp`,
|
||||
* `maxmem`, `maxtmp`, `maxswap`); a `NULL` name returns `false`.
|
||||
* `xce_format_bytes_human()` adaptively scales `bytes` to the smallest
|
||||
* B/KB/MB/GB/TB/PB unit it fits, writing e.g. "20.56 GB" into `buf`.
|
||||
* `xce_format_units_value()` assumes the caller has already decided
|
||||
* `bytes_value` is byte-valued (via `xce_is_bytes_valued_resource()` or the
|
||||
* caller's own equivalent check) -- it does not re-derive that decision:
|
||||
* RAW renders the bare "%f" of `bytes_value` alone, HUMAN renders
|
||||
* `xce_format_bytes_human()`'s scaled form alone, and BOTH (the default for
|
||||
* any other mode value) renders "<raw> (<human>)".
|
||||
*
|
||||
* `xce_repl_units_mode_t` (scheduler-private, `repl_internal.h`) is a
|
||||
* deliberately separate, independently-defined enum with the same three
|
||||
* semantic values -- a `src/lib` type must not be defined in terms of a
|
||||
* scheduler-internal concept. The scheduler bridges the two at its one call
|
||||
* site (`repl_info.c`'s `translate_units_mode()`).
|
||||
*/
|
||||
typedef enum {
|
||||
XCE_UNITS_RAW = 1,
|
||||
XCE_UNITS_HUMAN,
|
||||
XCE_UNITS_BOTH
|
||||
} xce_units_mode_t;
|
||||
|
||||
extern void xce_format_bytes_human(double bytes, char* buf, size_t bufsz);
|
||||
extern bool xce_is_bytes_valued_resource(const char* name);
|
||||
extern void xce_format_units_value(xce_units_mode_t mode, double bytes_value,
|
||||
char* buf, size_t bufsz);
|
||||
|
||||
extern void unblock_sig(int);
|
||||
extern void block_sig(int);
|
||||
|
||||
|
|
|
|||
|
|
@ -278,6 +278,154 @@ void test_compose_version_ex_matches_original_when_fingerprint_absent(void)
|
|||
TEST_ASSERT_EQUAL_STRING(buf_orig, buf_ex);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* scheduler-sim-diagnostics spec, task 7 (Requirement 6.1, 6.3, 6.5):
|
||||
* xce_format_bytes_human() / xce_is_bytes_valued_resource() /
|
||||
* xce_format_units_value() -- shared-library promotion of the scheduler
|
||||
* REPL's byte-unit scaling algorithm, its byte-valued-resource
|
||||
* classification, and a display-mode-aware value composer (formerly
|
||||
* repl_fmt.c's repl_format_bytes_human()/repl_is_bytes_valued_resource()
|
||||
* and repl_info.c's repl_format_numeric_resource_value()'s byte-valued
|
||||
* branch). Mirrors test_repl_resource_formatting.c's own assertion style --
|
||||
* that file's tests are the scheduler-side regression proof that
|
||||
* delegating repl_fmt.c's two wrapper functions here left their observable
|
||||
* behavior unchanged; these are the direct unit tests for the promoted
|
||||
* primitives themselves.
|
||||
* ------------------------------------------------------------------------ */
|
||||
|
||||
static void test_xce_is_bytes_valued_resource_true_for_canonical_five(void)
|
||||
{
|
||||
TEST_ASSERT_TRUE_MESSAGE(xce_is_bytes_valued_resource("mem"),
|
||||
"mem's wire unit is bytes");
|
||||
TEST_ASSERT_TRUE_MESSAGE(xce_is_bytes_valued_resource("tmp"),
|
||||
"tmp's wire unit is bytes");
|
||||
TEST_ASSERT_TRUE_MESSAGE(xce_is_bytes_valued_resource("maxmem"),
|
||||
"maxmem's wire unit is bytes");
|
||||
TEST_ASSERT_TRUE_MESSAGE(xce_is_bytes_valued_resource("maxtmp"),
|
||||
"maxtmp's wire unit is bytes");
|
||||
TEST_ASSERT_TRUE_MESSAGE(xce_is_bytes_valued_resource("maxswap"),
|
||||
"maxswap's wire unit is bytes");
|
||||
}
|
||||
|
||||
static void
|
||||
test_xce_is_bytes_valued_resource_false_for_null_empty_and_unknown(void)
|
||||
{
|
||||
TEST_ASSERT_FALSE_MESSAGE(
|
||||
xce_is_bytes_valued_resource(NULL),
|
||||
"a NULL name must not be misclassified as bytes-valued");
|
||||
TEST_ASSERT_FALSE_MESSAGE(
|
||||
xce_is_bytes_valued_resource(""),
|
||||
"an empty name must not be misclassified as bytes-valued");
|
||||
TEST_ASSERT_FALSE_MESSAGE(
|
||||
xce_is_bytes_valued_resource("slots"),
|
||||
"an unknown/custom resource name must not be misclassified as "
|
||||
"bytes-valued -- this is a small, explicit, hardcoded list, not a "
|
||||
"heuristic");
|
||||
}
|
||||
|
||||
static void
|
||||
test_xce_format_bytes_human_scales_across_full_unit_range_at_boundaries(void)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(0.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING("0.00 B", buf);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(1023.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(
|
||||
"1023.00 B", buf, "just below the KB boundary must stay in B");
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(1024.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(
|
||||
"1.00 KB", buf,
|
||||
"exactly 1024 bytes must render as '1.00 KB', not '1024.00 B'");
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(1024.0 * 1024.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING("1.00 MB", buf);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(1024.0 * 1024.0 * 1024.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING("1.00 GB", buf);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(1024.0 * 1024.0 * 1024.0 * 1024.0, buf,
|
||||
sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING("1.00 TB", buf);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0, buf,
|
||||
sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING("1.00 PB", buf);
|
||||
|
||||
/* PB is the largest unit -- a value past it stays capped there instead
|
||||
* of inventing a further unit. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(
|
||||
1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0, buf,
|
||||
sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(
|
||||
"1024.00 PB", buf,
|
||||
"a value past the PB range must stay capped at PB, not invent a "
|
||||
"further unit");
|
||||
}
|
||||
|
||||
static void
|
||||
test_xce_format_bytes_human_fractional_values_render_two_decimals(void)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
/* 5,000,000,000 bytes / 1024^3 = 4.656612873077393... GB, rounds via
|
||||
* "%.2f" to "4.66 GB" -- an arbitrary, non-power-of-2 value, the exact
|
||||
* transcript figure that motivated Requirement 6. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_bytes_human(5000000000.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING("4.66 GB", buf);
|
||||
}
|
||||
|
||||
static void test_xce_format_units_value_raw_mode_renders_bare_value(void)
|
||||
{
|
||||
char buf[64];
|
||||
char expected[64];
|
||||
|
||||
snprintf(expected, sizeof(expected), "%f", 5000000000.0);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_units_value(XCE_UNITS_RAW, 5000000000.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING(expected, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_xce_format_units_value_human_mode_renders_scaled_string_alone(void)
|
||||
{
|
||||
char buf[64];
|
||||
char expected[64];
|
||||
|
||||
xce_format_bytes_human(5000000000.0, expected, sizeof(expected));
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_units_value(XCE_UNITS_HUMAN, 5000000000.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING(expected, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_xce_format_units_value_both_mode_renders_raw_and_human(void)
|
||||
{
|
||||
char buf[128];
|
||||
char expected[128];
|
||||
char human[64];
|
||||
|
||||
xce_format_bytes_human(5000000000.0, human, sizeof(human));
|
||||
snprintf(expected, sizeof(expected), "%f (%s)", 5000000000.0, human);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
xce_format_units_value(XCE_UNITS_BOTH, 5000000000.0, buf, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_STRING(expected, buf);
|
||||
}
|
||||
|
||||
void test_utils(void)
|
||||
{
|
||||
printf("\n>> utils test\n\n");
|
||||
|
|
@ -298,4 +446,13 @@ void test_utils(void)
|
|||
RUN_TEST(test_compose_version_ex_empty_fingerprint_dirty_commit_unchanged);
|
||||
RUN_TEST(test_compose_version_ex_null_fingerprint_matches_empty);
|
||||
RUN_TEST(test_compose_version_ex_matches_original_when_fingerprint_absent);
|
||||
RUN_TEST(test_xce_is_bytes_valued_resource_true_for_canonical_five);
|
||||
RUN_TEST(
|
||||
test_xce_is_bytes_valued_resource_false_for_null_empty_and_unknown);
|
||||
RUN_TEST(
|
||||
test_xce_format_bytes_human_scales_across_full_unit_range_at_boundaries);
|
||||
RUN_TEST(test_xce_format_bytes_human_fractional_values_render_two_decimals);
|
||||
RUN_TEST(test_xce_format_units_value_raw_mode_renders_bare_value);
|
||||
RUN_TEST(test_xce_format_units_value_human_mode_renders_scaled_string_alone);
|
||||
RUN_TEST(test_xce_format_units_value_both_mode_renders_raw_and_human);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -703,6 +703,77 @@ uint64_t array_idx(uint64_t jobid)
|
|||
return EXTRACT_ARRAY_IDX(jobid);
|
||||
}
|
||||
|
||||
/*
|
||||
* xce_format_bytes_human / xce_is_bytes_valued_resource / xce_format_units_value
|
||||
* (scheduler-sim-diagnostics spec, task 7, Requirement 6.1/6.3/6.5) --
|
||||
* shared-library promotion of the scheduler REPL's byte-unit scaling
|
||||
* algorithm and byte-valued-resource classification (formerly repl_fmt.c's
|
||||
* repl_format_bytes_human()/repl_is_bytes_valued_resource(), now thin
|
||||
* wrappers around these), plus a display-mode-aware value composer
|
||||
* promoted from repl_info.c's repl_format_numeric_resource_value()'s
|
||||
* byte-valued branch (now delegated to via that file's own
|
||||
* translate_units_mode() bridge). See utils.h's doc comment on
|
||||
* xce_units_mode_t for the full contract; this is a pure, display-only,
|
||||
* leaf utility -- none of these functions ever mutate a caller-supplied
|
||||
* value.
|
||||
*/
|
||||
void xce_format_bytes_human(double bytes, char* buf, size_t bufsz)
|
||||
{
|
||||
static const char* const UNITS[] = { "B", "KB", "MB", "GB", "TB", "PB" };
|
||||
const int nunits = (int)(sizeof(UNITS) / sizeof(UNITS[0]));
|
||||
double val = bytes;
|
||||
int i = 0;
|
||||
|
||||
while ((val >= 1024.0) && (i < nunits - 1)) {
|
||||
val /= 1024.0;
|
||||
i++;
|
||||
}
|
||||
|
||||
snprintf(buf, bufsz, "%.2f %s", val, UNITS[i]);
|
||||
}
|
||||
|
||||
bool xce_is_bytes_valued_resource(const char* name)
|
||||
{
|
||||
static const char* const BYTES_VALUED_RESOURCES[]
|
||||
= { "mem", "tmp", "maxmem", "maxtmp", "maxswap" };
|
||||
const int nres = (int)(sizeof(BYTES_VALUED_RESOURCES)
|
||||
/ sizeof(BYTES_VALUED_RESOURCES[0]));
|
||||
int i;
|
||||
|
||||
if (name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < nres; i++) {
|
||||
if (strcmp(name, BYTES_VALUED_RESOURCES[i]) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void xce_format_units_value(xce_units_mode_t mode, double bytes_value,
|
||||
char* buf, size_t bufsz)
|
||||
{
|
||||
char human[64];
|
||||
|
||||
xce_format_bytes_human(bytes_value, human, sizeof(human));
|
||||
|
||||
switch (mode) {
|
||||
case XCE_UNITS_RAW:
|
||||
snprintf(buf, bufsz, "%f", bytes_value);
|
||||
break;
|
||||
case XCE_UNITS_HUMAN:
|
||||
snprintf(buf, bufsz, "%s", human);
|
||||
break;
|
||||
case XCE_UNITS_BOTH:
|
||||
default:
|
||||
snprintf(buf, bufsz, "%f (%s)", bytes_value, human);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void unblock_sig(int signo)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
|
|
|||
|
|
@ -72,69 +72,26 @@ void repl_format_ts_human(uint64_t ns, char* buf, size_t bufsz)
|
|||
}
|
||||
|
||||
/*
|
||||
* repl_is_bytes_valued_resource - scheduler-sim-repl-verbosity spec, task
|
||||
* 7.2, design.md's "Resource Value Formatter" component (Req 6.1). Mirrors
|
||||
* src/controller/testsuite/test.c's own is_bytes_valued_resource() exactly
|
||||
* -- same 5-name list, same "small, explicit, client-side list rather than
|
||||
* a wire field" rationale that file's own doc comment gives: mem/tmp's
|
||||
* canonical wire unit is bytes (node_information.c's node_info_get_mem()/
|
||||
* node_info_get_tmp() doc comments); maxmem/maxtmp/maxswap's canonical wire
|
||||
* unit is bytes too (xcecd.c's init_host_attrs() bug-1554 comment). `swp`
|
||||
* is deliberately NOT in this list -- its own wire unit is megabytes, not
|
||||
* bytes (node_info_get_swap() doc comment); see repl_format_bytes_human()'s
|
||||
* own doc comment below and repl_params.c's `set units` caller-side
|
||||
* MB->bytes conversion.
|
||||
* repl_is_bytes_valued_resource / repl_format_bytes_human -
|
||||
* scheduler-sim-repl-verbosity spec, task 7.2, design.md's "Resource Value
|
||||
* Formatter" component (Req 6.1/6.2). scheduler-sim-diagnostics spec, task
|
||||
* 7 (Req 6.1, 6.3, 6.5) promoted both functions' bodies verbatim into the
|
||||
* shared library (`xce_is_bytes_valued_resource()`/`xce_format_bytes_human()`,
|
||||
* `utils.h`/`utils.c`), so any `libxce` consumer -- not only the
|
||||
* scheduler's REPL -- can reach this display-only formatting. These two
|
||||
* remain in place as thin, behavior-preserving wrappers: every existing
|
||||
* call site in this file family keeps calling them by these exact names/
|
||||
* signatures, unchanged. See utils.h's doc comment on xce_units_mode_t for
|
||||
* the full algorithm/classification-list contract now owned there.
|
||||
*/
|
||||
bool repl_is_bytes_valued_resource(const char* name)
|
||||
{
|
||||
static const char* const BYTES_VALUED_RESOURCES[]
|
||||
= { "mem", "tmp", "maxmem", "maxtmp", "maxswap" };
|
||||
const int nres = (int)(sizeof(BYTES_VALUED_RESOURCES)
|
||||
/ sizeof(BYTES_VALUED_RESOURCES[0]));
|
||||
int i;
|
||||
|
||||
if (name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < nres; i++) {
|
||||
if (strcmp(name, BYTES_VALUED_RESOURCES[i]) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return xce_is_bytes_valued_resource(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* repl_format_bytes_human - scheduler-sim-repl-verbosity spec, task 7.2,
|
||||
* design.md's "Resource Value Formatter" component (Req 6.2). Adaptively
|
||||
* scales `bytes` to the smallest B/KB/MB/GB/TB/PB unit it fits (dividing by
|
||||
* 1024 while >= 1024.0, capping at PB once no larger unit remains), writing
|
||||
* e.g. "20.56 GB" into `buf` (bufsz-bounded) -- mirrors
|
||||
* src/controller/testsuite/test.c's own format_bytes_human() algorithm
|
||||
* exactly, same "%.2f %s" render format. Display-only -- never touches the
|
||||
* underlying stored/wire value, same discipline that file's own doc comment
|
||||
* states ("the stored/wire value stays raw bytes always, this never feeds
|
||||
* back into anything"). `swp`'s wire value is megabytes, not bytes
|
||||
* (node_info_get_swap() doc comment, repl_is_bytes_valued_resource() above)
|
||||
* -- callers convert MB->bytes (x 1024.0 x 1024.0) BEFORE calling this, so
|
||||
* it renders on the same adaptive scale a byte-native resource of
|
||||
* equivalent magnitude would (repl_params.c).
|
||||
*/
|
||||
void repl_format_bytes_human(double bytes, char* buf, size_t bufsz)
|
||||
{
|
||||
static const char* const UNITS[] = { "B", "KB", "MB", "GB", "TB", "PB" };
|
||||
const int nunits = (int)(sizeof(UNITS) / sizeof(UNITS[0]));
|
||||
double val = bytes;
|
||||
int i = 0;
|
||||
|
||||
while ((val >= 1024.0) && (i < nunits - 1)) {
|
||||
val /= 1024.0;
|
||||
i++;
|
||||
}
|
||||
|
||||
snprintf(buf, bufsz, "%.2f %s", val, UNITS[i]);
|
||||
xce_format_bytes_human(bytes, buf, bufsz);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -369,6 +369,32 @@ repl_classify_resource_def_section(const xce_resource_t* r)
|
|||
: XCE_REPL_RES_SECTION_LOAD;
|
||||
}
|
||||
|
||||
/*
|
||||
* translate_units_mode - scheduler-sim-diagnostics spec, task 7 (Req 6.1,
|
||||
* 6.3, 6.5): bridges the REPL's own units-mode selection
|
||||
* (xce_repl_units_mode_t, repl_internal.h) to the shared library's
|
||||
* independently-defined xce_units_mode_t (utils.h) at the one seam that
|
||||
* needs to cross between them. Deliberately NOT a shared enum -- a
|
||||
* src/lib type must not be defined in terms of a scheduler-internal
|
||||
* concept, nor should the scheduler's own already-tested
|
||||
* xce_repl_units_mode_t plumbing need to change for this (design.md's
|
||||
* "Where the byte-formatter should live" decision). If
|
||||
* xce_repl_units_mode_t's three values ever change, this mapping must be
|
||||
* re-checked by hand -- nothing enforces it mechanically.
|
||||
*/
|
||||
static xce_units_mode_t translate_units_mode(xce_repl_units_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case XCE_REPL_UNITS_RAW:
|
||||
return XCE_UNITS_RAW;
|
||||
case XCE_REPL_UNITS_HUMAN:
|
||||
return XCE_UNITS_HUMAN;
|
||||
case XCE_REPL_UNITS_BOTH:
|
||||
default:
|
||||
return XCE_UNITS_BOTH;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* repl_format_numeric_resource_value - Requirement 6.1/6.2/6.5: formats the
|
||||
* text that follows "value=" for a non-consumable ("Load Metrics") numeric
|
||||
|
|
@ -383,6 +409,13 @@ repl_classify_resource_def_section(const xce_resource_t* r)
|
|||
* by repl_info_worker_one()'s and repl_info_resource_one()'s identical Load
|
||||
* Metrics rendering so the two commands can never disagree about this
|
||||
* format.
|
||||
*
|
||||
* scheduler-sim-diagnostics spec, task 7 (Req 6.1, 6.3, 6.5): the
|
||||
* byte-valued branch now delegates its raw/human/both composition to the
|
||||
* shared library's xce_format_units_value() via translate_units_mode()
|
||||
* above, instead of switching on `mode` itself -- so this function, its
|
||||
* `info worker`/`info resource` callers, AND the `info limit` command
|
||||
* this spec is adding all funnel through one single implementation.
|
||||
*/
|
||||
static void repl_format_numeric_resource_value(xce_repl_units_mode_t mode,
|
||||
const char* rname,
|
||||
|
|
@ -393,22 +426,9 @@ static void repl_format_numeric_resource_value(xce_repl_units_mode_t mode,
|
|||
|
||||
if (repl_is_bytes_valued_resource(rname) || is_swp) {
|
||||
double bytes_value = is_swp ? (value * 1024.0 * 1024.0) : value;
|
||||
char human[64];
|
||||
|
||||
repl_format_bytes_human(bytes_value, human, sizeof(human));
|
||||
|
||||
switch (mode) {
|
||||
case XCE_REPL_UNITS_RAW:
|
||||
snprintf(buf, bufsz, "%f", value);
|
||||
break;
|
||||
case XCE_REPL_UNITS_HUMAN:
|
||||
snprintf(buf, bufsz, "%s", human);
|
||||
break;
|
||||
case XCE_REPL_UNITS_BOTH:
|
||||
default:
|
||||
snprintf(buf, bufsz, "%f (%s)", value, human);
|
||||
break;
|
||||
}
|
||||
xce_format_units_value(translate_units_mode(mode), bytes_value, buf,
|
||||
bufsz);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue