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();
156 bool has_next() {
return !(m_scheduled_events.empty() || m_scheduled_events.begin()->first > sc_core::sc_time_stamp()); }
159 while(!m_scheduled_events.empty()) {
160 auto queue = m_scheduled_events.begin()->second;
162 free_pool.push_back(queue);
163 m_scheduled_events.erase(m_scheduled_events.begin());
168 map_type m_scheduled_events;
169 std::deque<std::deque<TYPE>*> free_pool;
170 sc_core::sc_event m_event;
172 void insert_entry(
const TYPE& entry, sc_core::sc_time abs_time) {
173 auto it = m_scheduled_events.find(abs_time);
174 if(it == m_scheduled_events.end()) {
175 if(free_pool.size()) {
176 auto r = m_scheduled_events.insert(std::make_pair(abs_time, free_pool.front()));
177 free_pool.pop_front();
178 r.first->second->push_back(entry);
180 auto r = m_scheduled_events.insert(std::make_pair(abs_time,
new std::deque<TYPE>()));
181 r.first->second->push_back(entry);
184 it->second->push_back(entry);
187 void insert_entry(TYPE&& entry, sc_core::sc_time abs_time) {
188 auto it = m_scheduled_events.find(abs_time);
189 if(it == m_scheduled_events.end()) {
190 if(free_pool.size()) {
191 auto r = m_scheduled_events.insert(std::make_pair(abs_time, free_pool.front()));
192 free_pool.pop_front();
193 r.first->second->push_back(entry);
195 auto r = m_scheduled_events.insert(std::make_pair(abs_time,
new std::deque<TYPE>()));
196 r.first->second->push_back(entry);
199 it->second->push_back(entry);
203 auto entry = m_scheduled_events.begin()->second;
204 auto ret = entry->front();
207 free_pool.push_back(entry);
208 m_scheduled_events.erase(m_scheduled_events.begin());
210 if(m_scheduled_events.size())
211 m_event.notify(m_scheduled_events.begin()->first - sc_core::sc_time_stamp());
217 while(m_scheduled_events.size()) {
218 free_pool.push_back(m_scheduled_events.begin()->second);
219 m_scheduled_events.erase(m_scheduled_events.begin());
221 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