feat(scheduler-core): extract xce_sched_core_t from monolithic scheduler struct (task 4.1)

Splits xce_scheduler_t along the controller-I/O seam: xce_sched_core_t
(new core.h/core.c) now holds all scheduling state (jobs/queues/workers/
users/projects/resource managers/plugins/three-thread-cbuf pipeline),
while xce_scheduler_t shrinks to {core; apictx; cluster_cfg}. Proven via
an nm-based link-time isolation test (zero netio/xcecli/idgen/delaymgr
symbols reachable from core.c) plus a reproducible wall-clock-call guard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dw5WnN3DXStaEaPYfACU1
This commit is contained in:
Rongsong Shen 2026-08-03 10:55:58 +00:00
parent 604a564904
commit 7c229284e2
Signed by: rshen
SSH key fingerprint: SHA256:8Vf2pZ3h6rJa7EhGK+WaAQ9Mta/apZvteW6g9U/WKKk
26 changed files with 1233 additions and 661 deletions

View file

@ -9,6 +9,7 @@
#include <time.h>
#include "client.h"
#include "core.h"
#include "dataq.h"
#include "decision.h"
#include "group.h"
@ -84,49 +85,23 @@ typedef struct {
- offsetof(xce_sched_update_request_t, \
link)))
/*
* xce_scheduler_t - scheduler-core spec, task 4.1 (Req 5.1/5.2): splits
* along the controller-I/O seam into `core` (xce_sched_core_t, core.h --
* all scheduling state, zero controller I/O) and the two fields below
* (controller client context + HA candidate list). Every field that used
* to live directly on this struct is unchanged in name/type/semantics --
* it now lives on `core` (see core.h's field-by-field comment). Existing
* callers holding an `xce_scheduler_t*` reach relocated state through
* `&sched->core` at the specific call sites that need the narrower
* `xce_sched_core_t*` type (the accessors declared in core.h); anything
* still operating on the full driver-level struct is unaffected.
*/
typedef struct {
mylock_t lock;
int stop;
xcecli_ctx_t apictx;
uint64_t nextid;
xce_conf4sched_t* config;
uint64_t configver;
/* Req 2 AC 1 (scheduler-core spec, task 1.3): global picker plugin
* name. NULL until sched_set_default_job_pick_plugin() (schedobj.c)
* applies the "builtin_fcfs" default, or a future config-driven
* assignment sets it explicitly. This field only carries the *name* --
* resolving it against the plugin registry (plugin_register/key_find)
* and failing startup loudly on an unregistered name (Req 2 AC 5) is
* task 2.4's job. */
char* job_pick_plugin;
var plugins;
void* seqjob_allocator;
void* parjob_allocator;
void* affinity_allocator;
void* gpu_allocator;
dataq_t* pend_updates[2];
var resmgr;
var ugmgr;
var qgmgr;
var pgmgr;
var hgmgr;
zarray_t sharedInst;
zarray_t sharedInUse;
var jobs;
var queues;
var workers;
var users;
var projects;
pthread_t jobpicker;
pthread_t allocator;
cbuf_t wbuf; /* action to trigger scheduling */
cbuf_t jbuf; /* job picked for allocation */
cbuf_t decisions; /* scheduler decisions */
_Atomic int session_active; /* 1 during scheduling session, 0 between */
_Atomic int eval_in_progress; /* 1 while eval_select loop runs */
_Atomic int staging_merge_complete; /* 1 after staging merge completes */
select_eval_ctx_t* sel_eval_ctx; /* session-level memoisation context; NULL between sessions */
xce_cluster_config_t cluster_cfg; /* HA candidate list — empty means single-host mode */
xce_sched_core_t core;
xcecli_ctx_t apictx;
xce_cluster_config_t
cluster_cfg; /* HA candidate list — empty means single-host mode */
} xce_scheduler_t;
extern int sched_init(xce_scheduler_t*, xce_client_config_t*,
@ -156,21 +131,14 @@ extern int sched_update(xce_scheduler_t*);
extern void sched_go(xce_scheduler_t*);
extern void sched_begin_session(xce_scheduler_t*);
extern void sched_end_session(xce_scheduler_t*);
extern xce_sched_job_t* sched_get_job(xce_scheduler_t*, uint64_t);
extern xce_sched_queue_t* sched_get_queue(xce_scheduler_t*, char*);
extern xce_sched_worker_t* sched_get_worker(xce_scheduler_t*, char*);
extern xce_sched_user_t* sched_get_user(xce_scheduler_t*, char*);
extern xce_sched_project_t* sched_get_project(xce_scheduler_t*, char*);
extern int sched_add_job(xce_scheduler_t*, xce_sched_job_t*);
extern int sched_add_queue(xce_scheduler_t*, xce_sched_queue_t*);
/* sched_get_job/sched_add_job/sched_get_queue/sched_add_queue/
* sched_get_worker/sched_add_worker/sched_get_user/sched_add_user/
* sched_get_project/sched_add_project/sched_job_is_ready/
* sched_queue_is_ready relocated to core.h (scheduler-core spec, task 4.1)
* -- they now operate on xce_sched_core_t*, not xce_scheduler_t*. */
extern int sched_update_existing_queue(xce_scheduler_t*, xce_queue_t*);
extern int sched_update_existing_job(xce_scheduler_t*, xce_job_t*);
extern int sched_apply_job_rusage(xce_scheduler_t*, xce_job_rusages_t*);
extern int sched_add_user(xce_scheduler_t*, xce_sched_user_t*);
extern int sched_add_worker(xce_scheduler_t*, xce_sched_worker_t*);
extern int sched_add_project(xce_scheduler_t*, xce_sched_project_t*);
extern int sched_job_is_ready(xce_sched_job_t*);
extern int sched_queue_is_ready(xce_sched_queue_t*);
extern int sched_apply_job_rusage(xce_scheduler_t*, xce_job_rusages_t*);
extern int sched_commit_decision(xce_scheduler_t*, xce_decision_t*);
extern int sched_publish_pend_reason(xce_scheduler_t*, xce_preason_set_t*);
extern int sched_publish_dispatch(xce_scheduler_t*, xce_job_dispatch_t*);