#include <config.h>
#endif
+#include <glib.h>
#include <lttv/lttv.h>
#include <lttv/module.h>
#include <lttv/state.h>
#include <ltt/trace.h>
#include <ltt/event.h>
#include <ltt/ltt.h>
+#include <ltt/marker-desc.h>
#include <stdio.h>
#include <string.h>
LTT_FIELD_MINOR,
LTT_FIELD_MAJOR,
LTT_FIELD_OPERATION,
- LTT_FIELD_ACTION,
- LTT_FIELD_NUM;
+ LTT_FIELD_ACTION;
LttvExecutionMode
LTTV_STATE_MODE_UNKNOWN,
LTTV_STATE_NAME_TABLES,
LTTV_STATE_TRACE_STATE_USE_COUNT,
LTTV_STATE_RESOURCE_CPUS,
+ LTTV_STATE_RESOURCE_CPUS_COUNT,
LTTV_STATE_RESOURCE_IRQS,
LTTV_STATE_RESOURCE_BLKDEVS;
g_hash_table_destroy(usertraces);
}
-
+gboolean rettrue(gpointer key, gpointer value, gpointer user_data)
+{
+ return TRUE;
+}
static void
restore_init_state(LttvTraceState *self)
/* reset bdev states */
g_hash_table_foreach(self->bdev_states, bdevstate_free_cb, NULL);
- g_hash_table_steal_all(self->bdev_states);
+ //g_hash_table_steal_all(self->bdev_states);
+ g_hash_table_foreach_steal(self->bdev_states, rettrue, NULL);
#if 0
nb_tracefile = self->parent.tracefiles->len;
guint i;
for(i=0; i<n; i++) {
- g_array_free(states[i].mode_stack, FALSE);
+ g_array_free(states[i].mode_stack, TRUE);
}
g_free(states);
guint i;
for(i=0; i<n; i++) {
- g_array_free(states[i].mode_stack, FALSE);
+ g_array_free(states[i].mode_stack, TRUE);
}
g_free(states);
static void bdevstate_free(LttvBdevState *bds)
{
- g_array_free(bds->mode_stack, FALSE);
+ g_array_free(bds->mode_stack, TRUE);
g_free(bds);
}
/* save the cpu state */
{
+ value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_CPUS_COUNT,
+ LTTV_UINT);
+ *(value.v_uint) = nb_cpus;
+
value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_CPUS,
LTTV_POINTER);
*(value.v_pointer) = lttv_state_copy_cpu_states(self->cpu_states, nb_cpus);
static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
{
- guint i, nb_tracefile, nb_cpus;
+ guint i, nb_tracefile, nb_cpus, nb_irqs;
LttvTracefileState *tfcs;
lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
/* Free running processes array */
- nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
type = lttv_attribute_get_by_name(container, LTTV_STATE_RUNNING_PROCESS,
&value);
g_assert(type == LTTV_POINTER);
running_process = *(value.v_pointer);
g_free(running_process);
+ /* free cpu resource states */
+ type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_CPUS_COUNT, &value);
+ g_assert(type == LTTV_UINT);
+ nb_cpus = *value.v_uint;
+ type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_CPUS, &value);
+ g_assert(type == LTTV_POINTER);
+ lttv_state_free_cpu_states(*(value.v_pointer), nb_cpus);
+
+ /* free irq resource states */
+ nb_irqs = self->nb_irqs;
+ type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_IRQS, &value);
+ g_assert(type == LTTV_POINTER);
+ lttv_state_free_irq_states(*(value.v_pointer), nb_irqs);
+
+ /* free the blkdev states */
+ type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_BLKDEVS, &value);
+ g_assert(type == LTTV_POINTER);
+ lttv_state_free_blkdev_hashtable(*(value.v_pointer));
+
nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 1);
if(!lttv_trace_find_hook(tcs->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_SYSCALL_ENTRY,
FIELD_ARRAY(LTT_FIELD_SYSCALL_ID),
NULL, NULL, &hooks)) {
// }
// }
+ name_tables->nb_syscalls = 256;
name_tables->syscall_names = g_new(GQuark, 256);
for(i = 0 ; i < 256 ; i++) {
g_string_printf(fe_name, "syscall %d", i);
lttv_trace_hook_remove_all(&hooks);
if(!lttv_trace_find_hook(tcs->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_TRAP_ENTRY,
FIELD_ARRAY(LTT_FIELD_TRAP_ID),
NULL, NULL, &hooks)) {
lttv_trace_hook_remove_all(&hooks);
if(!lttv_trace_find_hook(tcs->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_IRQ_ENTRY,
FIELD_ARRAY(LTT_FIELD_IRQ_ID),
NULL, NULL, &hooks)) {
* the parent waits for its child terminaison, but may also happen in special
* cases in the child's exit : when the parent ignores its children SIGCCHLD or
* has the flag SA_NOCLDWAIT. It can also happen when the child is part
- * of a killed thread ground, but isn't the leader.
+ * of a killed thread group, but isn't the leader.
*/
static void exit_process(LttvTracefileState *tfs, LttvProcessState *process)
{
process->state->change = s->parent.timestamp;
}
- if(state_out == 32 || state_out == 128)
+ if(state_out == 32 || state_out == 64)
exit_process(s, process); /* EXIT_DEAD || TASK_DEAD */
/* see sched.h for states */
}
/* update cpu status */
if(pid_in == 0)
+ /* going to idle task */
cpu_set_base_mode(s->cpu_state, LTTV_CPU_IDLE);
- else
+ else {
+ /* scheduling a real task.
+ * we must be careful here:
+ * if we just schedule()'ed to a process that is
+ * in a trap, we must put the cpu in trap mode
+ */
cpu_set_base_mode(s->cpu_state, LTTV_CPU_BUSY);
+ if(process->state->t == LTTV_STATE_TRAP)
+ cpu_push_mode(s->cpu_state, LTTV_CPU_TRAP);
+ }
return FALSE;
}
f = lttv_trace_get_hook_field(th, 3);
type = ltt_enum_string_get(f, ltt_event_get_unsigned(e, f));
+ //FIXME: type is rarely used, enum must match possible types.
+
/* mode */
f = lttv_trace_get_hook_field(th, 4);
mode = ltt_enum_string_get(f,ltt_event_get_unsigned(e, f));
//hn = 0;
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_SYSCALL_ENTRY,
FIELD_ARRAY(LTT_FIELD_SYSCALL_ID),
syscall_entry, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_SYSCALL_EXIT,
NULL,
syscall_exit, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_TRAP_ENTRY,
FIELD_ARRAY(LTT_FIELD_TRAP_ID),
trap_entry, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_TRAP_EXIT,
NULL,
trap_exit, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_IRQ_ENTRY,
FIELD_ARRAY(LTT_FIELD_IRQ_ID),
irq_entry, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_IRQ_EXIT,
NULL,
irq_exit, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_SOFT_IRQ_ENTRY,
FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID),
soft_irq_entry, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_SOFT_IRQ_EXIT,
NULL,
soft_irq_exit, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_SCHED_SCHEDULE,
FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID,
LTT_FIELD_PREV_STATE),
schedchange, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_PROCESS_FORK,
FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID,
LTT_FIELD_CHILD_TGID),
process_fork, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL_ARCH,
LTT_EVENT_KTHREAD_CREATE,
FIELD_ARRAY(LTT_FIELD_PID),
process_kernel_thread, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_PROCESS_EXIT,
FIELD_ARRAY(LTT_FIELD_PID),
process_exit, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL,
LTT_EVENT_PROCESS_FREE,
FIELD_ARRAY(LTT_FIELD_PID),
process_free, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_FS,
LTT_EVENT_EXEC,
FIELD_ARRAY(LTT_FIELD_FILENAME),
process_exec, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_USER_GENERIC,
LTT_EVENT_THREAD_BRAND,
FIELD_ARRAY(LTT_FIELD_NAME),
thread_brand, NULL, &hooks);
/* statedump-related hooks */
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_LIST,
LTT_EVENT_PROCESS_STATE,
FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE,
enum_process_state, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_LIST,
LTT_EVENT_STATEDUMP_END,
NULL,
statedump_end, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_LIST,
LTT_EVENT_LIST_INTERRUPT,
- FIELD_ARRAY(LTT_FIELD_ACTION, LTT_FIELD_NUM),
+ FIELD_ARRAY(LTT_FIELD_ACTION, LTT_FIELD_IRQ_ID),
enum_interrupt, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_BLOCK,
LTT_EVENT_REQUEST_ISSUE,
FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION),
bdev_request_issue, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_BLOCK,
LTT_EVENT_REQUEST_COMPLETE,
FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION),
bdev_request_complete, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_USER_GENERIC,
LTT_EVENT_FUNCTION_ENTRY,
FIELD_ARRAY(LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE),
function_entry, NULL, &hooks);
lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_USER_GENERIC,
LTT_EVENT_FUNCTION_EXIT,
FIELD_ARRAY(LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE),
function_exit, NULL, &hooks);
static void module_init()
{
- LTTV_STATE_UNNAMED = g_quark_from_string("UNNAMED");
- LTTV_STATE_UNBRANDED = g_quark_from_string("UNBRANDED");
+ LTTV_STATE_UNNAMED = g_quark_from_string("");
+ LTTV_STATE_UNBRANDED = g_quark_from_string("");
LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("MODE_UNKNOWN");
LTTV_STATE_USER_MODE = g_quark_from_string("USER_MODE");
LTTV_STATE_SYSCALL = g_quark_from_string("SYSCALL");
LTTV_STATE_TRACE_STATE_USE_COUNT =
g_quark_from_string("trace_state_use_count");
LTTV_STATE_RESOURCE_CPUS = g_quark_from_string("cpu resource states");
+ LTTV_STATE_RESOURCE_CPUS = g_quark_from_string("cpu count");
LTTV_STATE_RESOURCE_IRQS = g_quark_from_string("irq resource states");
LTTV_STATE_RESOURCE_BLKDEVS = g_quark_from_string("blkdevs resource states");
LTT_EVENT_TRAP_EXIT = g_quark_from_string("trap_exit");
LTT_EVENT_IRQ_ENTRY = g_quark_from_string("irq_entry");
LTT_EVENT_IRQ_EXIT = g_quark_from_string("irq_exit");
- LTT_EVENT_SOFT_IRQ_ENTRY = g_quark_from_string("soft_irq_entry");
- LTT_EVENT_SOFT_IRQ_EXIT = g_quark_from_string("soft_irq_exit");
+ LTT_EVENT_SOFT_IRQ_ENTRY = g_quark_from_string("softirq_entry");
+ LTT_EVENT_SOFT_IRQ_EXIT = g_quark_from_string("softirq_exit");
LTT_EVENT_SCHED_SCHEDULE = g_quark_from_string("sched_schedule");
LTT_EVENT_PROCESS_FORK = g_quark_from_string("process_fork");
LTT_EVENT_KTHREAD_CREATE = g_quark_from_string("kthread_create");
LTT_FIELD_MINOR = g_quark_from_string("minor");
LTT_FIELD_OPERATION = g_quark_from_string("direction");
LTT_FIELD_ACTION = g_quark_from_string("action");
- LTT_FIELD_NUM = g_quark_from_string("num");
LTTV_CPU_UNKNOWN = g_quark_from_string("unknown");
LTTV_CPU_IDLE = g_quark_from_string("idle");