49 using std::atomic_bool;
54 using std::unique_ptr;
55 using std::make_unique;
56 using std::this_thread::yield;
57 using std::this_thread::sleep_for;
58 using std::chrono_literals::operator
""us;
63 const size_t REPETITIONS = 100;
121 Time now = detector.executionCtx.getSchedTime();
125 queue.
instruct ({activity, when, dead});
131 CHECK (detector.verifyInvocation(
"CTX-tick").
arg(now));
132 CHECK (queue.empty());
146 auto myself = std::this_thread::get_id();
161 auto myself = std::this_thread::get_id();
212 auto pause_and_sum = [&](
size_t i) ->
size_t 214 auto oldSum = checkSum;
216 checkSum = oldSum + i;
219 auto protected_sum = [&](
size_t i) ->
size_t 228 threadBenchmark<NUM_THREADS> (pause_and_sum, REPETITIONS);
230 size_t brokenSum = checkSum;
233 threadBenchmark<NUM_THREADS> (protected_sum, REPETITIONS);
235 CHECK (brokenSum < checkSum);
236 CHECK (checkSum =
NUM_THREADS * REPETITIONS*(REPETITIONS-1)/2);
242 atomic_bool stopTheHog_{
false};
243 unique_ptr<ThreadHookable> groomingHog_;
244 using Launch = ThreadHookable::Launch;
250 REQUIRE (not groomingHog_);
255 groomingHog_ = make_unique<ThreadHookable>(
258 do sleep_for (100us);
259 while (not stopTheHog_);
265 groomingHog_.reset();
267 .threadID(
"grooming-hog"));
269 ENSURE (groomingHog_);
346 CHECK (not sched.
findWork (queue, now));
353 CHECK (not sched.
findWork (queue, now));
357 CHECK (isSameObject (a1, *sched.
findWork(queue, now)));
358 CHECK (not sched.
findWork (queue, now));
361 CHECK (isSameObject (a2, *sched.
findWork(queue, now)));
362 CHECK (not sched.
findWork (queue, now));
364 CHECK (not queue.empty());
366 CHECK (isSameObject (a3, *sched.
findWork(queue, t3)));
367 CHECK (not sched.
findWork (queue, t3));
368 CHECK ( queue.empty());
372 CHECK (isSameObject (a1, *sched.
findWork(queue, now)));
374 CHECK (isSameObject (a2, *sched.
findWork(queue, now)));
375 CHECK (not sched.
findWork (queue, now));
376 CHECK ( queue.empty());
380 CHECK (not sched.
findWork (queue, now));
381 CHECK (not queue.empty());
384 CHECK (isSameObject (a2, *sched.
findWork(queue, now)));
385 CHECK (queue.empty());
419 CHECK (isSameObject (a1, *queue.
peekHead()));
428 CHECK (not sched.
findWork(queue, t1));
430 CHECK (isSameObject (a2, *queue.
peekHead()));
438 CHECK (isSameObject (a3, *queue.
peekHead()));
446 CHECK (not sched.
findWork(queue, t4));
464 CHECK (isSameObject (a3, *queue.
peekHead()));
465 CHECK (isSameObject (a4, *sched.
findWork(queue, t4)));
466 CHECK (queue.empty());
484 Time now = detector.executionCtx.getSchedTime();
485 Time past {Time::ZERO};
486 Time future{now+now};
490 auto myself = std::this_thread::get_id();
494 CHECK (activity::PASS == sched.
postChain (makeEvent(past), queue));
495 CHECK (detector.ensureNoInvocation(
"testActivity"));
497 CHECK (not sched.
findWork (queue,now));
499 CHECK (queue.empty());
502 CHECK (activity::PASS == sched.
postChain (makeEvent(future), queue));
504 CHECK (not queue.empty());
505 CHECK (isSameObject (activity, *queue.
peekHead()));
510 CHECK (queue.empty());
513 CHECK (activity::PASS == sched.
postChain (makeEvent(future), queue));
516 CHECK (not queue.empty());
520 CHECK (activity::PASS == sched.
postChain (makeEvent(now), queue));
526 CHECK (detector.ensureNoInvocation(
"testActivity"));
534 CHECK (isSameObject (activity, *sched.
findWork(queue, now)));
537 CHECK (not queue.
isDue(now));
538 CHECK ( queue.
isDue(future));
539 CHECK (sched.
findWork(queue, future));
540 CHECK ( queue.empty());
567 queue.
instruct ({activity, start, dead});
574 auto myself = std::this_thread::get_id();
579 auto getSchedTime = detector.executionCtx.getSchedTime;
591 CHECK (not queue.empty());
602 CHECK (queue.empty());
604 CHECK (detector.verifyInvocation(
"testActivity"));
628 Job testJob{detector.buildMockJob(
"testJob", nominal, 12345)};
634 Activity& anchor = activityLang.buildCalculationJob (testJob, start,dead)
638 detector.watchGate (anchor.
next,
"theGate");
647 auto myself = std::this_thread::get_id();
653 detector.executionCtx.getSchedTime = [&]{
return Time{now}; };
655 detector.executionCtx.work.implementedAs(
666 CHECK (detector.ensureNoInvocation(
"testJob"));
668 CHECK (not queue.empty());
677 CHECK (isSameObject(*act, anchor));
682 CHECK (queue.empty());
685 CHECK (detector.verifySeqIncrement(1)
686 .beforeInvocation(
"theGate").
arg(
"5.555 ⧐ Act(GATE")
687 .beforeInvocation(
"after-theGate").
arg(
"⧐ Act(WORKSTART")
688 .beforeInvocation(
"CTX-work").
arg(
"5.555",
"")
689 .beforeInvocation(
"testJob") .
arg(
"7.007",12345)
690 .beforeInvocation(
"CTX-done").
arg(
"5.555",
""));
a mutable time value, behaving like a plain number, allowing copy and re-accessing ...
activity::Proc postChain(ActivationEvent event, SchedulerInvocation &layer1)
This is the primary entrance point to the Scheduler.
Record to describe an Activity, to happen within the Scheduler's control flow.
auto threadBenchmark(FUN const &subject, const size_t repeatCnt=DEFAULT_RUNS)
perform a multithreaded microbenchmark.
void integratedWorkCycle()
bool holdsGroomingToken(ThreadID id) noexcept
check if the indicated thread currently holds the right to conduct internal state transitions...
void dropGroomingToken() noexcept
relinquish the right for internal state transitions.
void blockGroomingToken(SchedulerCommutator &sched)
void verify_GroomingToken()
Scheduler Layer-2 : execution of Scheduler Activities.
auto thisThread()
convenient short-notation, also used by SchedulerService
ActivationEvent findWork(SchedulerInvocation &layer1, Time now)
Look into the queues and possibly retrieve work due by now.
Functions to perform (multithreaded) timing measurement on a given functor.
void verify_Significance()
Lumiera's internal time value datatype.
static void ___ensureGroomingTokenReleased(SchedulerCommutator &sched)
Controller to coordinate resource usage related to the Scheduler.
void instruct(ActivationEvent actEvent)
Accept an ActivationEvent with an Activity for time-bound execution.
void activate(ManifestationID manID)
Enable entries marked with a specific ManifestationID to be processed.
Abstract Base Class for all testcases.
Term builder and execution framework to perform chains of scheduler Activities.
bool isOutdated(Time now) const
determine if Activity at scheduler is outdated and should be discarded
Marker for current (and obsolete) manifestations of a CalcStream processed by the Render-Engine...
Diagnostic context to record and evaluate activations within the Scheduler.
void demonstrateSimpleUsage()
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void unblockGroomingToken()
Convenience front-end to simplify and codify basic thread handling.
void verify_GroomingGuard()
ActivationEvent peekHead()
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Activity & buildActivationProbe(string id)
build a rigged HOOK-Activity to record each invocation
bool isMissed(Time now) const
determine if Activity at scheduler head missed it's deadline
uint incrementSeq()
increment the internal invocation sequence number
Activity * next
Activities are organised into chains to represent relations based on verbs.
Diagnostic setup to instrument and observe Activity activations.
Layer-2 of the Scheduler: coordination and interaction of activities.
void torture_GroomingToken()
static const Time NEVER
border condition marker value. NEVER >= any time value
bool isOutOfTime(Time now) const
detect a compulsory Activity at scheduler head with missed deadline
Extended variant of the standard case, allowing to install callbacks (hook functions) to be invoked d...
ScopedGroomingGuard requireGroomingTokenHere()
a scope guard to force acquisition of the GroomingToken
static activity::Proc dispatchChain(Activity *chain, EXE &executionCtx)
Execution Framework: dispatch performance of a chain of Activities.
ActivationEvent pullHead()
Retrieve from the scheduling queue the entry with earliest start time.
Individual frame rendering task, forwarding to a closure.
a family of time value like entities and their relationships.
void feedPrioritisation()
Pick up all new events from the entrance queue and enqueue them to be retrieved ordered by start time...
ActivityMatch & arg(ARGS const &...args)
qualifier: additionally match the function arguments
Vault-Layer implementation namespace root.
bool isDue(Time now) const
Determine if there is work to do right now.
bool acquireGoomingToken() noexcept
acquire the right to perform internal state transitions.
Scheduler Layer-1 : time based dispatch.
activity::Proc dispatchCapacity(SchedulerInvocation &, LoadController &, DISPATCH, CLOCK)
Implementation of the worker-Functor:
void detach_thread_from_wrapper()
allow to detach explicitly — independent from thread-function's state.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.