24.22.4. gem5 event queue
gem5 is an event based simulator, and as such the event queue is of of the crucial elements in the system.
Every single action that takes time (e.g. notably reading from memory) models that time delay by scheduling an event in the future.
The gem5 event queue stores one callback event for each future point in time.
The event queue is implemented in the class EventQueue
in the file src/sim/eventq.hh
.
Not all times need to have an associated event: if a given time has no events, gem5 just skips it and jumps to the next event: the queue is basically a linked list of events.
Important examples of events include:
-
CPU ticks
-
peripherals and memory
At gem5 event queue AtomicSimpleCPU syscall emulation freestanding example analysis we see for example that at the beginning of an AtomicCPU simulation, gem5 sets up exactly two events:
-
the first CPU cycle
-
one exit event at the end of time which triggers gem5 simulate() limit reached
Then, at the end of the callback of one tick event, another tick is scheduled.
And so the simulation progresses tick by tick, until an exit event happens.
The EventQueue
class has one awesome dump()
function that prints a human friendly representation of the queue, and can be easily called from GDB. TODO example.
We can also observe what is going on in the event queue with the Event
debug flag.
Event execution is done at EventQueue::serviceOne()
:
Event *exit_event = eventq->serviceOne();
This calls the Event::process
method of the event.
Another important technique is to use GDB and break at interesting points such as:
b Trace::OstreamLogger::logMessage b EventManager::schedule b EventFunctionWrapper::process
although stepping into EventFunctionWrapper::process
which does std::function
is a bit of a pain: https://stackoverflow.com/questions/59429401/how-to-step-into-stdfunction-user-code-from-c-functional-with-gdb
Another potentially useful technique is to use:
--trace Event,ExecAll,FmtFlag,FmtStackTrace --trace-stdout
which automates the logging of Trace::OstreamLogger::logMessage()
backtraces.
But alas, it misses which function callback is being scheduled, which is the awesome thing we actually want:
Then, once we had that, the most perfect thing ever would be to make the full event graph containing which events schedule which events!
-
gem5 event queue AtomicSimpleCPU syscall emulation freestanding example analysis
-
gem5 event queue TimingSimpleCPU syscall emulation freestanding example analysis
-
gem5 event queue TimingSimpleCPU syscall emulation freestanding example analysis with caches
-
gem5 event queue MinorCPU syscall emulation freestanding example analysis
-
gem5 event queue DerivO3CPU syscall emulation freestanding example analysis