102 #ifndef SRC_VAULT_GEAR_SCHEDULER_H_ 103 #define SRC_VAULT_GEAR_SCHEDULER_H_ 135 class SchedulerService_test;
157 bool isCompulsory_{
false};
160 std::optional<activity::Term> term_;
165 , theScheduler_{&sched}
166 , term_{std::nullopt}
170 startOffset (microseconds afterNow)
172 start_ = RealClock::now() + _uTicks(afterNow);
177 startTime (
Time fixedTime)
184 lifeWindow (microseconds afterStart)
186 death_ = start_ + _uTicks(afterStart);
198 compulsory (
bool indeed =
true)
200 isCompulsory_ = indeed;
211 void maybeBuildTerm();
249 , activityLang_{activityAllocator}
250 , loadControl_{connectMonitoring()}
251 , engineObserver_{engineObserver}
258 return layer1_.empty();
270 TRACE (engine,
"Ignite Scheduler Dispatch.");
271 bool force_continued_run{
true};
272 handleDutyCycle (RealClock::now(), force_continued_run);
289 TRACE (engine,
"Forcibly terminate Scheduler Dispatch.");
290 workForce_.awaitShutdown();
334 continueMetaJob (RealClock::now(), planningJob, manID);
346 bool isCompulsory =
true;
349 postChain ({activityLang_.
buildMetaJob(planningJob, nextStart, deadline)
383 void handleDutyCycle (
Time now,
bool =
false);
384 void handleWorkerTermination (
bool isFailure);
385 void maybeScaleWorkForce (
Time startHorizon);
387 void triggerEmergency();
396 setup.currWorkForceSize = [
this]{
return workForce_.size(); };
397 setup.stepUpWorkForce = [
this](uint steps){ workForce_.incScale(steps); };
405 return RealClock::now();
429 using EngineEvent::EngineEvent;
457 , rootEvent{toDispatch}
476 chainEvent.refineTo (chain, when, dead);
477 scheduler_.sanityCheck (chainEvent);
478 return scheduler_.layer2_.
postChain (chainEvent, scheduler_.layer1_);
491 scheduler_.engineObserver_.dispatchEvent(qualifier, WorkTiming::start(now));
498 scheduler_.engineObserver_.dispatchEvent(qualifier, WorkTiming::stop(now));
506 return activity::PASS;
528 ,[
this]{
return getSchedTime(); }
551 theScheduler_->postChain ({term_->post(), start_
567 theScheduler_->activityLang_
568 .buildCalculationJob (job_, start_,death_));
572 ScheduleSpec::linkToSuccessor (
ScheduleSpec& succSpec,
bool unlimitedTime)
574 this->maybeBuildTerm();
576 term_->appendNotificationTo (*succSpec.term_, unlimitedTime);
581 ScheduleSpec::linkToPredecessor (
ScheduleSpec& predSpec,
bool unlimitedTime)
584 this->maybeBuildTerm();
585 predSpec.term_->appendNotificationTo (*term_, unlimitedTime);
595 throw error::Logic (
"Empty event passed into Scheduler entrance");
597 throw error::Fatal (
"Attempt to schedule an Activity without valid start time");
599 throw error::Fatal (
"Attempt to schedule an Activity without valid deadline");
600 Time now{getSchedTime()};
601 Offset toDeadline{now,
event.deathTime()};
604 "with a deadline by %s into the future"}
619 sanityCheck (actEvent);
620 maybeScaleWorkForce (actEvent.startTime());
665 if (not empty() or forceContinuation)
717 UNIMPLEMENTED (
"scheduler overrun -- trigger Emergency");
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
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.
Scheduler resource usage coordination.
Record to describe an Activity, to happen within the Scheduler's control flow.
Types marked with this mix-in may be moved and move-assigned.
void seedCalcStream(Job planningJob, ManifestationID manID=ManifestationID(), FrameRate expectedAdditionalLoad=FrameRate(25))
Set the Scheduler to work on a new CalcStream.
Low-level Render Engine event — abstracted storage base.
void handleWorkerTermination(bool isFailure)
Callback invoked whenever a worker-thread is about to exit.
void discardSchedule()
forcibly clear out the schedule
void dropGroomingToken() noexcept
relinquish the right for internal state transitions.
Memory management scheme for activities and parameter data passed through the Scheduler within the Lu...
Offset DUTY_CYCLE_PERIOD
period of the regular scheduler »tick« for state maintenance.
double getLoadIndicator()
Framerate specified as frames per second.
activity::Proc tick(Time now)
λ-tick : scheduler management duty cycle.
const size_t DISMISS_CYCLES
number of wait cycles before an idle worker terminates completely
Any copy and copy construction prohibited.
void announceLoad(FrameRate fps)
Scheduler Layer-2 : execution of Scheduler Activities.
Offset FUTURE_PLANNING_LIMIT
limit timespan of deadline into the future (~360 MiB max)
double effectiveLoad() const
Render Engine performance data collection service.
void postChain(ActivationEvent)
Enqueue for time-bound execution, possibly dispatch immediately.
ScheduleSpec post()
build Activity chain and hand-over to the Scheduler.
void ignite()
Spark the engine self-regulation cycle and power up WorkForce.
Time getSchedTime()
access high-resolution-clock, rounded to µ-Ticks
A front-end for using printf-style formatting.
LoadController::Wiring connectMonitoring()
ScheduleSpec defineSchedule(Job job)
Render Job builder: start definition of a schedule to invoke the given Job.
Lumiera's internal time value datatype.
Offset DUTY_CYCLE_TOLERANCE
maximum slip tolerated on duty-cycle start before triggering Scheduler-emergency
activity::Proc post(Time when, Time dead, Activity *chain, ExecutionCtx &ctx)
λ-post: enqueue for time-bound execution, within given ExecutionCtx.
void done(Time now, size_t qualifier)
λ-done : signal end time of actual processing.
Controller to coordinate resource usage related to the Scheduler.
void activate(ManifestationID manID)
Enable entries marked with a specific ManifestationID to be processed.
Derived specific exceptions within Lumiera's exception hierarchy.
Term builder and execution framework to perform chains of scheduler Activities.
»Scheduler-Service« : coordinate render activities.
Layer-1 of the Scheduler: queueing and prioritisation of activities.
Token or Atom with distinct identity.
void maybeScaleWorkForce(Time startHorizon)
Hook invoked whenever a new task is passed in.
void ensureCapacity(Time startHorizon)
Hook to check and possibly scale up WorkForce to handle one additional job.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
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...
const auto IDLE_WAIT
sleep-recheck cycle for workers deemed idle
work-timing event for performance observation
A language framework to define and interconnect scheduler activity verbs.
void handleDutyCycle(Time now, bool=false)
»Tick-hook« : code to maintain sane running status.
void triggerEmergency()
Trip the emergency brake and unwind processing while retaining all state.
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Layer-2 of the Scheduler: coordination and interaction of activities.
void continueMetaJob(Time nextStart, Job planningJob, ManifestationID manID=ManifestationID())
Place a follow-up job-planning job into the timeline.
activity::Proc doWork()
The worker-Functor: called by the active Workers from the WorkForce to pull / perform the actual rend...
Lumiera error handling (C++ interface).
void markWorkerExit()
statistics update on scaling down the WorkForce
void activate(double degree=1.0)
Activate or scale up the worker pool.
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
Offset measures a distance in time.
auto setup(FUN &&workFun)
Helper: setup a Worker-Pool configuration for the test.
Time getSchedTime()
access high-resolution-clock, rounded to µ-Ticks
void discardBefore(Time deadline)
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.
A pool of workers for multithreaded rendering.
static size_t COMPUTATION_CAPACITY
Nominal »full size« of a pool of concurrent workers.
Proc
Result instruction from Activity activation.
ActivationEvent pullHead()
Retrieve from the scheduling queue the entry with earliest start time.
Activity & createTick(Time deadline)
Individual frame rendering task, forwarding to a closure.
Duration WORK_HORIZON
the scope of activity currently in the works
void feedPrioritisation()
Pick up all new events from the entrance queue and enqueue them to be retrieved ordered by start time...
Front-end for simplified access to the current wall clock time.
Pool of worker threads for rendering.
void terminateProcessing()
Bring down processing destructively as fast as possible.
Base for configuration of the worker pool.
Vault-Layer implementation namespace root.
activity::Term buildMetaJob(Job job, Time start, Time deadline)
Builder-API: initiate definition of internal/planning job.
Collector and aggregator for performance data.
void updateState(Time)
periodic call to build integrated state indicators
Scheduler Layer-1 : time based dispatch.
void work(Time now, size_t qualifier)
λ-work : transition Managment-Mode -> Work-Mode.
activity::Proc dispatchCapacity(SchedulerInvocation &, LoadController &, DISPATCH, CLOCK)
Implementation of the worker-Functor: