The Sparta Modeling Framework
Loading...
Searching...
No Matches
Scheduleable.hpp
Go to the documentation of this file.
1
2// <Scheduleable.h> -*- C++ -*-
3
4
5#pragma once
6
7#include <cinttypes>
8
11
18namespace sparta
19{
20 class ScheduleableHandle;
21 class Scheduler;
22 class Vertex;
23
38 {
39
40 public:
42 typedef uint32_t PrecedenceGroup;
43
44 static const PrecedenceGroup INVALID_GROUP;
45
56 Scheduleable(const SpartaHandler & consumer_event_handler,
57 Clock::Cycle delay, SchedulingPhase sched_phase,
58 bool is_unique_event = false);
59
63 virtual ~Scheduleable() = default;
64
66 Scheduleable(const Scheduleable &) = default;
67
69 Scheduleable(Scheduleable &&) noexcept = default;
70
72 Scheduler * getScheduler(const bool must_exist = true) {
73 sparta_assert(scheduler_ || !must_exist);
74 return scheduler_;
75 }
76
78 const Scheduler * getScheduler(const bool must_exist = true) const {
79 sparta_assert(scheduler_ || !must_exist);
80 return scheduler_;
81 }
82
87 void setDelay(Clock::Cycle delay) {
88 delay_ = delay;
89 }
90
95 void addDelay(Clock::Cycle delay) {
96 delay_ += delay;
97 }
98
103 Clock::Cycle getDelay() const {
104 return delay_;
105 }
106
115 void setContinuing(bool continuing) {
116 continuing_ = continuing;
117 }
118
123 bool isContinuing() const {
124 return continuing_;
125 }
126
131 const SpartaHandler & getHandler() const {
133 }
134
139 SpartaHandler & getHandler() {
141 }
142
147 void setHandler(const SpartaHandler & handler) {
148 consumer_event_handler_ = handler;
150 }
151
156 void schedule()
157 {
158 this->schedule(delay_, local_clk_);
159 }
160
166 void schedule(const Clock * clk)
167 {
168 schedule(delay_, clk);
169 }
170
176 void schedule(Clock::Cycle delay)
177 {
178 schedule(delay, local_clk_);
179 }
180
188 virtual void scheduleRelativeTick(const Scheduler::Tick rel_tick,
189 Scheduler * const scheduler)
190 {
191 sparta_assert(scheduler != nullptr);
192 scheduler->scheduleEvent(this, rel_tick, pgid_,
193 continuing_, is_unique_event_);
194 }
195
201 void schedule(Clock::Cycle delay, const Clock *clk)
202 {
203 sparta_assert(clk != nullptr);
204 this->scheduleRelativeTick(clk->getTick(delay),
205 clk->getScheduler());
206 }
207
214 bool isScheduled() const {
215 return scheduler_->isScheduled(this);
216 }
217
221 bool isOrphan() const;
222
226 bool isScheduled(Clock::Cycle rel_cycle) const {
227 Scheduler::Tick rel_tick = local_clk_->getTick(rel_cycle);
228 return scheduler_->isScheduled(this, rel_tick);
229 }
230
233 return sched_phase_;
234 }
235
237 const char * getLabel() const {
238 return label_.c_str();
239 }
240
242 void setLabel(const char * label);
243
246 Vertex * getVertex(){
247 return vertex_;
248 }
249
258 void precedes(Scheduleable & consumer, const std::string & reason = "");
259
268 void precedes(Vertex & consumer, const std::string & reason = "") const;
269
278 void precedes(Scheduleable * consumer, const std::string & reason = "") {
279 this->precedes(*consumer, reason);
280 }
281
290 void precedes(Vertex * consumer, const std::string & reason = "") const{
291 this->precedes(*consumer, reason);
292 }
293
299 void setGOP(bool gop) {
300 is_gop_ = gop;
301 }
302
305 void setGroupID(const PrecedenceGroup gid) {
306 pgid_ = gid;
307 }
308
314
320 return pgid_;
321 }
322
327 void cancel() {
328 scheduler_->cancelEvent(this);
330 }
331
339 void cancel(Clock::Cycle rel_cycle) {
340 Scheduler::Tick rel_tick = local_clk_->getTick(rel_cycle);
341 scheduler_->cancelEvent(this, rel_tick);
342
343 // If the event was scheduled at the given time, it will
344 // be cancelled by the Scheduler. We don't explicitly
345 // cancel this here.
346 }
347
348
354 void setScheduleableClock(const Clock * clk) {
355 sparta_assert(clk != nullptr);
356 local_clk_ = clk;
357 scheduler_ = clk->getScheduler();
358 }
359
366 void setScheduler(Scheduler * sched){
367 scheduler_ = sched;
368 }
369
377 void setVertex();
378
379#ifndef DO_NOT_DOCUMENT
380
381 virtual void onSchedulerAssignment_() {
382 setupDummyPrecedence_ThisMethodToGoAwayOnceDaveAddsPhaseSupportToDAG();
383 }
384 void setupDummyPrecedence_ThisMethodToGoAwayOnceDaveAddsPhaseSupportToDAG();
385
386#endif
387
388 protected:
391
393 const Clock * local_clk_ = nullptr;
394
398 return scheduleable_handle_count_;
399 }
400
408 virtual void setGroupID_(const PrecedenceGroup gid) {
409 pgid_ = gid;
410 }
411
412 // Allow the Scheduler to cancel the event
413 friend class Scheduler;
414
417 virtual void eventCancelled_() {}
418
428 public:
429 explicit PrecedenceSetup(Scheduleable * scheduleable) :
430 scheduleable_(scheduleable)
431 {}
432
433 PrecedenceSetup & operator=(Scheduler * scheduler);
434
435 Scheduler * operator->() {
436 return scheduler_;
437 }
438
439 const Scheduler * operator->() const {
440 return scheduler_;
441 }
442
443 operator Scheduler*() {
444 return scheduler_;
445 }
446
447 operator const Scheduler*() const {
448 return scheduler_;
449 }
450
451 operator bool() const {
452 return scheduler_ != nullptr;
453 }
454
455 bool equals(const PrecedenceSetup & other) const {
456 return scheduler_ == other.scheduler_;
457 }
458
459 private:
460 Scheduleable * scheduleable_ = nullptr;
461 Scheduler * scheduler_ = nullptr;
462 };//End class PrecedenceSetup
463
466
467 private:
468 friend class DAG;
469
470 friend class Unit; // temporary
471
472 friend class ScheduleableHandle;
473
477 Vertex * vertex_ = nullptr;
478
480 std::string label_;
481
483 PrecedenceGroup pgid_ = 0;
484
486 // TODO: elminate Unit.cpp code that used this.
487 bool is_gop_ = false;
488
490 mutable uint32_t scheduleable_handle_count_ = 0;
491
495 virtual void reclaim_() {}
496
498 Clock::Cycle delay_;
499
502 const SchedulingPhase sched_phase_ = SchedulingPhase::Invalid;
503
508 bool continuing_ = true;
509
512 const bool is_unique_event_ = false;
513
514 };//End class Scheduleable
515
516
530 {
531 private:
533 void disconnect_() {
534 if(scheduleable_ && --scheduleable_->scheduleable_handle_count_ == 0) {
535 scheduleable_->reclaim_();
536 }
537 }
538
540 void connect_() {
541 if(scheduleable_) {
542 ++scheduleable_->scheduleable_handle_count_;
543 }
544 }
545
546 public:
549
550 // Default move
552
555 {
556 disconnect_();
557 scheduleable_ = orig.scheduleable_;
558 connect_();
559 }
560
568 scheduleable_(scheduleable)
569 {
570 connect_();
571 }
572
580 scheduleable_(&scheduleable)
581 {
582 connect_();
583 }
584
590 {
591 disconnect_();
592 }
593
596 return scheduleable_;
597 }
598
601 bool operator==(const ScheduleableHandle & rhs) const {
602 return (scheduleable_ == rhs.scheduleable_);
603 }
604
607 bool operator!=(const ScheduleableHandle & rhs) const {
608 return !(scheduleable_ == rhs.scheduleable_);
609 }
610
613 disconnect_();
614 scheduleable_ = rhs.scheduleable_;
615 connect_();
616 return *this;
617 }
618
619 private:
620 Scheduleable *scheduleable_ = nullptr;
621 };//End class ScheduleableHandle
622
623
624 // Scheduleable >> Scheduleable
625 inline Scheduleable & operator>>(Scheduleable & producer, Scheduleable & consumer)
626 {
627 sparta_assert(producer.getSchedulingPhase() == consumer.getSchedulingPhase(),
628 "The Producer: " << producer.getLabel() << " scheduling phase is not equal to"
629 " the consumer: " << consumer.getLabel());
630 producer.precedes(consumer);
631 return consumer;
632 }
633
634}
File that defines the Clock class.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
File that contains the macro used to generate the class callbacks.
A representation of simulated time.
Definition Clock.hpp:51
Scheduler * getScheduler() const
Definition Clock.hpp:302
Scheduler::Tick getTick(const Cycle &cycle) const
Return the tick corresponding to the given cycle.
Definition Clock.hpp:214
A light-weight reference counting handle for Scheduleables – DOES NOT delete.
bool operator==(const ScheduleableHandle &rhs) const
ScheduleableHandle & operator=(const ScheduleableHandle &rhs)
Assignment.
ScheduleableHandle(Scheduleable *scheduleable)
Create a ScheduleableHandle with a given Scheduleable pointer. NO reference counting is performed wit...
ScheduleableHandle(const ScheduleableHandle &orig)
Copy a Handle, increment the count.
ScheduleableHandle()=default
Create an empty Handle.
bool operator!=(const ScheduleableHandle &rhs) const
ScheduleableHandle(Scheduleable &scheduleable)
Create a ScheduleableHandle with a given Scheduleable reference. NO reference counting is performed w...
Scheduleable * operator->() const
Get at the underlying Scheduleable.
An internal class used in Scheduleble to cache a pointer to the scheduler.
A class that defines the basic scheduling interface to the Scheduler. Not intended to be used by mode...
void setContinuing(bool continuing)
This event, if continuing == true, will keep the simulation running.
SpartaHandler & getHandler()
Get the consumer handler/callback associated with this event.
void setScheduler(Scheduler *sched)
Set the Scheduler of this Scheduleable, and set the local vertex_ to a new vertex from the Vertex Fac...
virtual void eventCancelled_()
void schedule(Clock::Cycle delay)
Schedule an event in the future using the pre-set Clock.
void precedes(Vertex *consumer, const std::string &reason="") const
Have this Scheduleable precede a Vertex.
virtual void scheduleRelativeTick(const Scheduler::Tick rel_tick, Scheduler *const scheduler)
Schedule this event on a relative scheduler tick.
PrecedenceGroup getGroupID() const
Get the group ID.
uint32_t PrecedenceGroup
Typedef defining the precedence group ID.
void addDelay(Clock::Cycle delay)
Add to the delay for this event.
void cancel(Clock::Cycle rel_cycle)
Cancel this Scheduleable at the given time, if placed on the Scheduler.
void schedule()
Schedule this event with its pre-set delay using the pre-set Clock.
const char * getLabel() const
Get the internal label.
void cancel()
Cancel all the times that this Scheduleable was placed on the Scheduler.
bool isScheduled(Clock::Cycle rel_cycle) const
Return true if this Scheduleable was scheduled on the given relative cycle.
Scheduler * getScheduler(const bool must_exist=true)
Get the scheduler this Scheduleable is assigned to.
void precedes(Scheduleable &consumer, const std::string &reason="")
Have this Scheduleable precede another.
bool isOrphan() const
Return true if this scheduleable is not associated with a vertex.
const SpartaHandler & getHandler() const
Get the consumer handler/callback associated with this event.
Scheduleable(const Scheduleable &)=default
Allow copies.
void setHandler(const SpartaHandler &handler)
Set the consumer handler/callback associated with this event.
bool unlink(Scheduleable *w)
Unlink this scheduleables vertex from another scheduleables vertex.
void setGOP(bool gop)
Vertex * getVertex()
get the internal Vertex of this scheduleable
void precedes(Vertex &consumer, const std::string &reason="") const
Have this Scheduleable precede a Vertex.
void setGroupID(const PrecedenceGroup gid)
bool isScheduled() const
Return true if this scheduleable was scheduled at all.
void schedule(const Clock *clk)
Schedule this event with its pre-set delay using the given clock.
const Scheduler * getScheduler(const bool must_exist=true) const
Get the scheduler this Scheduleable is assigned to.
Clock::Cycle getDelay() const
Get the delay associated with this event.
Scheduleable(Scheduleable &&) noexcept=default
Allow moves. Marked as noexcept to force containers to use it.
void setVertex()
Set the local vertex_ to a new vertex from the Vertex Factory. This needs to happen before the Schedu...
void setDelay(Clock::Cycle delay)
Set a fixed delay for this event.
void setLabel(const char *label)
Set a new label for this Scheduleable – used in debugging.
void setScheduleableClock(const Clock *clk)
Set the clock and scheduler of this Scheduleable.
bool isContinuing() const
Is this Event continuing?
virtual void setGroupID_(const PrecedenceGroup gid)
Set the group ID of this Scheduleable's derivatives.
void schedule(Clock::Cycle delay, const Clock *clk)
Schedule an event in the future using the given Clock.
SchedulingPhase getSchedulingPhase() const
Get the internal phase number.
virtual ~Scheduleable()=default
Destructor.
PrecedenceSetup scheduler_
Cache a pointer to the scheduler used.
uint32_t getScheduleableHandleCount_() const
const Clock * local_clk_
A local clock for speed.
void precedes(Scheduleable *consumer, const std::string &reason="")
Have this Scheduleablee precede another.
SpartaHandler consumer_event_handler_
The Consumer callback registered with the Event.
Scheduleable(const SpartaHandler &consumer_event_handler, Clock::Cycle delay, SchedulingPhase sched_phase, bool is_unique_event=false)
Construct a Scheduleable object.
A class that lets you schedule events now and in the future.
bool isScheduled(const Scheduleable *scheduleable) const
Is the given Scheduleable item anywhere (in time now -> future) on the Scheduler?
void cancelEvent(const Scheduleable *scheduleable)
Cancel the given Scheduleable if on the Scheduler.
void scheduleEvent(Scheduleable *scheduleable, Tick rel_time, uint32_t dag_group=0, bool continuing=true, bool add_if_not_scheduled=false)
Schedule a single event. This method should also be thread safe.
uint64_t Tick
Typedef for our unit of time.
The is the base class for user defined blocks in simulation.
Definition Unit.hpp:38
Macros for handling exponential backoff.
std::enable_if< std::is_base_of< EventNode, ScheduleableTypeA >::value, constGlobalOrderingPoint >::type & operator>>(ScheduleableTypeA &producer, const GlobalOrderingPoint &consumer)
Place a precedence between a Scheduleable object and a GlobalOrderingPoint.
SchedulingPhase
The SchedulingPhases used for events (Tick, Update, PortUpdate, etc)