gem5
|
Queue of events sorted in time order. More...
#include <eventq.hh>
Classes | |
class | ScopedMigration |
Temporarily migrate execution to a different event queue. More... | |
class | ScopedRelease |
Temporarily release the event queue service lock. More... | |
Public Member Functions | |
EventQueue (const std::string &n) | |
virtual const std::string | name () const |
void | name (const std::string &st) |
void | schedule (Event *event, Tick when, bool global=false) |
Schedule the given event on this queue. More... | |
void | deschedule (Event *event) |
Deschedule the specified event. More... | |
void | reschedule (Event *event, Tick when, bool always=false) |
Reschedule the specified event. More... | |
Tick | nextTick () const |
void | setCurTick (Tick newVal) |
Tick | getCurTick () const |
Event * | getHead () const |
Event * | serviceOne () |
void | serviceEvents (Tick when) |
bool | empty () const |
void | dump () const |
bool | debugVerify () const |
void | handleAsyncInsertions () |
Function for moving events from the async_queue to the main queue. More... | |
virtual void | wakeup (Tick when=(Tick)-1) |
Function to signal that the event loop should be woken up because an event has been scheduled by an agent outside the gem5 event loop(s) whose event insertion may not have been noticed by gem5. More... | |
Event * | replaceHead (Event *s) |
function for replacing the head of the event queue, so that a different set of events can run without disturbing events that have already been scheduled. More... | |
void | checkpointReschedule (Event *event) |
Reschedule an event after a checkpoint. More... | |
virtual | ~EventQueue () |
void | lock () |
Provide an interface for locking/unlocking the event queue. More... | |
void | unlock () |
Private Member Functions | |
void | insert (Event *event) |
Insert / remove event from the queue. More... | |
void | remove (Event *event) |
void | asyncInsert (Event *event) |
Function for adding events to the async queue. More... | |
EventQueue (const EventQueue &) | |
Private Attributes | |
std::string | objName |
Event * | head |
Tick | _curTick |
std::mutex | async_queue_mutex |
Mutex to protect async queue. More... | |
std::list< Event * > | async_queue |
List of events added by other threads to this event queue. More... | |
std::mutex | service_mutex |
Lock protecting event handling. More... | |
Queue of events sorted in time order.
Events are scheduled (inserted into the event queue) using the schedule() method. This method either inserts a synchronous or asynchronous event.
Synchronous events are scheduled using schedule() method with the argument 'global' set to false (default). This should only be done from a thread holding the event queue lock (EventQueue::service_mutex). The lock is always held when an event handler is called, it can therefore always insert events into its own event queue unless it voluntarily releases the lock.
Events can be scheduled across thread (and event queue borders) by either scheduling asynchronous events or taking the target event queue's lock. However, the lock should never be taken directly since this is likely to cause deadlocks. Instead, code that needs to schedule events in other event queues should temporarily release its own queue and lock the new queue. This prevents deadlocks since a single thread never owns more than one event queue lock. This functionality is provided by the ScopedMigration helper class. Note that temporarily migrating between event queues can make the simulation non-deterministic, it should therefore be limited to cases where that can be tolerated (e.g., handling asynchronous IO or fast-forwarding in KVM).
Asynchronous events can also be scheduled using the normal schedule() method with the 'global' parameter set to true. Unlike the previous queue migration strategy, this strategy is fully deterministic. This causes the event to be inserted in a separate queue of asynchronous events (async_queue), which is merged main event queue at the end of each simulation quantum (by calling the handleAsyncInsertions() method). Note that this implies that such events must happen at least one simulation quantum into the future, otherwise they risk being scheduled in the past by handleAsyncInsertions().
|
private |
EventQueue::EventQueue | ( | const std::string & | n | ) |
|
private |
Function for adding events to the async queue.
The added events are added to main event queue later. Threads, other than the owning thread, should call this function instead of insert().
Definition at line 422 of file eventq.cc.
References async_queue, and async_queue_mutex.
Referenced by schedule().
void EventQueue::checkpointReschedule | ( | Event * | event | ) |
Reschedule an event after a checkpoint.
Since events don't know which event queue they belong to, parent objects need to reschedule events themselves. This method conditionally schedules an event that has the Scheduled flag set. It should be called by parent objects after unserializing an object.
Only use this method after unserializing an Event.
Definition at line 285 of file eventq.cc.
References Event::flags, Flags< T >::isSet(), and EventBase::Scheduled.
bool EventQueue::debugVerify | ( | ) | const |
Definition at line 319 of file eventq.cc.
References cprintf(), Event::dump(), Event::nextBin, Event::nextInBin, Event::priority(), and Event::when().
|
inline |
Deschedule the specified event.
Should be called only from the owning thread.
Definition at line 69 of file eventq_impl.hh.
References curEventQueue(), DTRACE, MipsISA::event, Event::initialized(), inParallelMode, EventBase::Scheduled, Event::scheduled(), and EventBase::Squashed.
Referenced by EventManager::deschedule(), BaseRemoteGDB::descheduleInstCommitEvent(), RubySystem::memWriteback(), and pybind_init_event().
void EventQueue::dump | ( | ) | const |
Definition at line 294 of file eventq.cc.
References cprintf(), curTick(), Event::dump(), Event::nextBin, and Event::nextInBin.
Referenced by pybind_init_event().
|
inline |
Definition at line 642 of file eventq.hh.
References head.
Referenced by doSimLoop(), RubySystem::eventQueueEmpty(), RubySystem::memWriteback(), and serviceEvents().
|
inline |
Definition at line 615 of file eventq.hh.
References _curTick.
Referenced by abortHandler(), curTick(), reschedule(), schedule(), and BaseRemoteGDB::scheduleInstCommitEvent().
|
inline |
Definition at line 616 of file eventq.hh.
References head.
Referenced by RubySystem::memWriteback().
void EventQueue::handleAsyncInsertions | ( | ) |
Function for moving events from the async_queue to the main queue.
Definition at line 430 of file eventq.cc.
References async_queue, async_queue_mutex, curEventQueue(), and insert().
Referenced by doSimLoop(), and GlobalSyncEvent::BarrierEvent::process().
|
private |
Insert / remove event from the queue.
Should only be called by thread operating this queue.
Definition at line 118 of file eventq.cc.
References Event::insertBefore(), and Event::nextBin.
Referenced by handleAsyncInsertions(), reschedule(), and schedule().
|
inline |
Provide an interface for locking/unlocking the event queue.
Do NOT use these methods directly unless you really know what you are doing. Incorrect use can easily lead to simulator deadlocks.
Definition at line 688 of file eventq.hh.
References service_mutex.
Referenced by DistIface::RecvScheduler::pushPacket(), DistIface::recvThreadFunc(), EventQueue::ScopedMigration::ScopedMigration(), EventQueue::ScopedMigration::~ScopedMigration(), and EventQueue::ScopedRelease::~ScopedRelease().
|
inlinevirtual |
|
inline |
Definition at line 599 of file eventq.hh.
References objName, and ArmISA::st.
|
inline |
Definition at line 613 of file eventq.hh.
References head, and Event::when().
Referenced by doSimLoop(), and serviceEvents().
|
private |
Definition at line 172 of file eventq.cc.
References Event::nextBin, panic, Event::queue, and Event::removeItem().
function for replacing the head of the event queue, so that a different set of events can run without disturbing events that have already been scheduled.
Already scheduled events can be processed by replacing the original head back. USING THIS FUNCTION CAN BE DANGEROUS TO THE HEALTH OF THE SIMULATOR. NOT RECOMMENDED FOR USE.
Definition at line 361 of file eventq.cc.
References ArmISA::s, and ArmISA::t.
Referenced by RubySystem::startup().
Reschedule the specified event.
Should be called only from the owning thread.
Definition at line 87 of file eventq_impl.hh.
References curEventQueue(), DTRACE, MipsISA::event, getCurTick(), Event::initialized(), inParallelMode, insert(), EventBase::Scheduled, Event::scheduled(), and EventBase::Squashed.
Referenced by pybind_init_event(), and EventManager::reschedule().
Schedule the given event on this queue.
Safe to call from any thread.
Definition at line 42 of file eventq_impl.hh.
References asyncInsert(), curEventQueue(), DTRACE, getCurTick(), Event::initialized(), inParallelMode, insert(), EventBase::Scheduled, and Event::scheduled().
Referenced by DelayFunction(), RubySystem::memWriteback(), Pl390::postInt(), VGic::postVInt(), pybind_init_event(), EventManager::schedule(), and BaseRemoteGDB::scheduleInstCommitEvent().
|
inline |
Definition at line 624 of file eventq.hh.
References empty(), nextTick(), serviceOne(), and setCurTick().
Event * EventQueue::serviceOne | ( | ) |
Definition at line 204 of file eventq.cc.
References Flags< T >::clear(), MipsISA::event, Event::flags, EventBase::IsMainQueue, X86ISA::lock, EventBase::Managed, Event::nextBin, Event::nextInBin, Event::process(), EventBase::Scheduled, and EventBase::Squashed.
Referenced by doSimLoop(), and serviceEvents().
|
inline |
Definition at line 614 of file eventq.hh.
References _curTick.
Referenced by StatTest::run(), serviceEvents(), and EventManager::setCurTick().
|
inline |
Definition at line 689 of file eventq.hh.
References service_mutex.
Referenced by DistIface::RecvScheduler::pushPacket(), DistIface::recvThreadFunc(), EventQueue::ScopedMigration::ScopedMigration(), EventQueue::ScopedRelease::ScopedRelease(), and EventQueue::ScopedMigration::~ScopedMigration().
Function to signal that the event loop should be woken up because an event has been scheduled by an agent outside the gem5 event loop(s) whose event insertion may not have been noticed by gem5.
This function isn't needed by the usual gem5 event loop but may be necessary in derived EventQueues which host gem5 onto other schedulers.
when | Time of a delayed wakeup (if known). This parameter can be used by an implementation to schedule a wakeup in the future if it is sure it will remain active until then. Or it can be ignored and the event queue can be woken up now. |
Definition at line 664 of file eventq.hh.
Referenced by dumprstStatsHandler(), dumpStatsHandler(), exitNowHandler(), ioHandler(), PollQueue::setupAsyncIO(), and EventManager::wakeupEventQueue().
|
private |
Definition at line 493 of file eventq.hh.
Referenced by getCurTick(), and setCurTick().
List of events added by other threads to this event queue.
Definition at line 499 of file eventq.hh.
Referenced by asyncInsert(), and handleAsyncInsertions().
|
private |
Mutex to protect async queue.
Definition at line 496 of file eventq.hh.
Referenced by asyncInsert(), and handleAsyncInsertions().
|
private |
Definition at line 492 of file eventq.hh.
Referenced by empty(), getHead(), and nextTick().
|
private |
|
private |
Lock protecting event handling.
This lock is always taken when servicing events. It is assumed that the thread scheduling new events (not asynchronous events though) have taken this lock. This is normally done by serviceOne() since new events are typically scheduled as a response to an earlier event.
This lock is intended to be used to temporarily steal an event queue to support inter-thread communication when some deterministic timing can be sacrificed for speed. For example, the KVM CPU can use this support to access devices running in a different thread.