From 907d8d80a303598db927e4b31fa5a84ed1ec2e8b Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Thu, 30 Apr 2026 04:49:27 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20implement=20build=5Fhost=5Feval=5Fctx?= =?UTF-8?q?=20=E2=80=94=20project=20resvals=20zarray=20to=20host=5Feval=5F?= =?UTF-8?q?ctx=5Ft=20(6-7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scheduler/src/resource.c | 48 +++++++++++++++++++++++++++++ src/scheduler/testsuite/meson.build | 2 +- src/scheduler/testsuite/test.c | 48 +++++++++++++++++++++++------ 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/src/scheduler/src/resource.c b/src/scheduler/src/resource.c index 320e4f79..35bf857b 100644 --- a/src/scheduler/src/resource.c +++ b/src/scheduler/src/resource.c @@ -5,6 +5,7 @@ #include "kvmgr.h" #include "plugin.h" #include "preason.h" +#include "resreq.h" #include "sched/types.h" #include "scheduler.h" #include "utils.h" @@ -124,6 +125,53 @@ static int unsatisfy_(int nres, int* idxs, float* total, float* inuse, return count; } +static host_eval_ctx_t* +build_host_eval_ctx(const xce_sched_worker_t* w, int num_res) +{ + host_eval_ctx_t* ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) return NULL; + + double* numvals = calloc(num_res, sizeof(double)); + const char** strvals = calloc(num_res, sizeof(char*)); + if (numvals == NULL || strvals == NULL) { + free(numvals); + free(strvals); + free(ctx); + return NULL; + } + + for (int i = 0; i < num_res; i++) { + xce_val_t** slot = (xce_val_t**)zarray_get((zarray_t*)&w->resvals, i); + if (slot == NULL || *slot == NULL) continue; + xce_val_t* v = *slot; + switch (v->which) { + case Value_u_fvalue: + numvals[i] = (double)v->u.fvalue; + break; + case Value_u_bvalue: + numvals[i] = v->u.bvalue ? 1.0 : 0.0; + break; + case Value_u_svalue: + strvals[i] = v->u.svalue; + break; + } + } + + ctx->num_res = num_res; + ctx->numvals = numvals; + ctx->strvals = strvals; + return ctx; +} + +static void +free_host_eval_ctx(host_eval_ctx_t* ctx) +{ + if (ctx == NULL) return; + free((void*)ctx->numvals); + free((void*)ctx->strvals); + free(ctx); +} + int sched_meet_host_selection(xce_scheduler_t* sched, xce_sched_worker_t* w, xce_select_t* s) { diff --git a/src/scheduler/testsuite/meson.build b/src/scheduler/testsuite/meson.build index b6ee31f2..56699c80 100644 --- a/src/scheduler/testsuite/meson.build +++ b/src/scheduler/testsuite/meson.build @@ -4,7 +4,7 @@ scheduler_test_src = [ scheduler_test_deps = [libxce_deps, librtti_dep, unity_dep, libxce_dep] -incdir = include_directories('../include', '../../include', '.') +incdir = include_directories('../include', '../../include', '.', '../src', '../../lib') scheduler_test = executable('sched_test', scheduler_test_src, diff --git a/src/scheduler/testsuite/test.c b/src/scheduler/testsuite/test.c index 1a192a9c..ef009b23 100644 --- a/src/scheduler/testsuite/test.c +++ b/src/scheduler/testsuite/test.c @@ -5,17 +5,14 @@ #include #include -#include "resreq.h" +/* Pull resource.c into this TU so static helpers are visible for white-box testing. + * This also brings in scheduler.h (with the real xce_scheduler_t) and all deps. */ +#include "../src/resource.c" -/* Minimal struct declaration to verify atomic fields exist. - * We avoid including scheduler.h to prevent dependency on capnp headers. */ -typedef struct { - /* Padding to represent fields before the atomic ones */ - char _dummy[968]; /* Approximate offset to atomic fields */ - _Atomic int session_active; - _Atomic int eval_in_progress; - _Atomic int staging_merge_complete; -} xce_scheduler_t; +/* Stubs for symbols used by resource.c functions not under test */ +xce_sched_worker_t* sched_get_worker(xce_scheduler_t* s, char* n) { (void)s; (void)n; return NULL; } +int plugin_prepare_allocation(void* s, xce_sched_ctx_t* c) { (void)s; (void)c; return 0; } +int sched_ctx_get_uncomit_host(xvec_t** v, xce_sched_ctx_t* c, int i) { (void)v; (void)c; (void)i; return 0; } void setUp() { return; } @@ -78,6 +75,36 @@ static int check_test(struct arguments* args, char* x) return 0; } +static void +test_build_host_eval_ctx_float(void) +{ + /* Worker with one float resource at res_idx=2 (value=4.0) */ + xce_sched_worker_t w; + memset(&w, 0, sizeof(w)); + zarray_init(&w.resvals, sizeof(xce_val_t*), NULL); + + xce_val_t v; + memset(&v, 0, sizeof(v)); + v.which = 5; /* Value_u_fvalue */ + v.u.fvalue = 4.0; + + /* zarray stores xce_val_t* items; pass pointer-to-pointer */ + xce_val_t* vp = &v; + zarray_put(&w.resvals, 2, &vp); + + host_eval_ctx_t* ctx = build_host_eval_ctx(&w, 3); + TEST_ASSERT_NOT_NULL(ctx); + /* Unity is built without UNITY_INCLUDE_DOUBLE; compare via float cast */ + TEST_ASSERT_EQUAL_FLOAT(4.0f, (float)ctx->numvals[2]); + TEST_ASSERT_NULL(ctx->strvals[2]); + TEST_ASSERT_EQUAL_INT(3, ctx->num_res); + + free((void*)ctx->numvals); + free((void*)ctx->strvals); + free(ctx); + zarray_fini(&w.resvals); +} + static void test_scheduler_t_has_atomic_gc_fields(void) { @@ -116,6 +143,7 @@ int main(int argc, char* argv[]) UNITY_BEGIN(); + TEST(test_build_host_eval_ctx_float); TEST(test_scheduler_t_has_atomic_gc_fields); TEST(test_sel_optimize_set_at_scheduler_startup);