precomputed states almost ok, needs testing
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Sat, 9 Sep 2006 00:57:58 +0000 (00:57 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Sat, 9 Sep 2006 00:57:58 +0000 (00:57 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@2088 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/lttv/lttv/state.c
ltt/branches/poly/lttv/lttv/state.h
ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c
ltt/branches/poly/lttv/modules/gui/detailedevents/events.c
ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.c
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c
ltt/branches/poly/lttv/modules/text/precomputeState.c

index 7770e9abec506b45704483551fc1ad2e5d1ffdc9..914ab728b86cc032185a0d4464568b933a0fc03d 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+/* Comment :
+ * Mathieu Desnoyers
+ * usertrace is there only to be able to update the current CPU of the
+ * usertraces when there is a schedchange. it is a way to link the ProcessState
+ * to the associated usertrace. Link only created upon thread creation.
+ *
+ * The cpu id is necessary : it gives us back the current ProcessState when we
+ * are considering data from the usertrace.
+ */
+
 #define PREALLOCATED_EXECUTION_STACK 10
 
 /* Facilities Quarks */
@@ -143,6 +153,8 @@ static void free_saved_state(LttvTraceState *tcs);
 
 static void lttv_state_free_process_table(GHashTable *processes);
 
+static void lttv_trace_states_read_raw(LttvTraceState *tcs, FILE *fp,
+                       GPtrArray *quarktable);
 
 void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
 {
@@ -280,6 +292,82 @@ static void free_usertrace_key(gpointer data)
   g_free(data);
 }
 
+#define MAX_STRING_LEN 4096
+
+static void
+state_load_saved_states(LttvTraceState *tcs)
+{
+  FILE *fp;
+  GPtrArray *quarktable;
+  char *trace_path;
+  char path[PATH_MAX];
+  guint count;
+  guint i;
+  tcs->has_precomputed_states = FALSE;
+  GQuark q;
+  gchar *string;
+  gint hdr;
+  gchar buf[MAX_STRING_LEN];
+  guint len;
+
+  trace_path = g_quark_to_string(ltt_trace_name(tcs->parent.t));
+  strncpy(path, trace_path, PATH_MAX-1);
+  count = strnlen(trace_path, PATH_MAX-1);
+  // quarktable : open, test
+  strncat(path, "/precomputed/quarktable", PATH_MAX-count-1);
+  fp = fopen(path, "r");
+  if(!fp) return;
+  quarktable = g_ptr_array_sized_new(4096);
+  
+  /* Index 0 is null */
+  hdr = fgetc(fp);
+  if(hdr == EOF) return;
+  g_assert(hdr == HDR_QUARKS);
+  q = 1;
+  do {
+    hdr = fgetc(fp);
+    if(hdr == EOF) break;
+    g_assert(hdr == HDR_QUARK);
+    g_ptr_array_set_size(quarktable, q+1);
+    i=0;
+    while(1) {
+      fread(&buf[i], sizeof(gchar), 1, fp);
+      if(buf[i] == '\0' || feof(fp)) break;
+      i++;
+    }
+    len = strnlen(buf, MAX_STRING_LEN-1);
+    g_ptr_array_index (quarktable, q) = g_new(gchar, len+1);
+    strncpy(g_ptr_array_index (quarktable, q), buf, len+1);
+    q++;
+  } while(1);
+
+  fclose(fp);
+  // saved_states : open, test
+  strncpy(path, trace_path, PATH_MAX-1);
+  count = strnlen(trace_path, PATH_MAX-1);
+  strncat(path, "/precomputed/states", PATH_MAX-count-1);
+  fp = fopen(path, "r");
+  if(!fp) return;
+
+  hdr = fgetc(fp);
+  if(hdr != HDR_TRACE) goto end;
+
+  lttv_trace_states_read_raw(tcs, fp, quarktable);
+
+  tcs->has_precomputed_states = TRUE;
+
+end:
+  fclose(fp);
+
+  /* Free the quarktable */
+  for(i=0; i<quarktable->len; i++) {
+    string = g_ptr_array_index (quarktable, i);
+    g_free(string);
+  }
+  g_ptr_array_free(quarktable, TRUE);
+  return;
+}
+
 static void
 init(LttvTracesetState *self, LttvTraceset *ts)
 {
@@ -324,21 +412,6 @@ init(LttvTracesetState *self, LttvTraceset *ts)
                                           LttvTracefileContext*, j));
       tfcs->tracefile_name = ltt_tracefile_name(tfcs->parent.tf);
       tfcs->cpu = ltt_tracefile_cpu(tfcs->parent.tf);
-#if 0    
-      if(ltt_tracefile_tid(tfcs->parent.tf) != 0) {
-        /* It's a Usertrace */
-        LttvProcessState *process;
-        LttTime timestamp = 
-          ltt_interpolate_time_from_tsc(tfcs->parent.tf,
-              ltt_tracefile_creation(tfcs->parent.tf));
-        process = lttv_state_find_process_or_create(
-                        tcs,
-                        0, ltt_tracefile_tid(tfcs->parent.tf),
-                        &timestamp);
-        process->usertrace = tfcs;
-      }
-    }
-#endif //0
       if(ltt_tracefile_tid(tfcs->parent.tf) != 0) {
         /* It's a Usertrace */
         guint tid = ltt_tracefile_tid(tfcs->parent.tf);
@@ -357,6 +430,8 @@ init(LttvTracesetState *self, LttvTraceset *ts)
       }
     }
 
