Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
scheduler-invocation.hpp
Go to the documentation of this file.
1/*
2 SCHEDULER-INVOCATION.hpp - invocation layer of the render engine scheduler
3
4 Copyright (C)
5 2023, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
51#ifndef SRC_VAULT_GEAR_SCHEDULER_INVOCATION_H_
52#define SRC_VAULT_GEAR_SCHEDULER_INVOCATION_H_
53
54
55#include "vault/common.hpp"
56#include "lib/nocopy.hpp"
59#include "lib/util.hpp"
60
61#include <queue>
62#include <boost/lockfree/queue.hpp>
63#include <unordered_set>
64#include <utility>
65
66namespace vault{
67namespace gear {
68
69 using lib::time::Time;
70 using std::move;
71
72 namespace error = lumiera::error;
73
74 namespace {// Internal defaults
75 const size_t INITIAL_CAPACITY = 128;
76 }
77
83 {
85 int64_t starting;
86 int64_t deadline;
87
88 uint32_t manifestation :32;
89 bool isCompulsory :1;
90
92 : activity{nullptr}
93 , starting{_raw(Time::ANYTIME)}
94 , deadline{_raw(Time::NEVER)}
95 , manifestation{0}
96 , isCompulsory{false}
97 { }
98
100 , Time dead =Time::NEVER
102 , bool compulsory =false)
103 : activity{&act}
104 , starting{_raw(act.constrainedStart(when))}
105 , deadline{_raw(act.constrainedDeath(dead))}
106 , manifestation{manID}
107 , isCompulsory{compulsory}
108 { }
109 // default copy operations acceptable
110
115 bool
116 operator< (ActivationEvent const& o) const
117 {
118 return starting > o.starting;
119 }
120
121 operator bool() const { return bool(activity); }
122 operator Activity*() const { return activity; }
123
124 Time startTime() const { return Time{TimeValue{starting}};}
125 Time deathTime() const { return Time{TimeValue{deadline}};}
126
127 void
128 refineTo (Activity* chain, Time when, Time dead)
129 {
130 activity = chain;
131 starting = _raw(activity->constrainedStart (when.isRegular()? when:startTime()));
132 deadline = _raw(activity->constrainedDeath (dead.isRegular()? dead:deathTime()));
133 }
134 };
135
136
137
138
139 /***************************************************/
150 {
151 using InstructQueue = boost::lockfree::queue<ActivationEvent>;
152 using PriorityQueue = std::priority_queue<ActivationEvent>;
153 using ActivationSet = std::unordered_set<ManifestationID>;
154
157
159
160 public:
162 : instruct_{INITIAL_CAPACITY}
163 , priority_{}
164 , allowed_{}
165 { }
166
167
169 void
171 {
172 instruct_.consume_all([](auto&){/*obliterate*/});
174 }
175
176
180 void
182 {
183 bool success = instruct_.push (move (actEvent));
184 if (not success)
185 throw error::Fatal{"Scheduler entrance: memory allocation failed"};
186 }
187
188
193 void
195 {
196 ActivationEvent actEvent;
197 while (instruct_.pop (actEvent))
198 priority_.push (move (actEvent));
199 }
200
201
207 void
209 {
210 priority_.push (move (actEvent));
211 }
212
213
220 {
221 return priority_.empty()? ActivationEvent()
222 : priority_.top();
223 }
224
233 {
234 ActivationEvent head = peekHead();
235 if (head)
236 priority_.pop();
237 return head;
238 }
239
248 void
250 {
251 if (manID)
252 allowed_.insert (manID);
253 }
254
255 void
257 {
258 allowed_.erase (manID);
259 }
260
261
262 /* ===== query functions ===== */
263
265 bool
266 isDue (Time now) const
267 {
268 return not priority_.empty()
269 and priority_.top().starting <= waterLevel(now);
270 }
271
274 bool
275 isMissed (Time now) const
276 {
277 return not priority_.empty()
278 and waterLevel(now) > priority_.top().deadline;
279 }
280
282 bool
284 {
285 return manID == ManifestationID()
286 or util::contains (allowed_, manID);
287 }
288
290 bool
291 isOutdated (Time now) const
292 {
293 return isMissed (now)
294 or (not priority_.empty()
295 and not isActivated (priority_.top().manifestation));
296 }
297
299 bool
300 isOutOfTime (Time now) const
301 {
302 return isMissed (now)
303 and (not priority_.empty()
304 and priority_.top().isCompulsory
305 and isActivated (priority_.top().manifestation));
306 }
307
308 bool
310 {
311 return not instruct_.empty();
312 }
313
314 bool
315 empty() const
316 {
317 return instruct_.empty()
318 and priority_.empty();
319 }
320
322 Time
323 headTime() const
324 {
325 return priority_.empty()? Time::NEVER
326 : Time{TimeValue{priority_.top().starting}};
327 } //Note: 64-bit waterLevel corresponds to µ-Ticks
328
329 private:
330 static int64_t
332 {
333 return _raw(time);
334 }
335 };
336
337
338
339}} // namespace vault::gear
340#endif /*SRC_VAULT_GEAR_SCHEDULER_INVOCATION_H_*/
Descriptor for a piece of operational logic performed by the scheduler.
basic constant internal time value.
bool isRegular() const
Lumiera's internal time value datatype.
static const Time NEVER
border condition marker value. NEVER >= any time value
Derived specific exceptions within Lumiera's exception hierarchy.
Definition error.hpp:193
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
Record to describe an Activity, to happen within the Scheduler's control flow.
Definition activity.hpp:227
Time constrainedStart(Time start)
Definition activity.hpp:443
Time constrainedDeath(Time death)
Definition activity.hpp:450
Marker for current (and obsolete) manifestations of a CalcStream processed by the Render-Engine.
Definition activity.hpp:85
Scheduler Layer-1 : time based dispatch.
void feedPrioritisation(ActivationEvent actEvent)
Feed the given Activity directly into time prioritisation, effectively bypassing the thread dispatchi...
void instruct(ActivationEvent actEvent)
Accept an ActivationEvent with an Activity for time-bound execution.
std::priority_queue< ActivationEvent > PriorityQueue
bool isDue(Time now) const
Determine if there is work to do right now.
boost::lockfree::queue< ActivationEvent > InstructQueue
std::unordered_set< ManifestationID > ActivationSet
bool isOutOfTime(Time now) const
detect a compulsory Activity at scheduler head with missed deadline
bool isMissed(Time now) const
determine if the Activity at scheduler head missed it's deadline.
bool isOutdated(Time now) const
determine if Activity at scheduler is outdated and should be discarded
void activate(ManifestationID manID)
Enable entries marked with a specific ManifestationID to be processed.
void feedPrioritisation()
Pick up all new events from the entrance queue and enqueue them to be retrieved ordered by start time...
bool isActivated(ManifestationID manID) const
determine if Activities with the given ManifestationID shall be processed
void discardSchedule()
forcibly clear out the schedule
ActivationEvent pullHead()
Retrieve from the scheduling queue the entry with earliest start time.
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
Definition util.hpp:230
Vault-Layer implementation namespace root.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
bool operator<(ActivationEvent const &o) const
void refineTo(Activity *chain, Time when, Time dead)
ActivationEvent(Activity &act, Time when, Time dead=Time::NEVER, ManifestationID manID=ManifestationID(), bool compulsory=false)
a family of time value like entities and their relationships.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Basic set of definitions and includes commonly used together (Vault).