# Linux Kernel Module Cheat

##### 24.22.5.1. gem5 `execute` vs `initiateAcc` vs `completeAcc`

These are the key methods defined in instruction definitions, so lets see when each one gets called and what they do more or less.

`execute` is the only one of the three that gets defined by "non-memory" instructions.

Memory instructions define all three.

The three methods are present in the base class `StaticInst`:

        virtual Fault execute(ExecContext *xc,
                              Trace::InstRecord *traceData) const = 0;

        virtual Fault initiateAcc(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
        {
            panic("initiateAcc not defined!");
        }

        virtual Fault completeAcc(Packet *pkt, ExecContext *xc,
                                  Trace::InstRecord *traceData) const
        {
            panic("completeAcc not defined!");
        }

so we see that all instructions must implement `execute`, while overriding `initiateAcc` and `completeAcc` are optional and only done by classes for which those might get called: memory instructions.

`execute` is what does the actual job for non-memory instructions (obviously, since it is the only one of the three methods that is defined as not `panic` for those).

Memory instructions however run either:

- `execute` in `AtomicSimpleCPU`: this does the entire memory access in one go

- `initiateAcc` + `completeAcc` in timing CPUs. `initiateAcc` is called when the instruction starts executing, and `completeAcc` is called when the memory fetch returns from the memory system.

This can be seen concretely in GDB from the analysis done at: TimingSimpleCPU analysis: LDR stall and for more memory details see gem5 functional vs atomic vs timing memory requests.

- gem5 <code>completeAcc</code>