feat(scheduler-core): implement simulation event loop and virtual clock advancement (task 11.2)
Add sim_loop.c implementing sched_sim_driver_run(): decode .replay messages in file order, jump the virtual clock to each ReplayEvent's exact timestamp as it's queued, and run a real push-events/go/drain/ end-session cycle on each ReplaySession boundary (AC 14, AC 18). Task 11.1 left no picker registered against the isolated core and no thread backing its cbufs, which deadlocks the decision drain the moment a real event loop exists. Add plugin_register_core() (registers a picker against a bare xce_sched_core_t*, no xce_scheduler_t* required) and extract builtin_fcfs_new_plugin() from register_builtin_fcfs() as a behavior-preserving factory, plus a picker-driving thread for the sim driver. Since real resource allocation is unreachable without a live xce_scheduler_t* (scheduler-allocation spec's job), the sim picker thread conservatively PENDs every candidate rather than dispatching. 28/28 scheduler suite, 32/32 whole-project tests green.
This commit is contained in:
parent
5d587ecf32
commit
7e1e861e4f
11 changed files with 1248 additions and 76 deletions
|
|
@ -123,6 +123,43 @@ extern int register_parjob_allocator(void*);
|
|||
* init() below only ever holds/passes a pointer to it. */
|
||||
typedef struct xce_sched_core_s xce_sched_core_t;
|
||||
|
||||
/*
|
||||
* builtin_fcfs_new_plugin - factory half of register_builtin_fcfs()'s
|
||||
* template-build step (plugins/builtin_fcfs.c), extracted so a caller with
|
||||
* no xce_scheduler_t* (e.g. the simulation driver, via
|
||||
* plugin_register_core() below) can obtain a freshly calloc'd, fully
|
||||
* populated `xce_sched_plugin_t` for builtin_fcfs -- same picker_iface/
|
||||
* init_fn/fini_fn template register_builtin_fcfs() itself uses, just not
|
||||
* yet registered anywhere. Returns NULL on allocation failure. Caller owns
|
||||
* the returned plugin (frees it only on a subsequent registration failure
|
||||
* -- once registered, the plugin registry owns it, same lifetime rule
|
||||
* every other plugin category in this codebase already follows).
|
||||
*/
|
||||
extern xce_sched_plugin_t* builtin_fcfs_new_plugin(void);
|
||||
|
||||
/*
|
||||
* plugin_register_core - Req 5 AC 17 (scheduler-core spec, task 11.2): the
|
||||
* "core.h-scoped plugin registration path" sim.h's own doc comment on
|
||||
* sched_sim_driver_start() anticipated but did not build (task 11.1's
|
||||
* documented "Known scope boundary"). plugin_register() above requires a
|
||||
* genuine `xce_scheduler_t*` (it dereferences `sched->core.plugins` and
|
||||
* stores `plugin->sched = sched` for plugin_unregister()'s later use) --
|
||||
* unavailable to a driver like the simulation driver that deliberately has
|
||||
* no such type. This is the SAME registration mechanism minus that one
|
||||
* dependency: run the plugin's init_fn (same "driver thread, at plugin
|
||||
* register" timing plugin.h's own hook-category doc comment documents),
|
||||
* then key_add() it into `core->plugins` directly -- identical steps
|
||||
* plugin_register() itself performs, in the same order, just addressed at
|
||||
* xce_sched_core_t* instead of xce_scheduler_t*. `plugin->sched` is left
|
||||
* NULL (no xce_scheduler_t* exists to store) -- safe, since
|
||||
* plugin_unregister() is a no-op on a NULL `plugin->sched` and nothing
|
||||
* calls it for a plugin registered this way (no sim-driver teardown path
|
||||
* exists yet). Returns the assigned plugin_id (>= 0) on success, or a
|
||||
* negative errno: -EINVAL for a NULL core/plugin, whatever init_fn
|
||||
* returned if it failed, or key_add()'s own negative return.
|
||||
*/
|
||||
extern int plugin_register_core(xce_sched_core_t*, xce_sched_plugin_t*);
|
||||
|
||||
/*
|
||||
* Hook categories and the thread each category runs in (Req 1 AC 3):
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue