Skip to main content

Module chaos_timeslice

Module chaos_timeslice 

Source
Expand description

The maximum timeslice that hermit run --chaos --chaos-seeded-timeslice draws from the scheduler seed.

Chaos mode ends each timeslice after a random number of retired conditional branches, exponentially distributed with a mean of the maximum timeslice and capped at it. Which mean finds a race depends on the race: one whose window is a few dozen branches long needs slices of about a hundred branches, while one whose second thread must run far into its own work before the conflicting access needs slices that let it get there. A fixed mean suits one of them. Drawing the mean once per scheduler seed spreads a sweep of seeds across five orders of magnitude, so it covers both without a guessed value.

The draw is not uniform over those orders of magnitude. The races measured needed either the shortest slices or the longest: a 46-branch window in a multithreaded C++ test binary failed in 9 of 32 seeds at 1000 ns and in none of 32 at 1e4, 1e5, 1e6 or the default 2e8 ns (1e7 was not measured), while races whose other thread must first run tens of thousands of branches need 1000000 ns or more, and none of the races measured needed the decades in between. So SEEDED_MAX_TIMESLICE_PIECES gives two in five seeds 1000 to 2000 ns (100 to 200 branches per slice), two in five 1000000 to 200000000 ns, and keeps one in five for the decades between them.

The draw is a pure function of the scheduler seed (and of the one-RCB floor, which only a large clock multiplier or slowdown factor raises above the range). It seeds a generator of its own and takes nothing from the streams Detcore already derives from that seed (each thread’s chaos generator, the post-fork generator, the per-thread slowdown factors), so those are seeded exactly as before. Its result is an ordinary --max-timeslice value: Detcore receives the configuration of a run given that value explicitly.

Constants§

DEFAULT_MAX_TIMESLICE
SEEDED_MAX_TIMESLICE_MAX_NS as a maximum: the default that --chaos-seeded-timeslice stands in for where it draws nothing.
SEEDED_MAX_TIMESLICE_MAX_NS
The largest drawn maximum, in virtual nanoseconds: the --max-timeslice default. No draw exceeds it, so a replay of a recorded chaos run, which keeps the default, is never bounded more tightly than the recording was.
SEEDED_MAX_TIMESLICE_MIN_NS
The smallest drawn maximum, in virtual nanoseconds: 100 retired conditional branches at the default clock multiplier.
SEEDED_MAX_TIMESLICE_PIECES
The pieces of the drawn maximum’s distribution, in order: each is (share, low, high), the share of seeds whose maximum falls in [low, high] virtual nanoseconds, log-uniformly within it. The pieces are contiguous, run from SEEDED_MAX_TIMESLICE_MIN_NS to SEEDED_MAX_TIMESLICE_MAX_NS, and their shares sum to one.

Functions§

seeded_max_timeslice
The maximum timeslice, in virtual nanoseconds, drawn for sched_seed: one uniform number u from the seed’s own generator, mapped through the quantile function of SEEDED_MAX_TIMESLICE_PIECES (the piece whose cumulative share passes u, log-uniformly within it), rounded to a whole nanosecond, then raised to minimum_ns (one RCB at the run’s clock multiplier and slowdown, detcore::Config::minimum_max_timeslice_nanos) if it falls below it. The mapping is monotone in u.