33 using std::chrono::microseconds;
36 using Wiring = LoadController::Wiring;
237 auto is_between = [](
auto lo,
auto hi,
auto val)
239 return lo <= val and val < hi;
244 TimeVar now = RealClock::now();
246 Time next{now + ten};
261 const size_t REPETITIONS = 1e6;
262 for (
size_t i=0; i< REPETITIONS; ++i)
267 auto error = fabs(avg/expect - 1);
268 CHECK (0.002 >
error);
290 uint maxThreads = 10;
291 uint currThreads = 0;
294 setup.maxCapacity = [&]{
return maxThreads; };
295 setup.currWorkForceSize = [&]{
return currThreads; };
299 CHECK (0 == lctrl.averageLag());
300 CHECK (0 == lctrl.effectiveLoad());
307 CHECK (0.5 == lctrl.effectiveLoad());
309 CHECK (0.8 == lctrl.effectiveLoad());
311 CHECK (1.0 == lctrl.effectiveLoad());
314 lctrl.setCurrentAverageLag (200+500);
315 CHECK (2.0 == lctrl.effectiveLoad());
317 lctrl.setCurrentAverageLag (200+500+500);
318 CHECK (3.0 == lctrl.effectiveLoad());
321 lctrl.setCurrentAverageLag (200-500);
322 CHECK (0.5 == lctrl.effectiveLoad());
323 CHECK (-300 == lctrl.averageLag());
325 lctrl.setCurrentAverageLag (200-500-500-500);
326 CHECK (0.25 == lctrl.effectiveLoad());
327 CHECK (-1300 == lctrl.averageLag());
331 CHECK (0.05 == lctrl.effectiveLoad());
334 Time head = Time::ZERO;
336 lctrl.markIncomingCapacity (head,curr);
337 CHECK (-882 == lctrl.averageLag());
339 lctrl.markIncomingCapacity (head,curr);
340 CHECK (-540 == lctrl.averageLag());
343 lctrl.markIncomingCapacity (head,curr);
344 lctrl.markIncomingCapacity (head,curr);
345 CHECK (1291 == lctrl.averageLag());
347 curr = head -
Time{0,2};
348 lctrl.markIncomingCapacity (head,curr);
349 CHECK (-2581 == lctrl.averageLag());
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
bool tendedNext(Time nextHead) const
did we already tend for the indicated next relevant head time?
int64_t setCurrentAverageLag(int64_t lag)
a mutable time value, behaving like a plain number, allowing copy and re-accessing ...
Duration NEAR_HORIZON
what counts as "imminent" (e.g. for spin-waiting)
Scheduler resource usage coordination.
void indicateAverageLoad()
Capacity markIncomingCapacity(Time head, Time now)
decide how this thread's capacity shall be used when returning from idle wait and asking for work ...
Lumiera's internal time value datatype.
Controller to coordinate resource usage related to the Scheduler.
Abstract Base Class for all testcases.
Simplistic test class runner.
Offset scatteredDelayTime(Time now, Capacity capacity)
Generate a time offset to relocate currently unused capacity to a time range where it's likely to be ...
void tendNext(Time nextHead)
Mark the indicated next head time as tended.
Duration SLEEP_HORIZON
schedules beyond that horizon justify going idle
static const Time NEVER
border condition marker value. NEVER >= any time value
Offset measures a distance in time.
auto setup(FUN &&workFun)
Helper: setup a Worker-Pool configuration for the test.
static Capacity classifyTimeHorizon(Offset off)
classification of time horizon for scheduling
Capacity markOutgoingCapacity(Time head, Time now)
decide how this thread's capacity shall be used after it returned from being actively employed ...
Duration WORK_HORIZON
the scope of activity currently in the works
Front-end for simplified access to the current wall clock time.
Capacity
Allocation of capacity to time horizon of expected work.
Vault-Layer implementation namespace root.