# Linux Kernel Module Cheat

#### 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:

- https://stackoverflow.com/questions/37545327/get-the-name-of-a-stdfunction

- https://stackoverflow.com/questions/40706805/how-to-convert-a-function-pointer-to-function-name/40706869

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 AtomicSimpleCPU syscall emulation freestanding example analysis with caches and multiple CPUs

- gem5 event queue TimingSimpleCPU syscall emulation freestanding example analysis with caches and multiple CPUs

- gem5 event queue TimingSimpleCPU syscall emulation freestanding example analysis with caches and multiple CPUs and Ruby

- gem5 event queue MinorCPU syscall emulation freestanding example analysis

- gem5 event queue DerivO3CPU syscall emulation freestanding example analysis