| 1 | #ifndef STATE_H |
| 2 | #define STATE_H |
| 3 | |
| 4 | #include <glib.h> |
| 5 | #include <lttv/processTrace.h> |
| 6 | |
| 7 | /* The operating system state kept during the trace analysis |
| 8 | contains a subset of the real operating system state, |
| 9 | sufficient for the analysis, and possibly organized quite differently. |
| 10 | |
| 11 | The state information is added to LttvTracesetContext, LttvTraceContext |
| 12 | and LttvTracefileContext objects, used by processTrace, through |
| 13 | subtyping. The context objects already reflect the multiple tracefiles |
| 14 | (one per cpu) per trace and multiple traces per trace set. The state |
| 15 | objects defined here simply add fields to the relevant context objects. |
| 16 | |
| 17 | There is no traceset specific state yet. It may eventually contains such |
| 18 | things as clock differences over time. |
| 19 | |
| 20 | The trace state currently consists in a process table. |
| 21 | |
| 22 | The tracefile level state relates to the associated cpu. It contains the |
| 23 | position of the current event in the tracefile (since the state depends on |
| 24 | which events have been processed) and a pointer to the current process, |
| 25 | in the process table, being run on that cpu. |
| 26 | |
| 27 | For each process in the process table, various informations such as exec |
| 28 | file name, pid, ppid and creation time are stored. Each process state also |
| 29 | contains an execution mode stack (e.g. irq within system call, called |
| 30 | from user mode). */ |
| 31 | |
| 32 | typedef struct _LttvTracesetState LttvTracesetState; |
| 33 | typedef struct _LttvTracesetStateClass LttvTracesetStateClass; |
| 34 | |
| 35 | typedef struct _LttvTraceState LttvTraceState; |
| 36 | typedef struct _LttvTraceStateClass LttvTraceStateClass; |
| 37 | |
| 38 | typedef struct _LttvTracefileState LttvTracefileState; |
| 39 | typedef struct _LttvTracefileStateClass LttvTracefileStateClass; |
| 40 | |
| 41 | void lttv_state_add_event_hooks(LttvTracesetState *self); |
| 42 | |
| 43 | void lttv_state_remove_event_hooks(LttvTracesetState *self); |
| 44 | |
| 45 | void lttv_state_save_add_event_hooks(LttvTracesetState *self); |
| 46 | |
| 47 | void lttv_state_save_remove_event_hooks(LttvTracesetState *self); |
| 48 | |
| 49 | void lttv_state_restore_closest_state(LttvTracesetState *self, LttTime t); |
| 50 | |
| 51 | /* The LttvProcessState structure defines the current state for each process. |
| 52 | A process can make system calls (in some rare cases nested) and receive |
| 53 | interrupts/faults. For instance, a process may issue a system call, |
| 54 | generate a page fault while reading an argument from user space, and |
| 55 | get caught by an interrupt. To represent these nested states, an |
| 56 | execution mode stack is maintained. The stack bottom is normal user mode |
| 57 | and the top of stack is the current execution mode. |
| 58 | |
| 59 | The execution mode stack tells about the process status, execution mode and |
| 60 | submode (interrupt, system call or IRQ number). All these could be |
| 61 | defined as enumerations but may need extensions (e.g. new process state). |
| 62 | GQuark are thus used. They are as easy to manipulate as integers but have |
| 63 | a string associated, just like enumerations. |
| 64 | |
| 65 | The execution mode is one of "user mode", "kernel thread", "system call", |
| 66 | "interrupt request", "fault". */ |
| 67 | |
| 68 | typedef GQuark LttvExecutionMode; |
| 69 | |
| 70 | extern LttvExecutionMode |
| 71 | LTTV_STATE_USER_MODE, |
| 72 | LTTV_STATE_SYSCALL, |
| 73 | LTTV_STATE_TRAP, |
| 74 | LTTV_STATE_IRQ, |
| 75 | LTTV_STATE_MODE_UNKNOWN; |
| 76 | |
| 77 | |
| 78 | /* The submode number depends on the execution mode. For user mode or kernel |
| 79 | thread, which are the normal mode (execution mode stack bottom), |
| 80 | it is set to "none". For interrupt requests, faults and system calls, |
| 81 | it is set respectively to the interrupt name (e.g. "timer"), fault name |
| 82 | (e.g. "page fault"), and system call name (e.g. "select"). */ |
| 83 | |
| 84 | typedef GQuark LttvExecutionSubmode; |
| 85 | |
| 86 | extern LttvExecutionSubmode |
| 87 | LTTV_STATE_SUBMODE_NONE, |
| 88 | LTTV_STATE_SUBMODE_UNKNOWN; |
| 89 | |
| 90 | /* The process status is one of "running", "wait-cpu" (runnable), or "wait-*" |
| 91 | where "*" describes the resource waited for (e.g. timer, process, |
| 92 | disk...). */ |
| 93 | |
| 94 | typedef GQuark LttvProcessStatus; |
| 95 | |
| 96 | extern LttvProcessStatus |
| 97 | LTTV_STATE_UNNAMED, |
| 98 | LTTV_STATE_WAIT_FORK, |
| 99 | LTTV_STATE_WAIT_CPU, |
| 100 | LTTV_STATE_EXIT, |
| 101 | LTTV_STATE_WAIT, |
| 102 | LTTV_STATE_RUN; |
| 103 | |
| 104 | |
| 105 | typedef struct _LttvExecutionState { |
| 106 | LttvExecutionMode t; |
| 107 | LttvExecutionSubmode n; |
| 108 | LttTime entry; |
| 109 | LttTime change; |
| 110 | LttvProcessStatus s; |
| 111 | } LttvExecutionState; |
| 112 | |
| 113 | |
| 114 | typedef struct _LttvProcessState { |
| 115 | guint pid; |
| 116 | guint ppid; |
| 117 | LttTime creation_time; |
| 118 | GQuark name; |
| 119 | GQuark pid_time; |
| 120 | GArray *execution_stack; /* Array of LttvExecutionState */ |
| 121 | LttvExecutionState *state; /* Top of interrupt stack */ |
| 122 | /* opened file descriptors, address map?... */ |
| 123 | } LttvProcessState; |
| 124 | |
| 125 | |
| 126 | LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs, guint pid); |
| 127 | |
| 128 | |
| 129 | /* The LttvTracesetState, LttvTraceState and LttvTracefileState types |
| 130 | inherit from the corresponding Context objects defined in processTrace. */ |
| 131 | |
| 132 | #define LTTV_TRACESET_STATE_TYPE (lttv_traceset_state_get_type ()) |
| 133 | #define LTTV_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATE_TYPE, LttvTracesetState)) |
| 134 | #define LTTV_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass)) |
| 135 | #define LTTV_IS_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATE_TYPE)) |
| 136 | #define LTTV_IS_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATE_TYPE)) |
| 137 | #define LTTV_TRACESET_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass)) |
| 138 | |
| 139 | struct _LttvTracesetState { |
| 140 | LttvTracesetContext parent; |
| 141 | }; |
| 142 | |
| 143 | struct _LttvTracesetStateClass { |
| 144 | LttvTracesetContextClass parent; |
| 145 | }; |
| 146 | |
| 147 | GType lttv_traceset_state_get_type (void); |
| 148 | |
| 149 | |
| 150 | #define LTTV_TRACE_STATE_TYPE (lttv_trace_state_get_type ()) |
| 151 | #define LTTV_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATE_TYPE, LttvTraceState)) |
| 152 | #define LTTV_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass)) |
| 153 | #define LTTV_IS_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATE_TYPE)) |
| 154 | #define LTTV_IS_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATE_TYPE)) |
| 155 | #define LTTV_TRACE_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass)) |
| 156 | |
| 157 | struct _LttvTraceState { |
| 158 | LttvTraceContext parent; |
| 159 | |
| 160 | GHashTable *processes; /* LttvProcessState objects indexed by pid */ |
| 161 | guint nb_event, save_interval; |
| 162 | /* Block/char devices, locks, memory pages... */ |
| 163 | GQuark *eventtype_names; |
| 164 | GQuark *syscall_names; |
| 165 | GQuark *trap_names; |
| 166 | GQuark *irq_names; |
| 167 | }; |
| 168 | |
| 169 | struct _LttvTraceStateClass { |
| 170 | LttvTraceContextClass parent; |
| 171 | |
| 172 | void (*state_save) (LttvTraceState *self, LttvAttribute *container); |
| 173 | void (*state_restore) (LttvTraceState *self, LttvAttribute *container); |
| 174 | void (*state_saved_free) (LttvTraceState *self, LttvAttribute *container); |
| 175 | }; |
| 176 | |
| 177 | GType lttv_trace_state_get_type (void); |
| 178 | |
| 179 | void lttv_state_save(LttvTraceState *self, LttvAttribute *container); |
| 180 | |
| 181 | void lttv_state_restore(LttvTraceState *self, LttvAttribute *container); |
| 182 | |
| 183 | void lttv_state_saved_state_free(LttvTraceState *self, |
| 184 | LttvAttribute *container); |
| 185 | |
| 186 | |
| 187 | #define LTTV_TRACEFILE_STATE_TYPE (lttv_tracefile_state_get_type ()) |
| 188 | #define LTTV_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileState)) |
| 189 | #define LTTV_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass)) |
| 190 | #define LTTV_IS_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATE_TYPE)) |
| 191 | #define LTTV_IS_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATE_TYPE)) |
| 192 | #define LTTV_TRACEFILE_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass)) |
| 193 | |
| 194 | struct _LttvTracefileState { |
| 195 | LttvTracefileContext parent; |
| 196 | |
| 197 | LttvProcessState *process; |
| 198 | GQuark cpu_name; |
| 199 | guint saved_position; |
| 200 | }; |
| 201 | |
| 202 | struct _LttvTracefileStateClass { |
| 203 | LttvTracefileContextClass parent; |
| 204 | }; |
| 205 | |
| 206 | GType lttv_tracefile_state_get_type (void); |
| 207 | |
| 208 | |
| 209 | #endif // STATE_H |