sim: EventQueue wakeup on events scheduled outside the event loop
This patch adds a 'wakeup' member function to EventQueue which should be called on an event queue whenever an event is scheduled on the event queue from outside code within the call tree of the gem5 event loop. This clearly isn't necessary for normal gem5 EventQueue operation but becomes the minimum necessary interface to allow hosting gem5's event loop onto other schedulers where there may be calls into gem5 from external code which schedules events onto an EventQueue between the current time and the time of the next scheduled event. The use case I have in mind is a SystemC hosting where the event loop is: while (more events) { wait(time_to_next_event or wakeup) setCurTick service events at this time } where the 'wait' needs to be woken up if time_to_next_event becomes shorter due to a scheduled event from SystemC arriving in a gem5 object. Requiring 'wakeup' to be called is a more efficient interface than requiring all gem5 event scheduling actions to affect the host scheduler. This interface could be located elsewhere, say on another global object, or by being passed by the host scheduler to objects which will schedule such events, but it seems cleanest to put it on EventQueue as it is actually a signal to the queue. EventQueue::wakeup is called for async_event events on event queue 0 as it's only important that *some* queue be triggered for such events.
This commit is contained in:
parent
960935a5bd
commit
e2a13386e5
4 changed files with 37 additions and 0 deletions
|
@ -44,6 +44,7 @@
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "sim/async.hh"
|
#include "sim/async.hh"
|
||||||
#include "sim/core.hh"
|
#include "sim/core.hh"
|
||||||
|
#include "sim/eventq.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -224,5 +225,7 @@ PollQueue::setupAsyncIO(int fd, bool set)
|
||||||
if (set) {
|
if (set) {
|
||||||
async_event = true;
|
async_event = true;
|
||||||
async_io = true;
|
async_io = true;
|
||||||
|
/* Wake up some event queue to handle event */
|
||||||
|
getEventQueue(0)->wakeup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "python/swig/pyevent.hh"
|
#include "python/swig/pyevent.hh"
|
||||||
#include "sim/async.hh"
|
#include "sim/async.hh"
|
||||||
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
PythonEvent::PythonEvent(PyObject *obj, Priority priority)
|
PythonEvent::PythonEvent(PyObject *obj, Priority priority)
|
||||||
: Event(priority), object(obj)
|
: Event(priority), object(obj)
|
||||||
|
@ -59,6 +60,8 @@ PythonEvent::process()
|
||||||
// that there's been an exception.
|
// that there's been an exception.
|
||||||
async_event = true;
|
async_event = true;
|
||||||
async_exception = true;
|
async_exception = true;
|
||||||
|
/* Wake up some event queue to handle event */
|
||||||
|
getEventQueue(0)->wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since the object has been removed from the event queue, its
|
// Since the object has been removed from the event queue, its
|
||||||
|
|
|
@ -605,6 +605,21 @@ class EventQueue : public Serializable
|
||||||
//! Function for moving events from the async_queue to the main queue.
|
//! Function for moving events from the async_queue to the main queue.
|
||||||
void handleAsyncInsertions();
|
void handleAsyncInsertions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param 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.
|
||||||
|
*/
|
||||||
|
virtual void wakeup(Tick when = (Tick)-1) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* function for replacing the head of the event queue, so that a
|
* function for replacing the head of the event queue, so that a
|
||||||
* different set of events can run without disturbing events that have
|
* different set of events can run without disturbing events that have
|
||||||
|
@ -635,6 +650,8 @@ class EventQueue : public Serializable
|
||||||
virtual void serialize(std::ostream &os);
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual ~EventQueue() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
void dumpMainQueue();
|
void dumpMainQueue();
|
||||||
|
@ -693,6 +710,11 @@ class EventManager
|
||||||
eventq->reschedule(event, when, always);
|
eventq->reschedule(event, when, always);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wakeupEventQueue(Tick when = (Tick)-1)
|
||||||
|
{
|
||||||
|
eventq->wakeup(when);
|
||||||
|
}
|
||||||
|
|
||||||
void setCurTick(Tick newVal) { eventq->setCurTick(newVal); }
|
void setCurTick(Tick newVal) { eventq->setCurTick(newVal); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "sim/async.hh"
|
#include "sim/async.hh"
|
||||||
#include "sim/core.hh"
|
#include "sim/core.hh"
|
||||||
|
#include "sim/eventq.hh"
|
||||||
#include "sim/init_signals.hh"
|
#include "sim/init_signals.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -58,6 +59,8 @@ dumpStatsHandler(int sigtype)
|
||||||
{
|
{
|
||||||
async_event = true;
|
async_event = true;
|
||||||
async_statdump = true;
|
async_statdump = true;
|
||||||
|
/* Wake up some event queue to handle event */
|
||||||
|
getEventQueue(0)->wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -66,6 +69,8 @@ dumprstStatsHandler(int sigtype)
|
||||||
async_event = true;
|
async_event = true;
|
||||||
async_statdump = true;
|
async_statdump = true;
|
||||||
async_statreset = true;
|
async_statreset = true;
|
||||||
|
/* Wake up some event queue to handle event */
|
||||||
|
getEventQueue(0)->wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exit signal handler.
|
/// Exit signal handler.
|
||||||
|
@ -74,6 +79,8 @@ exitNowHandler(int sigtype)
|
||||||
{
|
{
|
||||||
async_event = true;
|
async_event = true;
|
||||||
async_exit = true;
|
async_exit = true;
|
||||||
|
/* Wake up some event queue to handle event */
|
||||||
|
getEventQueue(0)->wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Abort signal handler.
|
/// Abort signal handler.
|
||||||
|
@ -89,6 +96,8 @@ ioHandler(int sigtype)
|
||||||
{
|
{
|
||||||
async_event = true;
|
async_event = true;
|
||||||
async_io = true;
|
async_io = true;
|
||||||
|
/* Wake up some event queue to handle event */
|
||||||
|
getEventQueue(0)->wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue