docs(scheduler-sim-discrete-clock): scheduler-core spec drops speed modes, --sim-speed deprecated, REPL speed removed (task 4.2)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
66435d100d
commit
d5527c665b
4 changed files with 38 additions and 30 deletions
|
|
@ -296,7 +296,7 @@ Key decision not obvious from the diagram: the controller is a pure pass-through
|
|||
| 5.11 | Periodic snapshot during recording | NormalDriver | `record_snapshot_interval` | — |
|
||||
| 5.12 | Session response time metrics | SchedulerCore | `SessionSummary` | — |
|
||||
| 5.13 | Simulation mode startup (load header+snapshot) | SimDriver | `.replay` load sequence | — |
|
||||
| 5.14 | Discrete event-driven virtual clock | SimDriver | `--sim-speed` | — |
|
||||
| 5.14 | Discrete event-driven virtual clock (clock set only to recorded timestamps; no speed modes; `--sim-speed` a deprecated no-op — Amended 2026-09-28 by spec scheduler-sim-discrete-clock) | SimDriver | `sim_advance_virtual_clock()` | — |
|
||||
| 5.15 | `--sim-verify` deterministic replay verification | SimDriver | `decision_eq` | — |
|
||||
| 5.16 | `--sim-alt-events` what-if branching | SimDriver | alt-events file | — |
|
||||
| 5.17 | Simulation isolation (no controller deps) | SimDriver | `xce_sched_sim_driver_t` | — |
|
||||
|
|
@ -526,7 +526,8 @@ int sched_driver_record_status(xce_sched_driver_t*, SchedAdminReply* out);
|
|||
typedef struct {
|
||||
xce_sched_core_t core;
|
||||
FILE *replay_file, *alt_events_file, *record_file;
|
||||
uint64_t sim_speed_num, sim_speed_den;
|
||||
// no sim_speed_num/sim_speed_den: simulation always runs the core clock
|
||||
// at speed 0/1 (Amended 2026-09-28 by spec scheduler-sim-discrete-clock)
|
||||
bool verify;
|
||||
bool interactive;
|
||||
} xce_sched_sim_driver_t;
|
||||
|
|
@ -757,7 +758,7 @@ No new metrics infrastructure — `SessionSummary` (Req 5 AC 12) provides sessio
|
|||
|
||||
- **Unit — Picker contract** (`test_picker_fcfs.c`): feed `on_queue_update`/`on_job_push`/`on_job_state_change` hooks directly, assert `next_job()` returns jobs in `(queue priority desc, job priority desc, queue_time asc)` order — verifies Req 3.2-3.4 without a live core.
|
||||
- **Unit — Core event contract** (`test_core_events.c`): `core_push_events()` followed by `core_go()` with a stub picker asserts state-change hooks fire exactly once per event, synchronously, before `core_go()` returns — verifies Req 5.1-5.8.
|
||||
- **Unit — Clock virtualization** (`test_clock.c`): `xce_core_now()` against the four mode rows in Req 5 AC 3's table (normal, discrete, real-time, fast/slow) — asserts the two-base+speed formula directly, no wall-clock flakiness (fixed `real_clock_base`/mocked `clock_gettime` delta).
|
||||
- **Unit — Clock virtualization** (`test_clock.c`): `xce_core_now()` against the two mode rows in Req 5 AC 3's table (normal 1/1, simulation 0/1), plus non-unit speed ratios that exercise the unchanged two-base+speed formula itself (no mode uses them; Amended 2026-09-28 by spec scheduler-sim-discrete-clock, which removed the real-time and fast/slow simulation rows) — asserts the formula directly, no wall-clock flakiness (fixed `real_clock_base`/mocked `clock_gettime` delta).
|
||||
- **Unit — Replay format round-trip** (as-built: `src/controller/testsuite/test_e2e_capnp.c`, not a dedicated `test_replay_format.c` — added to this repo's existing shared capnp round-trip test file instead): encode/decode every new capnp struct (`JobStateChangeEvent`, `JobUpdateEvent`, `DispatchDecision`, `PendDecision`, `PreemptDecision`, `SnapshotData`) — field-for-field equality after round-trip.
|
||||
- **Integration — Deterministic replay** (`test_sim_equivalence.c`, Req 5.7/5.7.1): record a synthetic scheduling session through `NormalDriver`'s test harness → replay through `SimDriver` → assert `ReplayDecision` sequences match exactly. This is the design's highest-value test — it directly exercises the central invariant.
|
||||
- **Integration — Recording lifecycle** (driver-level, Req 5.10-5.11): `record start` → submit synthetic events → `record stop` → verify file structure (`ReplayHeader`, `SnapshotEntry`, alternating `ReplayEvent`/`ReplaySession`, periodic checkpoints at the configured interval, final `endSession`).
|
||||
|
|
@ -780,7 +781,7 @@ _Feature-specific targets only; general practices are in steering docs._
|
|||
|
||||
- **Recording overhead**: zero file I/O, zero extra allocation when `recording == false` — a single boolean branch per session (Req 5 AC 10, explicit requirement, inherited here as a design constraint on `NormalDriver`).
|
||||
- **Determinism vs throughput**: `jbuf` cbuf capacity is permanently 1 (rendezvous, not a buffer) — this bounds picker→allocator throughput to strictly sequential handoff. This is an intentional trade-off (determinism over pipelining) already made at the requirements level (Req 5 AC 7) and is not revisited here; any future throughput work must find a different mechanism that preserves the ordering guarantee (e.g. deterministic batching with an explicit order tag), not simply raise the cbuf capacity.
|
||||
- **Simulation fast mode**: `speed_num=0` means the virtual clock never advances between events at wall-clock cost — `--sim` on a large `.replay` file runs at CPU-bound speed, not wall-clock speed. No specific throughput target is set here (none given in requirements); implementation should avoid introducing any per-event syscall beyond what decoding the capnp stream requires.
|
||||
- **Simulation throughput** (Amended 2026-09-28 by spec scheduler-sim-discrete-clock): simulation always runs at `speed_num=0`, so the virtual clock never advances between recorded timestamps and the replay is never paced against the wall clock — `--sim` on a large `.replay` file runs at CPU-bound speed, not wall-clock speed. There are no speed modes; `--sim-speed` is a deprecated no-op. No specific throughput target is set here (none given in requirements); implementation should avoid introducing any per-event syscall beyond what decoding the capnp stream requires.
|
||||
- **`OPCode_schedAdmin` vtask occupancy (hardened 2026-08-19)**: each request blocks its vtask handler thread up to 5s (cross-process wait on the scheduler's reply) while holding `c->sched.lock` — now gated by the same `vtaskmgr_blocking_acquire`/`_release` admission reservation `commit.c`'s commit-wait barrier shares (see `SchedAdminOpcode` component above). Admission-exhausted bursts fast-reject instead of occupying vtask threads; not separately load-tested against a real concurrent burst (unit-tested only, `test_schedadmin_fast_rejects_when_admission_exhausted`), but the mechanism itself is the same one already proven under `test_vtask_admission.c` and production commit-wait traffic.
|
||||
|
||||
## Open Questions / Risks
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ if (arguments.sim_file) {
|
|||
|------|------|---------|
|
||||
| (none) | Normal | Controller-connected (current behavior) |
|
||||
| `--sim FILE` | Simulation | Replay `.replay` file |
|
||||
| `--sim-speed N` | Simulation | 0=fast, 1=real-time, N=N× |
|
||||
| `--sim-speed N` | Simulation | Deprecated no-op: accepted with any value (in either mode), logs one warning, has no effect, removed in a future release; no simulation speed modes exist (AC 14; Amended 2026-09-28 by spec scheduler-sim-discrete-clock) |
|
||||
| `--sim-start-ts NS` | Simulation | Start replay from logical time |
|
||||
| `--sim-verify` | Simulation | Compare decisions against recorded |
|
||||
| `--interactive` / `-i` | Simulation | Open REPL for step-through debugging |
|
||||
|
|
@ -400,11 +400,11 @@ if (arguments.sim_file) {
|
|||
| Mode | `virtual_clock_base` | `real_clock_base` | `speed` | Behavior |
|
||||
|------|----------------------|-------------------|---------|----------|
|
||||
| Normal | 0 | 0 | 1/1 | `xce_core_now()` = wall clock (degraded: `0 + (wall - 0) × 1`) |
|
||||
| Simulation discrete | event `ts` | wall at load | 0/1 | `xce_core_now()` = frozen at event `ts` (time does not advance between events) |
|
||||
| Simulation real-time | snapshot `ts` | wall at load | 1/1 | `xce_core_now()` tracks wall clock from virtual anchor |
|
||||
| Simulation fast/slow | snapshot `ts` | wall at load | N/1 or 1/N | `xce_core_now()` runs N× faster or slower than wall clock |
|
||||
| Simulation | recorded value the replay last set: start snapshot `ts`, then each event `ts` / session `beginRound` (AC 14) | wall at each set | 0/1 (always) | `xce_core_now()` = exactly that recorded value; does not advance between sets, however much real time passes |
|
||||
|
||||
The driver atomically updates all four fields before each event dispatch. **Multi-thread safety**: `xce_core_now()` reads atomic fields lock-free. Both picker and allocator threads independently compute the same virtual time from the shared bases — no mutex needed.
|
||||
**Amendment (2026-09-28, spec scheduler-sim-discrete-clock)**: the former "Simulation real-time" (1/1) and "Simulation fast/slow" (N/1 or 1/N) rows are removed. The formula and its four atoms are unchanged, and normal mode keeps speed 1/1 anchored to the wall clock, but simulation mode always runs at speed 0/1: its virtual clock moves only when the replay sets it to a recorded timestamp. No simulation speed modes or wall-clock pacing are provided (none was ever implemented; a non-zero speed only let the virtual clock drift with host speed between recorded timestamps). `--sim-speed` is a deprecated no-op (AC 14) and the REPL `speed` parameter was removed (AC 22).
|
||||
|
||||
The driver atomically updates the clock fields before each event dispatch (in simulation mode the speed is set to 0/1 once at startup, AC 13 Step 4, and each later set re-anchors only the two bases). **Multi-thread safety**: `xce_core_now()` reads atomic fields lock-free. Both picker and allocator threads independently compute the same virtual time from the shared bases — no mutex needed.
|
||||
|
||||
All internal time uses go through `xce_core_now()`: scheduling logic, logging (via tlog format function using `userptr`), error messages, debug traces.
|
||||
Job `sub_time` and `queue_time` are set by the driver before pushing `JOBS_PUSH`.
|
||||
|
|
@ -747,7 +747,7 @@ if (arguments.sim_file) {
|
|||
|
||||
12. **Session response time metrics**: The core shall track session duration for diagnostics. At `core_go()`, the core stores `session_start = xce_core_now()`. At `core_end_session()`, the core computes `session_duration_ns = xce_core_now() - session_start`. The duration is written to the `ReplaySession.summary` field as a `SessionSummary` struct. The `SessionSummary` is optional for replay correctness (the simulation driver ignores it) but provides valuable diagnostics:
|
||||
- **Normal mode**: reveals real scheduling latency — is the picker slow? is allocation the bottleneck?
|
||||
- **Simulation mode**: in real-time mode, compare virtual vs wall-clock session duration; in fast mode, the virtual clock freezes during `core_go()` so `duration_ns` is typically 0 (all decisions at same `ts`)
|
||||
- **Simulation mode**: the virtual clock moves only when the replay sets it to a recorded timestamp (AC 14), and the replay reaches no recorded timestamp while a session is in progress, so `session_start` equals the recorded `beginRound` and `duration_ns` is 0 (all of the session's decisions carry that same `ts`). (Amended 2026-09-28 by spec scheduler-sim-discrete-clock: the real-time and fast simulation modes this bullet used to compare no longer exist.)
|
||||
- **Tuning**: diff session durations before and after a policy change to quantify performance impact
|
||||
|
||||
The core stores `session_start` internally — no new API functions, no change to the `on_decision` callback, no overhead beyond a single `xce_core_now()` call per session.
|
||||
|
|
@ -785,19 +785,22 @@ if (arguments.sim_file) {
|
|||
```
|
||||
sim->core.virtual_clock_base = snapshot_ts
|
||||
sim->core.real_clock_base = clock_gettime(CLOCK_MONOTONIC) // wall anchor
|
||||
sim->core.speed_num = arguments.sim_speed // 0=fast, 1=real-time, N>1=N×
|
||||
sim->core.speed_num = 0 // always: the clock moves only when the replay sets it (AC 14)
|
||||
sim->core.speed_den = 1
|
||||
```
|
||||
From this point, `xce_core_now()` returns virtual time computed from the snapshot's logical timestamp.
|
||||
From this point, `xce_core_now()` returns exactly the snapshot's logical timestamp until the replay sets the clock to the next recorded timestamp (AC 14), however much real time passes. (Amended 2026-09-28 by spec scheduler-sim-discrete-clock: `speed_num` no longer comes from `--sim-speed`, which is a deprecated no-op.)
|
||||
|
||||
**Step 5 — Enter event loop (AC 18):** accumulate events → BEGIN_ROUND → `core_push_events` → `core_go` → drain decisions → `core_end_session` → repeat until EOF.
|
||||
|
||||
The `ReplayHeader` + `SnapshotEntry` together form the complete self-contained starting point. Nothing outside the replay file is needed to begin simulation.
|
||||
|
||||
14. **Discrete event-driven virtual clock**: The simulation driver shall implement a virtual clock that advances by jumping directly to the timestamp of the next queued event — no fixed tick interval, no wall-clock waiting. Strictly monotonically increasing. Same-timestamp events delivered in file order. Supports:
|
||||
- `--sim-speed N` — N=0 as-fast-as-possible, N=1 real-time, N>1 N× real-time
|
||||
14. **Discrete event-driven virtual clock**: The simulation driver shall implement a virtual clock that moves only when the replay sets it — to the start snapshot's timestamp (AC 13 Step 4), to each recorded event's `ts`, and to each recorded session's `beginRound` — exactly, with no fixed tick interval, no wall-clock waiting, and no drift with real time between those sets. The clock follows the recording rather than being forced monotonic: a recorded `ts` or `beginRound` earlier than the current clock (for example the first events after the start snapshot, which the recorder stamps with a time read before it stamps that snapshot, or an out-of-order `--sim-alt-events` file) is set exactly as recorded, moving the clock backwards, without clamping and without error. Same-timestamp events delivered in file order. Supports:
|
||||
- `--interactive` / `-i` — open REPL for step-through debugging, breakpoints, state inspection, and snapshot capture (AC 22)
|
||||
|
||||
No simulation speed modes or wall-clock pacing are provided. `--sim-speed N` is a deprecated no-op: it is accepted with any value (including a non-numeric, negative or empty one), in simulation or normal mode, logs exactly one warning at startup naming the value, has no other effect, and will be removed in a future release.
|
||||
|
||||
(Amended 2026-09-28 by spec scheduler-sim-discrete-clock, its Requirements 1.2, 1.3, 1.5 and 2: replaces the former "Strictly monotonically increasing" clause and the `--sim-speed N` speed-mode bullet.)
|
||||
|
||||
15. **Deterministic replay verification**: In simulation mode with `--sim-verify`, the driver shall compare each core-emitted decision against the recorded decisions in the replay file. Any mismatch shall be reported as a regression with exact logical-time and decision-detail context.
|
||||
|
||||
16. **What-if branching**: The simulation driver shall accept `--sim-alt-events FILE`. When both a base `.replay` file (for snapshot loading) and an alt-events file are provided, the driver loads the snapshot from the base file, then replays events from the alt-events file (same `.replay` capnp stream format) — enabling "what-if" analysis.
|
||||
|
|
@ -1050,13 +1053,14 @@ if (arguments.sim_file) {
|
|||
**Simulation parameters** (interactive `set` / `info config`):
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `set speed <N>` | Set simulation speed from this point forward. `0` = as-fast-as-possible (no wall-clock delay), `1` = real-time, `N` = N× real-time. Overrides the `--sim-speed` CLI value. |
|
||||
| `set output <FILE>` | Start writing simulation decisions to FILE in the same `.replay` capnp stream format as `--sim-output`. Opens `ReplayHeader`+`SnapshotEntry` at the current position if the file is new. File is written incrementally — each subsequent session's decisions land in the file. |
|
||||
| `set output off` | Close the current output file. Subsequent decisions are not recorded. `info config` confirms the file path and event count at close time. |
|
||||
| `set verify on\|off` | Enable or disable decision verification against the recorded replay file. When enabled, each decision is compared against the corresponding recorded decision at the same logical time. Mismatches are printed immediately. Default: matches `--sim-verify` CLI flag. |
|
||||
| `info config` | Show current sim parameters: `speed=N, output=<path or "off">, verify=on|off, events_processed=N, current_ts=<logical_time>, sessions=N`. |
|
||||
| `info config` | Show current sim parameters: `output=<path or "off">, verify=on|off, events_processed=N, current_ts=<logical_time>, sessions=N`. |
|
||||
|
||||
**Why interactive parameters matter**: Without these, tuning simulation requires restart: change `--sim-speed`, re-run from snapshot, re-check results. With `set speed` and `set output`, the operator can fast-forward through known-good regions (`set speed 0`), slow down for suspicious sections (`set speed 0.1`), and only start recording output when the interesting behavior starts — all in one session. This turns the REPL from a passive inspector into an active investigation tool where parameters co-evolve with the operator's understanding of the trace.
|
||||
**REPL `speed` parameter removed** (Amended 2026-09-28 by spec scheduler-sim-discrete-clock): the table no longer has a `set speed <N>` row and `info config` no longer shows a `speed=` item. Entering `set speed`, with or without a value, changes no simulation state, prints a message that the speed parameter was removed because the simulator's clock moves only at recorded timestamps, and returns to the prompt (it does not end the simulation). `help` and the `set` usage message do not list it.
|
||||
|
||||
**Why interactive parameters matter**: Without these, tuning simulation requires restart: change the batch flags, re-run from snapshot, re-check results. With `set output` and `set verify`, the operator can move through known-good regions with `continue` and breakpoints, turn decision verification on or off, and only start recording output when the interesting behavior starts — all in one session. (Amended 2026-09-28 by spec scheduler-sim-discrete-clock: the former `set speed` fast-forward/slow-down rationale is removed with the parameter; the replay is never paced against the wall clock.) This turns the REPL from a passive inspector into an active investigation tool where parameters co-evolve with the operator's understanding of the trace.
|
||||
|
||||
**REPL integration with the simulation loop**:
|
||||
```
|
||||
|
|
@ -1067,9 +1071,9 @@ if (arguments.sim_file) {
|
|||
repl_pause() // pre-replay pause — operator can set breakpoints
|
||||
|
||||
for each event in replay_file:
|
||||
// ── sim parameter: speed ──
|
||||
if sim->sim_speed_num > 0:
|
||||
wall_clock_delay(delta_ns * sim->sim_speed_den / sim->sim_speed_num)
|
||||
// ── virtual clock (AC 14): set exactly to the recorded value ──
|
||||
// (no speed parameter and no wall-clock delay; Amended 2026-09-28 by spec scheduler-sim-discrete-clock)
|
||||
set_virtual_clock(msg.which == ReplaySession ? session.beginRound : event.ts)
|
||||
|
||||
if check_breakpoints(event):
|
||||
print "[sim] hit breakpoint @ event #I: <event_type> <key>..."
|
||||
|
|
@ -1099,7 +1103,7 @@ if (arguments.sim_file) {
|
|||
```
|
||||
|
||||
**What is NOT in v1**:
|
||||
- **Write-side mutations to scheduler state**: No `set queue priority`, `set job state`, `add job`, `remove job`. The `set` command in v1 only tunes simulation parameters (`speed`, `output`, `verify`) — it never mutates core scheduling state. Operator inspects state but cannot alter it. What-if analysis uses `--sim-alt-events` (AC 16) instead. State mutation from REPL is a follow-up.
|
||||
- **Write-side mutations to scheduler state**: No `set queue priority`, `set job state`, `add job`, `remove job`. The `set` command in v1 only tunes simulation parameters (`output`, `verify`; `speed` was removed, Amended 2026-09-28 by spec scheduler-sim-discrete-clock) — it never mutates core scheduling state. Operator inspects state but cannot alter it. What-if analysis uses `--sim-alt-events` (AC 16) instead. State mutation from REPL is a follow-up.
|
||||
- **Reverse execution**: No `step back` or time-travel undo. Operator can restart from snapshots captured at earlier points.
|
||||
- **Expression evaluation**: No `print core->sessions_count` or arbitrary C evaluation. Commands are fixed.
|
||||
- **Scripting/batch mode**: No `source FILE` or `-c "step 5; info summary"`. The REPL is interactive-only. For automated simulation runs, use the batch flags (`--sim`, `--sim-output`, `--sim-verify`) without `--interactive`.
|
||||
|
|
@ -1241,7 +1245,8 @@ typedef struct {
|
|||
xce_sched_core_t core;
|
||||
FILE *replay_file, *alt_events_file, *record_file;
|
||||
// sim parameters (mutable via REPL 'set' command — AC 22)
|
||||
uint64_t sim_speed_num, sim_speed_den; // 0/1=fast, 1/1=real-time, N/1=Nx
|
||||
// (no sim_speed_num/sim_speed_den: simulation always runs the core clock
|
||||
// at speed 0/1, AC 13 Step 4 — Amended 2026-09-28 by spec scheduler-sim-discrete-clock)
|
||||
bool verify; // decision comparison on/off
|
||||
bool interactive; // REPL active
|
||||
} xce_sched_sim_driver_t;
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ Test-first throughout (red → green → refactor). Every sub-task leaves the bu
|
|||
- _Requirements: 1.5, 2.2, 4.1_
|
||||
- _Depends: 2.1, 2.2, 2.3_
|
||||
|
||||
- [ ] 4. Documentation and specification alignment
|
||||
- [x] 4. Documentation and specification alignment
|
||||
- [x] 4.1 (P) Update the operator documentation of simulation mode
|
||||
- Describe the simulator clock as moving only at recorded timestamps, describe `--sim-speed` as deprecated with no effect, remove it from the example command line, and remove the claim that REPL and batch runs differ in pacing.
|
||||
- Done when the simulation section of the deployment guide contains none of real-time, speed modes or pacing, and names `--sim-speed` only as deprecated.
|
||||
- _Requirements: 5.1_
|
||||
- _Boundary: Docs (deployment guide)_
|
||||
- [ ] 4.2 (P) Update the scheduler-core specification
|
||||
- [x] 4.2 (P) Update the scheduler-core specification
|
||||
- Replace every speed-mode passage listed in requirements.md 5.2 in the scheduler-core requirements (flag table, AC 3, 12, 13, 14 including the monotonic-clock clause, AC 22 parameter table, pseudocode, rationale and out-of-scope note, data-structure summary) and design (traceability row, simulator fields, clock-test mode rows, fast-mode note).
|
||||
- Done when those passages state that no speed modes or wall-clock pacing exist, that `--sim-speed` is a deprecated no-op and that the REPL speed parameter was removed, and AC 14 permits the clock to move backwards to a recorded value.
|
||||
- _Requirements: 5.2_
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@
|
|||
* as xce_core_now() - session_start (Req 5 AC 12), exercised through
|
||||
* the REAL xce_core_go()/xce_core_end_session() (core_session.c) with
|
||||
* the core's clock frozen (discrete-simulation mode) so both the
|
||||
* zero-duration case (AC 12's own "fast mode ... duration_ns is
|
||||
* typically 0" note) and a nonzero case (clock advanced between go()
|
||||
* and end_session(), the same anchor-update-between-events pattern a
|
||||
* real driver follows) are fully deterministic.
|
||||
* zero-duration case (AC 12's simulation-mode bullet: the clock moves
|
||||
* only at recorded timestamps, so a session's duration_ns is 0) and
|
||||
* a nonzero case (clock advanced between go() and end_session(), the
|
||||
* same anchor-update-between-events pattern a real driver follows)
|
||||
* are fully deterministic.
|
||||
*
|
||||
* White-box #include of ../src/core_clock.c (xce_core_now(),
|
||||
* xce_core_tlog_format(), g_active_core_for_logging,
|
||||
|
|
@ -432,8 +433,9 @@ static void test_xce_core_register_tlog_format_succeeds(void)
|
|||
|
||||
static void test_session_duration_zero_when_clock_frozen_across_session(void)
|
||||
{
|
||||
/* AC 12's own note: "in fast mode the virtual clock freezes during
|
||||
* core_go() so duration_ns is typically 0". Discrete-simulation mode
|
||||
/* AC 12's simulation-mode bullet: the virtual clock moves only when
|
||||
* the replay sets it to a recorded timestamp, none is reached while a
|
||||
* session is in progress, so duration_ns is 0. Simulation mode
|
||||
* (speed=0/1) reproduces exactly that: xce_core_now() returns the same
|
||||
* frozen value at both core_go() and core_end_session(). */
|
||||
xce_sched_core_t core;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue