Lumiera  0.pre.03
»edit your freedom«
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) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
60 #ifndef SRC_VAULT_GEAR_SCHEDULER_INVOCATION_H_
61 #define SRC_VAULT_GEAR_SCHEDULER_INVOCATION_H_
62 
63 
64 #include "vault/common.hpp"
65 #include "lib/nocopy.hpp"
66 #include "vault/gear/activity.hpp"
67 #include "lib/time/timevalue.hpp"
68 #include "lib/util.hpp"
69 
70 #include <queue>
71 #include <boost/lockfree/queue.hpp>
72 #include <unordered_set>
73 #include <utility>
74 
75 namespace vault{
76 namespace gear {
77 
78  using lib::time::Time;
79  using std::move;
80 
81  namespace error = lumiera::error;
82 
83  namespace {// Internal defaults
84  const size_t INITIAL_CAPACITY = 128;
85  }
86 
92  {
93  Activity* activity;
94  int64_t starting;
95  int64_t deadline;
96 
97  uint32_t manifestation :32;
98  bool isCompulsory :1;
99 
101  : activity{nullptr}
102  , starting{_raw(Time::ANYTIME)}
103  , deadline{_raw(Time::NEVER)}
104  , manifestation{0}
105  , isCompulsory{false}
106  { }
107 
108  ActivationEvent(Activity& act, Time when
109  , Time dead =Time::NEVER
111  , bool compulsory =false)
112  : activity{&act}
113  , starting{_raw(act.constrainedStart(when))}
114  , deadline{_raw(act.constrainedDeath(dead))}
115  , manifestation{manID}
116  , isCompulsory{compulsory}
117  { }
118  // default copy operations acceptable
119 
124  bool
125  operator< (ActivationEvent const& o) const
126  {
127  return starting > o.starting;
128  }
129 
130  operator bool() const { return bool{activity}; }
131  operator Activity*() const { return activity; }
132 
133  Time startTime() const { return Time{TimeValue{starting}};}
134  Time deathTime() const { return Time{TimeValue{deadline}};}
135 
136  void
137  refineTo (Activity* chain, Time when, Time dead)
138  {
139  activity = chain;
140  starting = _raw(activity->constrainedStart (when.isRegular()? when:startTime()));
141  deadline = _raw(activity->constrainedDeath (dead.isRegular()? dead:deathTime()));
142  }
143  };
144 
145 
146 
147 
148  /***************************************************/
159  {
160  using InstructQueue = boost::lockfree::queue<ActivationEvent>;
161  using PriorityQueue = std::priority_queue<ActivationEvent>;
162  using ActivationSet = std::unordered_set<ManifestationID>;
163 
164  InstructQueue instruct_;
165  PriorityQueue priority_;
166 
167  ActivationSet allowed_;
168 
169  public:
171  : instruct_{INITIAL_CAPACITY}
172  , priority_{}
173  , allowed_{}
174  { }
175 
176 
178  void
180  {
181  instruct_.consume_all([](auto&){/*obliterate*/});
182  priority_ = PriorityQueue();
183  }
184 
185 
189  void
191  {
192  bool success = instruct_.push (move (actEvent));
193  if (not success)
194  throw error::Fatal{"Scheduler entrance: memory allocation failed"};
195  }
196 
197 
202  void
204  {
205  ActivationEvent actEvent;
206  while (instruct_.pop (actEvent))
207  priority_.push (move (actEvent));
208  }
209 
210 
216  void
218  {
219  priority_.push (move (actEvent));
220  }
221 
222 
229  {
230  return priority_.empty()? ActivationEvent()
231  : priority_.top();
232  }
233 
242  {
243  ActivationEvent head = peekHead();
244  if (head)
245  priority_.pop();
246  return head;
247  }
248 
257  void
259  {
260  if (manID)
261  allowed_.insert (manID);
262  }
263 
264  void
265  drop (ManifestationID manID)
266  {
267  allowed_.erase (manID);
268  }
269 
270 
271  /* ===== query functions ===== */
272 
274  bool
275  isDue (Time now) const
276  {
277  return not priority_.empty()
278  and priority_.top().starting <= waterLevel(now);
279  }
280 
283  bool
284  isMissed (Time now) const
285  {
286  return not priority_.empty()
287  and waterLevel(now) > priority_.top().deadline;
288  }
289 
291  bool
293  {
294  return manID == ManifestationID()
295  or util::contains (allowed_, manID);
296  }
297 
299  bool
300  isOutdated (Time now) const
301  {
302  return isMissed (now)
303  or (not priority_.empty()
304  and not isActivated (priority_.top().manifestation));
305  }
306 
308  bool
309  isOutOfTime (Time now) const
310  {
311  return isMissed (now)
312  and (not priority_.empty()
313  and priority_.top().isCompulsory
314  and isActivated (priority_.top().manifestation));
315  }
316 
317  bool
318  hasPendingInput() const
319  {
320  return not instruct_.empty();
321  }
322 
323  bool
324  empty() const
325  {
326  return instruct_.empty()
327  and priority_.empty();
328  }
329 
331  Time
332  headTime() const
333  {
334  return priority_.empty()? Time::NEVER
335  : Time{TimeValue{priority_.top().starting}};
336  } //Note: 64-bit waterLevel corresponds to µ-Ticks
337 
338  private:
339  static int64_t
340  waterLevel (Time time)
341  {
342  return _raw(time);
343  }
344  };
345 
346 
347 
348 }} // namespace vault::gear
349 #endif /*SRC_VAULT_GEAR_SCHEDULER_INVOCATION_H_*/
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
Definition: timevalue.hpp:322
Record to describe an Activity, to happen within the Scheduler&#39;s control flow.
Definition: activity.hpp:235
void discardSchedule()
forcibly clear out the schedule
void feedPrioritisation(ActivationEvent actEvent)
Feed the given Activity directly into time prioritisation, effectively bypassing the thread dispatchi...
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
Time constrainedDeath(Time death)
Definition: activity.hpp:459
bool isActivated(ManifestationID manID) const
determine if Activities with the given ManifestationID shall be processed
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
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.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
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...
Definition: activity.hpp:93
bool isRegular() const
Definition: timevalue.hpp:780
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
bool isMissed(Time now) const
determine if Activity at scheduler head missed it&#39;s deadline
Basic set of definitions and includes commonly used together (Vault).
static const Time NEVER
border condition marker value. NEVER >= any time value
Definition: timevalue.hpp:323
bool isOutOfTime(Time now) const
detect a compulsory Activity at scheduler head with missed deadline
ActivationEvent pullHead()
Retrieve from the scheduling queue the entry with earliest start time.
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...
basic constant internal time value.
Definition: timevalue.hpp:142
Time constrainedStart(Time start)
Definition: activity.hpp:452
Vault-Layer implementation namespace root.
bool isDue(Time now) const
Determine if there is work to do right now.
Scheduler Layer-1 : time based dispatch.
Descriptor for a piece of operational logic performed by the scheduler.