diff --git a/doc/emu_chan.txt b/doc/emu_chan.txt new file mode 100644 index 0000000..bfad57f --- /dev/null +++ b/doc/emu_chan.txt @@ -0,0 +1,157 @@ +--- Channels --- + +As the emulation progresses, information is written in the PRV trace to record +the new states. The emulator has specific mechanism to handle the output of new +states in the PRV trace via channels. A channel stores an integer that +represents an state at a given point in time and corresponds to the value that +will be observed in the Paraver timeline. + + NOTE: In general, the emulator receives events, then performs a state + transition and the new state (or states) are written into the PRV file. + +There are two classes of channels: CPU and thread channels. Both CPU and threads +have the same fixed number of channels, given by the enumeration `enum chan`. + +For example the CHAN_OVNI_STATE of the thread stores the execution state of the +thread (running, paused ...). Whereas, the CPU channel CHAN_OVNI_NRTHREADS +records how many running threads a given CPU has. + +The channels are used in the following way: + +1) In the "pre" phase, the emulator modifies the state of the emulator based on +the new event. The channels are then updated accordingly in this phase, for +example when a thread goes from running to paused it must update the +CHAN_OVNI_STATE channel of the thread by also the CHAN_OVNI_NRTHREADS channel of +the CPU. + +2) In the "emit" phase, the emulator calls the chan_emit() method on those channels +that have been modified. Those have the dirty attribute set to 1. + +3) The optional "post" phase is used to perform some operations before the next +event is loaded, but is not commonly used. + +Then the emulator then loads the next event and repeats the process again. + +-- Disabling and enabling channels -------------------------------------------- + +Some channels provide information that only makes sense in some conditions. For +example, the CPU channel CHAN_OVNI_TID tracks the TID of the thread currently +running in the CPU. When there is no thread running or there are multiple +threads running in the same CPU, this channel cannot output valid information. + +For those cases, the channels can be enabled or disabled as to only provide +information when it is necessary. When a channel is disabled, it will emit the +value stored in `badst` which by default is set to 0. + +Notice that if a channel was in a given state A, and was disabled, it must emit +the new state is 0. When the channel is enabled again, it will emit again the +state A. + +-- Thread tracking channels ---------------------------------------------------------- + +Regarding thread channels, there are two common conditions that cause the +channels to become disabled. When the thread is no longer running, and then the +thread is not active. + +For those cases, the thread channels can be configured to automatically be +enabled or disabled, following the execution state of the thread. The tracking +mode specifies how the tracking must be done: + +- CHAN_TRACK_NONE: nothing to track +- CHAN_TRACK_RUNNING_TH: enable the channel only if the thread is running +- CHAN_TRACK_ACTIVE_TH: enable the channel only if the thread is running, + cooling or warming. + +This mechanism removes the complexity of detecting when a thread stops running, +to update a channel of a given module. As the thread state changes as handled by +the emu_ovni.c module only. + +-- CPU tracking channels ------------------------------------------------------ + +Similarly, CPU channels can also be configured to track the execution state of +the threads. They become disabled when the tracking condition is not met, but +also copy the state of the tracking thread channel. + +They share the same tracking modes, but their behavior is slightly different: + +In the case of tracking the running thread, if the CPU has more than one thread +running, the channel will always output the error state ST_TOO_MANY_TH. + +If is has no threads running, will be disabled and emit a 0 state by default. + +Otherwise, it will emit the same value as the running thread. If the thread +channel is disabled, it will emit a ST_BAD error state. + +Regarding the active thread tracking mode, the CPU channels behave similarly, +but with the active threads instead of running ones. + +The CPU tracking mechanism simplify the process of updating CPU channels, as +the modules don't need to worry about the execution model. Only the channels +need to be configured to follow the proper execution state. + +-- Channel state modes -------------------------------------------------------- + +The channels can be updated in three ways: + +1) A fixed state can be set to the channel using chan_set(), which overrides the +previous state. + +2) The new state can be stored in a stack with chan_push() and chan_pop(), to +remember the history of the previous states. The emitted event will be the one +on the top. + +3) Using a punctual event. + +Setting the channel state is commonly used to track quantities such as the +number of threads running per CPU. While the stack mode is commonly used to +track functions or sections of code delimited with enter and exit events, which +can call an return to the previous state. + +An example program may be instrumented like this: + + int bar() { + instr("Xb["); + ... + instr("Xb]"); + } + + int foo() { + instr("Xf["); + bar(); + instr("Xf]"); + } + +Then, in the emulator, when processing the events "Xf[" and "Xf]", we could track +of the state as follows: + + int hook_pre_foo(struct ovni_chan *chan, int value) { + switch(value) { + case '[': chan_push(chan, 2); break; + case ']': chan_pop(chan, 2); break; + default: break; + } + } + + int hook_pre_bar(struct ovni_chan *chan, int value) { + switch(value) { + case '[': chan_push(chan, 1); break; + case ']': chan_pop(chan, 1); break; + default: break; + } + } + +The channel will emit the following sequence of states: 0, 1, 2, 1, 0. + +Notice that the chan_pop() function uses the same state being pop()'ed as +argument. The function checks that the stack contains the expected state, +forcing the emulator to always receive a matching pair of enter and exit events. + +-- Punctual events ------------------------------------------------------------ + +There are some conditions that are better mapped to events rather than to state +transitions. For those cases, the channels provide punctual events which are +emitted as a state than only has 1 ns of duration. + +When a channel is configured to emit a punctual event with chan_ev(), it will +first output the new state at the current time minus 1 ns, then restore the +previous channel state and emit it at the current time.