+    /* See if the trace has saved states */
+    state_load_saved_states(tcs);
   }
 }
 
@@ -579,6 +654,7 @@ static void write_process_state_raw(gpointer key, gpointer value,
     fwrite(&es->s, sizeof(es->s), 1, fp);
     fwrite(&es->entry, sizeof(es->entry), 1, fp);
     fwrite(&es->change, sizeof(es->change), 1, fp);
+    fwrite(&es->cum_cpu_time, sizeof(es->cum_cpu_time), 1, fp);
 #if 0
     fprintf(fp, "    <ES MODE=\"%s\" SUBMODE=\"%s\" ENTRY_S=%lu ENTRY_NS=%lu",
       g_quark_to_string(es->t), g_quark_to_string(es->n),
@@ -677,17 +753,19 @@ void lttv_state_write_raw(LttvTraceState *self, LttTime t, FILE *fp)
 /* Read process state from a file */
 
 /* Called because a HDR_PROCESS was found */
-static void read_process_state_raw(LttvTraceState *self, FILE *fp)
+static void read_process_state_raw(LttvTraceState *self, FILE *fp,
+                       GPtrArray *quarktable)
 {
   LttvExecutionState *es;
   LttvProcessState *process, *parent_process;
   LttvProcessState tmp;
+  GQuark tmpq;
 
   guint i;
-  guint64 address;
+  guint64 *address;
   guint cpu;
 
-  /* TOOD : check return value */
+  /* TODO : check return value */
   fread(&tmp.type, sizeof(tmp.type), 1, fp);
   fread(&tmp.name, sizeof(tmp.name), 1, fp);
   fread(&tmp.brand, sizeof(tmp.brand), 1, fp);
@@ -704,28 +782,58 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp)
     /* We must link to the parent */
     parent_process = lttv_state_find_process_or_create(self, ANY_CPU, tmp.ppid,
         &ltt_time_zero);
-    process = lttv_state_find_process_or_create(self, ANY_CPU, tmp.pid,
-        &tmp.insertion_time);
+    process = lttv_state_find_process_or_create(self, tmp.cpu, tmp.pid,
+        &tmp.creation_time);
   }
+  process->insertion_time = tmp.insertion_time;
   process->creation_time = tmp.creation_time;
-  process->type = tmp.type;
-  process->brand = tmp.brand;
+  process->type = g_quark_from_string(
+    (gchar*)g_ptr_array_index(quarktable, tmp.type));
   process->tgid = tmp.tgid;
-  process->cpu = tmp.cpu;
+  process->ppid = tmp.ppid;
+  process->brand = g_quark_from_string(
+    (gchar*)g_ptr_array_index(quarktable, tmp.brand));
+  process->name = 
+    g_quark_from_string((gchar*)g_ptr_array_index(quarktable, tmp.name));
 
   do {
     if(feof(fp) || ferror(fp)) goto end_loop;
 
     gint hdr = fgetc(fp);
+    if(hdr == EOF) goto end_loop;
 
     switch(hdr) {
       case HDR_ES:
+        process->execution_stack =
+          g_array_set_size(process->execution_stack,
+                           process->execution_stack->len + 1);
+        es = &g_array_index(process->execution_stack, LttvExecutionState,
+                process->execution_stack->len-1);
+
+        fread(&es->t, sizeof(es->t), 1, fp);
+        es->t = g_quark_from_string(
+           (gchar*)g_ptr_array_index(quarktable, es->t));
+        fread(&es->n, sizeof(es->n), 1, fp);
+        es->n = g_quark_from_string(
+           (gchar*)g_ptr_array_index(quarktable, es->n));
+        fread(&es->s, sizeof(es->s), 1, fp);
+        es->s = g_quark_from_string(
+           (gchar*)g_ptr_array_index(quarktable, es->s));
+        fread(&es->entry, sizeof(es->entry), 1, fp);
+        fread(&es->change, sizeof(es->change), 1, fp);
+        fread(&es->cum_cpu_time, sizeof(es->cum_cpu_time), 1, fp);
         break;
       case HDR_USER_STACK:
+        process->user_stack = g_array_set_size(process->user_stack,
+                              process->user_stack->len + 1);
+        address = &g_array_index(process->user_stack, guint64,
+                                 process->user_stack->len-1);
+        fread(address, sizeof(address), 1, fp);
+       process->current_function = *address;
         break;
       case HDR_USERTRACE:
-        break;
-      case HDR_PROCESS_STATE:
+        fread(&tmpq, sizeof(tmpq), 1, fp);
+        fread(&process->usertrace->cpu, sizeof(process->usertrace->cpu), 1, fp);
         break;
       default:
         ungetc(hdr, fp);
@@ -739,11 +847,10 @@ end_loop:
 
 /* Called because a HDR_PROCESS_STATE was found */
 /* Append a saved state to the trace states */
-void lttv_state_read_raw(LttvTraceState *self, FILE *fp)
+void lttv_state_read_raw(LttvTraceState *self, FILE *fp, GPtrArray *quarktable)
 {
   guint i, nb_tracefile, nb_block, offset;
   guint64 tsc;
-  LttTracefile *tf;
   LttvTracefileState *tfcs;
 
   LttEventPosition *ep;
@@ -766,11 +873,12 @@ void lttv_state_read_raw(LttvTraceState *self, FILE *fp)
   do {
     if(feof(fp) || ferror(fp)) goto end_loop;
     hdr = fgetc(fp);
+    if(hdr == EOF) goto end_loop;
 
     switch(hdr) {
       case HDR_PROCESS:
         /* Call read_process_state_raw */
-        read_process_state_raw(self, fp);
+        read_process_state_raw(self, fp, quarktable);
         break;
       case HDR_TRACEFILE:
       case HDR_TRACESET:
@@ -782,9 +890,8 @@ void lttv_state_read_raw(LttvTraceState *self, FILE *fp)
       case HDR_USERTRACE:
       case HDR_PROCESS_STATE:
       case HDR_CPU:
-        g_error("Error while parsing saved state file :"
-            " unexpected data header %d",
-            hdr);
+        ungetc(hdr, fp);
+       goto end_loop;
         break;
       default:
         g_error("Error while parsing saved state file : unknown data header %d",
@@ -822,7 +929,7 @@ end_loop:
       fread(&nb_block, sizeof(nb_block), 1, fp);
       fread(&offset, sizeof(offset), 1, fp);
       fread(&tsc, sizeof(tsc), 1, fp);
-      ltt_event_position_set(ep, tf, nb_block, offset, tsc);
+      ltt_event_position_set(ep, tfcs->parent.tf, nb_block, offset, tsc);
       gint ret = ltt_tracefile_seek_position(tfcs->parent.tf, ep);
       g_assert(ret == 0);
     }
@@ -845,18 +952,20 @@ end_loop:
 }
 
 /* Called when a HDR_TRACE is found */
-void lttv_trace_states_read_raw(LttvTraceState *tcs, FILE *fp)
+void lttv_trace_states_read_raw(LttvTraceState *tcs, FILE *fp,
+                       GPtrArray *quarktable)
 {
   int hdr;
 
   do {
     if(feof(fp) || ferror(fp)) goto end_loop;
     hdr = fgetc(fp);
+    if(hdr == EOF) goto end_loop;
 
     switch(hdr) {
       case HDR_PROCESS_STATE:
         /* Call read_process_state_raw */
-        lttv_state_read_raw(tcs, fp);
+        lttv_state_read_raw(tcs, fp, quarktable);
         break;
       case HDR_TRACEFILE:
       case HDR_TRACESET:
@@ -2368,6 +2477,8 @@ void lttv_state_add_event_hooks(LttvTracesetState *self)
   for(i = 0 ; i < nb_trace ; i++) {
     ts = (LttvTraceState *)self->parent.traces[i];
 
+    if(ts->has_precomputed_states) continue;
+
     /* Find the eventtype id for the following events and register the
        associated by id hooks. */
 
@@ -2543,6 +2654,9 @@ void lttv_state_remove_event_hooks(LttvTracesetState *self)
   nb_trace = lttv_traceset_number(traceset);
   for(i = 0 ; i < nb_trace ; i++) {
     ts = LTTV_TRACE_STATE(self->parent.traces[i]);
+
+    if(ts->has_precomputed_states) continue;
+
     lttv_attribute_find(ts->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
     hooks = *(val.v_pointer);
 
index f03138489f35b18bfe52a7024ef164563e6c02cb..1c20095f6780cc3f2cf239d2c3ea5ff0f092aa1c 100644 (file)
@@ -295,6 +295,7 @@ struct _LttvTraceState {
 
   /* Array of per cpu running process */
   LttvProcessState **running_process;
+  gboolean has_precomputed_states;
 };
 
 struct _LttvTraceStateClass {
index cac372ca16851411949d52be6aa0631c954649ff..65f47eec4a17c250afd1763f7d6a6cf784bc0a52 100644 (file)
@@ -122,6 +122,7 @@ static void request_background_data(ControlFlowData *control_flow_data)
   gint num_traces = lttv_traceset_number(tsc->ts);
   gint i;
   LttvTrace *trace;
+  LttvTraceState *tstate;
 
   LttvHooks *background_ready_hook = 
     lttv_hooks_new();
@@ -131,8 +132,10 @@ static void request_background_data(ControlFlowData *control_flow_data)
   
   for(i=0;i<num_traces;i++) {
     trace = lttv_traceset_get(tsc->ts, i);
+    tstate = LTTV_TRACE_STATE(tsc->traces[i]);
 
-    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE
+        && !tstate->has_precomputed_states) {
 
       if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
                                           trace) == FALSE) {
@@ -159,7 +162,7 @@ static void request_background_data(ControlFlowData *control_flow_data)
         control_flow_data->background_info_waiting++;
       }
     } else {
-      /* Data ready. Be its nature, this viewer doesn't need to have
+      /* Data ready. By its nature, this viewer doesn't need to have
        * its data ready hook called there, because a background
        * request is always linked with a redraw.
        */
index 41d72ae8bcb62f380f3687a598e47f47b2e8bde1..dcd2cf998460c1cedefbfef453782ba9d3e8b302 100644 (file)
@@ -556,6 +556,7 @@ static void request_background_data(EventViewerData *event_viewer_data)
   gint num_traces = lttv_traceset_number(tsc->ts);
   gint i;
   LttvTrace *trace;
+  LttvTraceState *tstate;
 
   LttvHooks *background_ready_hook = 
     lttv_hooks_new();
@@ -565,8 +566,10 @@ static void request_background_data(EventViewerData *event_viewer_data)
   
   for(i=0;i<num_traces;i++) {
     trace = lttv_traceset_get(tsc->ts, i);
+    tstate = LTTV_TRACE_STATE(tsc->traces[i]);
 
-    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE
+        && !tstate->has_precomputed_states) {
 
       if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
                                           trace) == FALSE) {
@@ -593,7 +596,7 @@ static void request_background_data(EventViewerData *event_viewer_data)
         event_viewer_data->background_info_waiting++;
       }
     } else {
-      /* Data ready. Be its nature, this viewer doesn't need to have
+      /* Data ready. By its nature, this viewer doesn't need to have
        * its data ready hook called htere, because a background
        * request is always linked with a redraw.
        */
index 96382c877399e9742a7b4c085bce572fd77df1bc..b315a3a413d43e4cc27a9784f223fa17aec5665b 100644 (file)
@@ -121,6 +121,7 @@ static void histo_request_background_data(HistoControlFlowData *histocontrol_flo
   gint num_traces = lttv_traceset_number(tsc->ts);
   gint i;
   LttvTrace *trace;
+  LttvTraceState *tstate;
 
   LttvHooks *histo_background_ready_hook = 
     lttv_hooks_new();
@@ -130,8 +131,10 @@ static void histo_request_background_data(HistoControlFlowData *histocontrol_flo
   
   for(i=0;i<num_traces;i++) {
     trace = lttv_traceset_get(tsc->ts, i);
+    tstate = LTTV_TRACE_STATE(tsc->traces[i]);
 
-    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE
+        && !tstate->has_precomputed_states) {
 
       if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
                                           trace) == FALSE) {
index f83c1f1e2bb7f87fff799c60cca3462c511da3a0..26cf0f3b6f260f14ce881482aed751f9fba4e8d5 100644 (file)
@@ -211,7 +211,6 @@ void lttvwindowtraces_add_trace(LttvTrace *trace)
   value = lttv_attribute_add(attribute,
                      LTTV_NOTIFY_CURRENT,
                      LTTV_POINTER);
 }
 
 /* Remove a trace from the global attributes */
index f9c2f31e0a8531dd8f737de8cf82c72d53332a0f..6853d44506060fdf45135c4bb8fc37fd4da69e08 100644 (file)
@@ -80,7 +80,8 @@ static gboolean write_traceset_header(void *hook_data, void *call_data)
   /* Print the trace set header */
   if(a_raw) {
   /* TODO : Write a header that will check for ILP size and endianness */
-    fputc(HDR_TRACESET, a_file);
+    //fputc(HDR_TRACESET, a_file);
+    g_assert(lttv_traceset_number(tc->ts) == 1); /* Only one trace in traceset */
   } else  {
     fprintf(a_file,"<TRACESET NUM_TRACES=%d/>\n", 
         lttv_traceset_number(tc->ts));
@@ -276,6 +277,6 @@ static void destroy()
 
 
 LTTV_MODULE("precomputeState", "Precompute states", \
-           "Precompute states in a trace, XML output.", \
+           "Precompute states in a trace, XML or binary output.", \
            init, destroy, "stats", "batchAnalysis", "option", "print")
 
This page took 0.033042 seconds and 4 git commands to generate.