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:
parent
604a564904
commit
7c229284e2
26 changed files with 1233 additions and 661 deletions
117
src/scheduler/include/core.h
Normal file
117
src/scheduler/include/core.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#if !defined(_CORE_H_)
|
||||
|
||||
#define _CORE_H_ 1
|
||||
|
||||
/*
|
||||
* core.h - xce_sched_core_t: the scheduler's pure scheduling-state
|
||||
* structure (scheduler-core spec, task 4.1, Req 5.1/5.2).
|
||||
*
|
||||
* Boundary (design.md "SchedulerCore" / "Existing Architecture Analysis"):
|
||||
* `xce_scheduler_t` (scheduler.h) splits along the controller-I/O seam into
|
||||
* this structure (no `apictx`/`cluster_cfg` -- zero controller I/O, network,
|
||||
* or wall-clock dependency) and the driver-level fields that remain on
|
||||
* `xce_scheduler_t` itself. Every field below is the SAME field, same name,
|
||||
* same type, that lived directly on `xce_scheduler_t` before this task --
|
||||
* this is a relocation, not a redesign; `xce_scheduler_t` now embeds this
|
||||
* struct as its `core` member instead of declaring these fields itself.
|
||||
*
|
||||
* Allowed dependencies only (design.md "Allowed Dependencies", Req 5 AC 3):
|
||||
* ordq, dataq, cbuf, xlist, zarray, kvmgr, rtti. This header and core.c
|
||||
* must NEVER include client.h/netio.h/xceapi.h/delay.h/idgen.h/
|
||||
* xce/cluster.h, and must never call a wall-clock function (time(),
|
||||
* clock_gettime(), gettimeofday()) -- enforced by
|
||||
* testsuite/test_core_isolation.c (source-text scan + an nm(1) undefined-
|
||||
* symbol audit of core.c's compiled object, the build-time proof this
|
||||
* task's Observable requires).
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <rtti.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dataq.h"
|
||||
#include "mylock.h"
|
||||
#include "sched/types.h"
|
||||
#include "xce/types.h"
|
||||
#include "zarray.h"
|
||||
|
||||
/* xce_sched_core_t is also forward-declared in plugin.h (picker lifecycle
|
||||
* hook parameter type); this typedef and the full struct definition below
|
||||
* are the canonical declaration -- same idiom as cluster_t across
|
||||
* myconf.h/persist.h/ha.h/cluster_def.h (an identical repeated typedef is
|
||||
* valid C11/gnu17, so include order between core.h and plugin.h doesn't
|
||||
* matter). */
|
||||
typedef struct xce_sched_core_s xce_sched_core_t;
|
||||
|
||||
struct xce_sched_core_s {
|
||||
mylock_t lock;
|
||||
int stop;
|
||||
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. */
|
||||
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_sched_core_init/xce_sched_core_fini - allocate/initialize, and tear
|
||||
* down, exactly the state above. Deliberately narrower than the design's
|
||||
* eventual Service Interface (`xce_sched_core_init(core, decision_cb,
|
||||
* driver_ctx, prng_seed)`, design.md "SchedulerCore" component) -- the
|
||||
* decision callback, driver context, and PRNG seed belong to the event/
|
||||
* decision protocol tasks 4.3-4.5 build; this task only extracts state
|
||||
* init/fini, mirroring the non-I/O portion of today's sched_init()/
|
||||
* sched_fini() (scheduler.c).
|
||||
*/
|
||||
extern int xce_sched_core_init(xce_sched_core_t*);
|
||||
extern void xce_sched_core_fini(xce_sched_core_t*);
|
||||
|
||||
/* Relocated state-only accessors/mutators (task 4.1): moved out of
|
||||
* scheduler.c/schedobj.c, now operating on xce_sched_core_t* -- zero
|
||||
* controller I/O, exactly like the rest of this header. */
|
||||
extern xce_sched_job_t* sched_get_job(xce_sched_core_t*, uint64_t);
|
||||
extern int sched_add_job(xce_sched_core_t*, xce_sched_job_t*);
|
||||
extern xce_sched_queue_t* sched_get_queue(xce_sched_core_t*, char*);
|
||||
extern int sched_add_queue(xce_sched_core_t*, xce_sched_queue_t*);
|
||||
extern xce_sched_worker_t* sched_get_worker(xce_sched_core_t*, char*);
|
||||
extern int sched_add_worker(xce_sched_core_t*, xce_sched_worker_t*);
|
||||
extern xce_sched_user_t* sched_get_user(xce_sched_core_t*, char*);
|
||||
extern int sched_add_user(xce_sched_core_t*, xce_sched_user_t*);
|
||||
extern xce_sched_project_t* sched_get_project(xce_sched_core_t*, char*);
|
||||
extern int sched_add_project(xce_sched_core_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*);
|
||||
|
||||
#endif
|
||||
|
|
@ -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*);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue