Master the fundamental concepts of process management through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksThroughput averages hide scheduling latency: the time from a thread becoming runnable to actually receiving CPU. A web server can post high requests-per-second while still stuttering if wakeups wait milliseconds behind a long-running batch job.
Use monotonic clocks around scheduler events:
CLOCK_MONOTONIC when marking a task RUNNABLEFor example, if a thread becomes ready at t=1000 us and runs at t=1450 us, scheduling latency is 450 us for that event.
Scheduling latency is precisely what tools like cyclictest measure to certify Linux's PREEMPT_RT patches for real-time use in robotics and audio production, where a single 50-microsecond spike can cause an audible glitch or a missed control loop deadline. Using CLOCK_MONOTONIC instead of CLOCK_REALTIME here matters in practice too: NTP adjustments to wall-clock time have caused real latency-measurement bugs in production monitoring code.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will instrument your simulator or harness with timestamp hooks and print percentile summaries (p50/p95). This task asks you to compare RR quantum sizes and show how smaller slices cut latency at the cost of more context switches.
Scheduling latency is the time between a task becoming runnable (a wakeup) and the moment it actually gets the CPU. Tools like runqlat and cyclictest measure it by timestamping both events. Wall-clock timings would differ on every run, so this task works from an event trace instead. Pair each wakeup with the run that follows it, then report per-task and overall statistics, percentiles, and a log2 histogram.
One event per line: TIME_NS TASK wakeup or TIME_NS TASK run.
line N: time went backwards, ignored, and an event other than wakeup/run prints line N: unknown event E, ignored. N counts every input line.run - wakeup, and clears the pending state. A run with nothing pending is counted as without wakeup.NAME: no samples.ceil(P * n / 100) in the sorted samples.0 -> 1, 2 -> 3, 4 -> 7, 8 -> 15, and so on. Print every bucket from the lowest non-empty one to the highest, empty ones included. Each bucket gets one * per sample; if the largest bucket holds more than 40, scale every bucket to count * 40 / max, rounded down.cLoading…
events counts the accepted lines. With no samples at all, print no latency samples after the first line and stop.
Input:
cLoading…
Output:
cLoading…
Hidden tests cover repeated wakeups, runs without a wakeup, out-of-order timestamps, unknown event names, a task that never gets a sample, timestamps beyond 32 bits, and a histogram with more than 40 samples in one bucket.