20 #include <boost/optional.hpp>
24 #include <type_traits>
41 template <
class TYPE>
struct peq :
public sc_core::sc_object {
43 static_assert(std::is_copy_constructible<TYPE>::value,
"TYPE needs to be copy-constructible");
45 using pair_type = std::pair<const sc_core::sc_time, TYPE>;
46 using map_type = std::map<const sc_core::sc_time, std::deque<TYPE>*>;
53 : sc_core::sc_object(sc_core::sc_gen_unique_name(
"peq")) {}
60 explicit peq(
const char* name)
61 : sc_core::sc_object(name) {}
77 void notify(
const TYPE& entry,
const sc_core::sc_time& t) {
78 insert_entry(entry, t + sc_core::sc_time_stamp());
79 m_event.notify(m_scheduled_events.begin()->first - sc_core::sc_time_stamp());
89 void notify(TYPE&& entry) {
90 insert_entry(entry, sc_core::sc_time_stamp());
102 insert_entry(entry, sc_core::sc_time_stamp());
112 if(m_scheduled_events.empty())
114 sc_core::sc_time now = sc_core::sc_time_stamp();
115 if(!m_scheduled_events.size() || m_scheduled_events.begin()->first > now) {
116 if(m_scheduled_events.size())
117 m_event.notify(m_scheduled_events.begin()->first - now);
130 sc_core::wait(
event());
140 sc_core::sc_event&
event() {
return m_event; }
147 m_scheduled_events.clear();
157 if(m_scheduled_events.empty())
159 sc_core::sc_time now = sc_core::sc_time_stamp();
160 if(!m_scheduled_events.size() || m_scheduled_events.begin()->first > now) {
161 if(m_scheduled_events.size())
162 m_event.notify(m_scheduled_events.begin()->first - now);
170 while(!m_scheduled_events.empty()) {
176 map_type m_scheduled_events;
177 std::deque<std::deque<TYPE>*> free_pool;
178 sc_core::sc_event m_event;
180 void insert_entry(
const TYPE& entry, sc_core::sc_time abs_time) {
181 auto it = m_scheduled_events.find(abs_time);
182 if(it == m_scheduled_events.end()) {
183 if(free_pool.size()) {
184 auto r = m_scheduled_events.insert(std::make_pair(abs_time, free_pool.front()));
185 free_pool.pop_front();
186 r.first->second->push_back(entry);
188 auto r = m_scheduled_events.insert(std::make_pair(abs_time,
new std::deque<TYPE>()));
189 r.first->second->push_back(entry);
192 it->second->push_back(entry);
195 void insert_entry(TYPE&& entry, sc_core::sc_time abs_time) {
196 auto it = m_scheduled_events.find(abs_time);
197 if(it == m_scheduled_events.end()) {
198 if(free_pool.size()) {
199 auto r = m_scheduled_events.insert(std::make_pair(abs_time, free_pool.front()));
200 free_pool.pop_front();
201 r.first->second->push_back(entry);
203 auto r = m_scheduled_events.insert(std::make_pair(abs_time,
new std::deque<TYPE>()));
204 r.first->second->push_back(entry);
207 it->second->push_back(entry);
211 auto entry = m_scheduled_events.begin()->second;
212 auto ret = entry->front();
215 free_pool.push_back(entry);
216 m_scheduled_events.erase(m_scheduled_events.begin());
218 if(m_scheduled_events.size())
219 m_event.notify(m_scheduled_events.begin()->first - sc_core::sc_time_stamp());
225 while(m_scheduled_events.size()) {
226 free_pool.push_back(m_scheduled_events.begin()->second);
227 m_scheduled_events.erase(m_scheduled_events.begin());
229 for(
auto* p : free_pool)
peq()
default constructor creating a unnamed peq
void notify(TYPE const &entry)
non-blocking push
bool has_next()
check if value is available at current time
void notify(const TYPE &entry, const sc_core::sc_time &t)
non-blocking push.
void cancel_all()
cancel all events from the event queue
boost::optional< TYPE > get_next()
non-blocking get
peq(const char *name)
named peq constructor
sc_core::sc_event & event()
get the available event