38 class PhasedPayloadEvent :
public EventNode
43 using ProxyAllocation = std::vector<std::unique_ptr<PayloadDeliveringProxy>>;
44 using ProxyFreeList = std::vector<PayloadDeliveringProxy *>;
45 using ProxyInflightList = sparta::utils::FastList <PayloadDeliveringProxy *>;
59 "This Payload handle is already scheduled or was previously cancelled. "
60 "To schedule again, you must create a new one");
67 PhasedPayloadEvent<DataT> * parent) :
70 target_consumer_event_handler_(prototype.
getHandler()),
71 loc_(parent_->inflight_pl_.end())
82 friend class PhasedPayloadEvent;
89 void reclaim_()
override {
91 parent_->reclaimProxy_(loc_);
98 void eventCancelled_()
override {
105 void setPayload_(
const DataT & pl) {
107 payload_ =
new (&payload_storage_) DataT(pl);
111 void destroyPayload_() {
113 std::destroy_at(payload_);
117 const DataT & getPayload_()
const {
130 void deliverPayload_() {
132 "Some construct is trying to deliver a payload twice: "
133 << parent_->name_ <<
" to handler: "
134 << target_consumer_event_handler_.getName());
136 target_consumer_event_handler_((
const void*)payload_);
140 PhasedPayloadEvent<DataT> * parent_ =
nullptr;
141 const SpartaHandler target_consumer_event_handler_;
143 alignas(DataT) std::byte payload_storage_[
sizeof(DataT)];
145 bool scheduled_ =
false;
146 bool cancelled_ =
false;
151 ScheduleableHandle allocateProxy_(
const DataT & dat)
156 proxy = free_pl_[free_idx_];
160 if(allocation_idx_ == allocated_proxies_.size()) {
165 proxy = allocated_proxies_[allocation_idx_].get();
170 "' has allocated over " << inflight_pl_.
max_size() <<
171 " outstanding events -- does that seem right?");
173 proxy->setInFlightLocation_(inflight_pl_.
emplace_back(proxy));
174 proxy->setPayload_(dat);
180 friend class PayloadDeliveringProxy;
188 (*pl_location)->destroyPayload_();
189 free_pl_[free_idx_++] = *pl_location;
190 inflight_pl_.
erase(pl_location);
191 pl_location = inflight_pl_.
end();
207 PhasedPayloadEvent(
TreeNode * event_set,
208 const std::string & name,
210 const SpartaHandler & consumer_event_handler,
211 Clock::Cycle delay = 0) :
213 name_(name +
"[" + consumer_event_handler.
getName() +
"]"),
214 prototype_(consumer_event_handler, delay, sched_phase)
217 "You must assign a PhasedPayloadEvent a consumer handler "
218 "that takes exactly one argument");
225 for(PayloadDeliveringProxy * proxy : inflight_pl_) {
226 std::destroy_at(proxy->payload_);
251 return allocateProxy_(payload);
258 prototype_ >> consumer;
288 return inflight_pl_.
size();
297 for(
auto * proxy : inflight_pl_) {
298 if(proxy->isScheduled(rel_cycle)) {
317 const uint32_t cancel_cnt = inflight_pl_.
size();
320 auto bit = inflight_pl_.
begin();
321 while(bit != inflight_pl_.
end()) {
336 uint32_t
cancel(Clock::Cycle rel_cycle) {
337 const uint32_t cancel_cnt = inflight_pl_.
size();
338 auto bit = inflight_pl_.
begin();
339 while(bit != inflight_pl_.
end()) {
344 proxy->cancel(rel_cycle);
360 uint32_t cancel_cnt = 0;
363 auto bit = inflight_pl_.
begin();
364 while(bit != inflight_pl_.
end()) {
367 if(proxy->getPayload_() == criteria) {
386 std::vector<Scheduleable*> ple_vector;
387 for(
auto * proxy : inflight_pl_)
389 if(proxy->getPayload_() == criteria) {
390 ple_vector.push_back(proxy);
406 for(
auto * proxy : inflight_pl_)
408 if(proxy->getPayload_() == criteria) {
451 uint32_t
cancelIf(std::function<
bool(
const DataT &)> compare) {
452 uint32_t cancel_cnt = 0;
455 auto bit = inflight_pl_.
begin();
456 while(bit != inflight_pl_.
end()) {
459 if(compare(proxy->getPayload_())) {
506 std::vector<Scheduleable*>
getHandleIf(std::function<
bool(
const DataT &)> compare) {
507 std::vector<Scheduleable*> ple_vector;
508 for(
auto * proxy : inflight_pl_) {
509 if(compare(proxy->getPayload_())) {
510 ple_vector.push_back(proxy);
552 uint32_t
confirmIf(std::function<
bool(
const DataT &)> compare) {
553 for(
auto * proxy : inflight_pl_)
555 if(compare(proxy->getPayload_())) {
580 const std::string & name,
582 const SpartaHandler & consumer_event_handler,
583 Clock::Cycle delay = 0) :
585 name_(name +
"[" + consumer_event_handler.
getName() +
"]"),
586 prototype_(consumer_event_handler, delay, sched_phase)
590 "You must assign a PhasedPayloadEvent a consumer handler ""that takes exactly one argument");
597 void createResource_()
override {
608 const uint32_t old_size = allocated_proxies_.size();
609 const uint32_t new_size = payload_proxy_allocation_cadence_ + old_size;
610 allocated_proxies_.resize(new_size);
611 for(uint32_t i = old_size; i < new_size; ++i) {
614 free_pl_.resize(new_size,
nullptr);
621 Scheduleable prototype_;
623 ProxyAllocation allocated_proxies_;
624 ProxyFreeList free_pl_;
625 ProxyInflightList inflight_pl_{1100};
630 const uint32_t payload_proxy_allocation_cadence_ = 16;
631 uint32_t free_idx_ = 0;
632 uint32_t allocation_idx_ = 0;
File that defines the EventNode class.
File that defines the FastList class – an alternative to std::list when the user knows the size of th...
File that defines the Scheduleable class.
File that defines the phases used in simulation.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define SPARTA_EXPECT_TRUE(x)
A macro for hinting to the compiler a particular condition should be considered most likely true.
#define SPARTA_EXPECT_FALSE(x)
A macro for hinting to the compiler a particular condition should be considered most likely false.
#define CREATE_SPARTA_HANDLER(clname, meth)
File that defines the StartupEvent class.
File that defines a ValidValue.
EventNode is the base class for all event types in SPARTA. Not to be used by the modeler....
EventNode(TreeNode *event_set, const std::string &name, sparta::SchedulingPhase sched_phase)
Create an Event Node.
static Scheduler * determineScheduler(const Clock *clk)
Center point of Scheduler location.
Class to schedule a Scheduleable in the future with a payload, but the class itself is not typed on t...
virtual ~PhasedPayloadEvent()
Destroy!
uint32_t getNumOutstandingEvents() const
Return the number of unfired/unscheduled Payloads.
ScheduleableHandle preparePayload(const DataT &payload)
Prepare a Scheduleable Payload for scheduling either now or later.
uint32_t cancel(Clock::Cycle rel_cycle)
Cancel inflight PayloadEvents at the given relative cycle.
bool isScheduled() const
Is this PhasedPayloadEvent have anything scheduled?
PhasedPayloadEvent< DataT > & operator=(const PhasedPayloadEvent< DataT > &)=delete
No assignments, no copies.
void setContinuing(bool continuing)
This event, if continuing == true, will keep the simulation running.
uint32_t cancelIf(const DataT &criteria)
Cancel any scheduled Payload that matches the given criteria.
uint32_t confirmIf(std::function< bool(const DataT &)> compare)
Confirm if any scheduled payload matches the given criteria.
friend class PayloadDeliveringProxy
Allow the proxy to reclaim itself.
std::vector< Scheduleable * > getHandleIf(std::function< bool(const DataT &)> compare)
Return a vector of scheduleable handles that match the given function.
bool isScheduled(Clock::Cycle rel_cycle) const
Determine if this PhasedPayloadEvent is driven on the given cycle.
uint32_t cancel()
Cancel all inflight PayloadEvents.
PhasedPayloadEvent(const PhasedPayloadEvent< DataT > &)=delete
No assignments, no copies.
Scheduleable & operator>>(Scheduleable &consumer)
uint32_t cancelIf(std::function< bool(const DataT &)> compare)
Cancel any scheduled Payload that matches the given function.
std::vector< Scheduleable * > getHandleIf(const DataT &criteria)
Return a vector of scheduleable handles that match the given criteria.
Scheduleable & getScheduleable() override
Get the scheduleable associated with this event node.
bool confirmIf(const DataT &criteria)
Confirm if any scheduled payload matches the given criteria.
PhasedPayloadEvent(PhasedPayloadEvent< DataT > &&)=delete
No assignments, no copies.
A light-weight reference counting handle for Scheduleables – DOES NOT delete.
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.
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 scheduleRelativeTick(const Scheduler::Tick rel_tick, Scheduler *const scheduler)
Schedule this event on a relative scheduler tick.
const SpartaHandler & getHandler() const
Get the consumer handler/callback associated with this event.
void setScheduleableClock(const Clock *clk)
Set the clock and scheduler of this Scheduleable.
uint32_t getScheduleableHandleCount_() const
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.
uint64_t Tick
Typedef for our unit of time.
Node in a composite tree representing a sparta Tree item.
std::string getLocation() const override final
TreeNode()=delete
Not default-constructable.
const std::string & getName() const override
Gets the name of this node.
const Clock * getClock() override
Walks up parents (starting with self) until a parent with an associated local clock is found,...
iterator end()
Obtain an end iterator.
iterator begin()
Obtain a beginning iterator.
iterator emplace_back(ArgsT &&...args)
emplace an object at the back
NodeIterator< false > iterator
iterator erase(const const_iterator &entry)
Erase an element with the given iterator.
Macros for handling exponential backoff.
SchedulingPhase
The SchedulingPhases used for events (Tick, Update, PortUpdate, etc)