fix for smp cfv, fix convert bug for 2.2 format, add task release event handling
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 24 Aug 2004 14:45:12 +0000 (14:45 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 24 Aug 2004 14:45:12 +0000 (14:45 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@834 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/ltt/convert/LinuxEvents.h
ltt/branches/poly/ltt/convert/convert.c
ltt/branches/poly/ltt/convert/core.xml
ltt/branches/poly/lttv/lttv/state.c
ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c
ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c
ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c
ltt/branches/poly/lttv/modules/gui/controlflow/processlist.h

index 49ae4a8bce0616fb713cb5ebd1d629b34da2d103..dfd0840c9b2ce96c329dcfabb7c70afabaea0138 100644 (file)
@@ -177,6 +177,8 @@ typedef struct _trace_soft_irq
 #define TRACE_PROCESS_WAIT        4  /* A wait occured */
 #define TRACE_PROCESS_SIGNAL      5  /* A signal has been sent */
 #define TRACE_PROCESS_WAKEUP      6  /* Wake up a process */
+#define TRACE_PROCESS_RELEASE     7  /* A task struct has been released */
+
 typedef struct _trace_process
 {
   uint8_t   event_sub_id;    /* Process event ID */
index 3f7bc1415fbf3d69d7ad9281a3409312f9899712..7b4403ea5b0df11c5b2571116a646cb654605a9c 100644 (file)
@@ -111,7 +111,7 @@ int main(int argc, char ** argv){
   int  ltt_major_version=0;
   int  ltt_minor_version=0;
   int  ltt_log_cpu;
-  guint ltt_trace_start_size;
+  guint ltt_trace_start_size = 0;
   char buf[BUFFER_SIZE];
   int i, k;
 
@@ -346,11 +346,11 @@ int main(int argc, char ** argv){
       ltt_trace_start_size = sizeof(trace_start_2_3);
     /* We do not use the flight recorder information for now, because we
      * never use the .proc file anyway */
-    } else {
-      ltt_trace_start_size = 0;
+    }
+    
+    if(ltt_trace_start_size == 0) 
       g_error("Minor version unknown : %hu. Supported minors : 2, 3",
                tStart->MinorVersion);
-    }
 
     block_size = ltt_block_size;//FIXME
     block_number = file_size/ltt_block_size;
index f54441fd7a33b4663bc75808832ff430dbe76b64..b1b23d6159b649ae37bf6bcabc58a09c6e81e9ed 100644 (file)
@@ -86,6 +86,7 @@
           <label name=TRACE_EV_PROCESS_WAIT/>
           <label name=TRACE_EV_PROCESS_SIGNAL/>
           <label name=TRACE_EV_PROCESS_WAKEUP/>
+          <label name=TRACE_EV_PROCESS_RELEASE/>
         </enum> 
       </field>
        
index 55bd4e056c23b1cbb4c2e0ed9ff5ece030c6db51..dc5c9806bfcadd63270d47828e2c7c8606b97f30 100644 (file)
@@ -1037,6 +1037,28 @@ static gboolean process_exit(LttvTraceHook *trace_hook, LttvTracefileState *s)
   return FALSE;
 }
 
+static gboolean process_release(LttvTraceHook *trace_hook,
+                                LttvTracefileState *s)
+{
+  LttField *f;
+  guint release_pid;
+  LttvProcessState *process;
+
+  /* PID of the process to release */
+  f = trace_hook->f2;
+  release_pid = ltt_event_get_unsigned(s->parent.e, f);
+
+  process = lttv_state_find_process(s, release_pid);
+
+  if(likely(process != NULL)) {
+    /* release_task is happening at kernel level : we can now safely release
+     * the data structure of the process */
+    exit_process(s, process);
+  }
+
+  return FALSE;
+}
+
 gboolean process(void *hook_data, void *call_data)
 {
   LttvTraceHook *trace_hook = (LttvTraceHook *)hook_data;
@@ -1051,6 +1073,8 @@ gboolean process(void *hook_data, void *call_data)
     return process_fork(trace_hook, s);
   } else if(sub_id == 3) {
     return process_exit(trace_hook, s);
+  } else if(sub_id == 7) {
+    return process_release(trace_hook, s);
   }
   return 0;
 }
index ebba555e368a19d49be22acf108aa397b842c356..4a1c9c94f7064d0867404724c05feae12fa703b0 100644 (file)
@@ -68,8 +68,8 @@ GdkColor drawing_colors[NUM_COLORS] =
   { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
   { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
   { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
-  { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_RUN_IRQ : red */
-  { 0, 0xA3FF, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
+  { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : red */
+  { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
   { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
   { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
   { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
index 3adb5bc1684cfd7f2513d4dc2fa2c0dac8abb4c6..b34e462b73aec74c697d49fb3349186ae5c9d9bf 100644 (file)
@@ -2432,6 +2432,169 @@ int before_process_hook(void *hook_data, void *call_data)
       }
     }
 
+  } else if(sub_id == 7) /* release */ {
+
+    guint pid;
+    {
+      LttField *f = ltt_event_field(e);
+      LttField *element;
+      element = ltt_field_member(f,1);
+      pid = ltt_event_get_long_unsigned(e,element);
+    }
+
+    /* Add process to process list (if not present) */
+    /* Don't care about the process if it's not in the state hash already :
+     * that means a process that has never done anything in the trace and
+     * unknown suddently gets destroyed : no state meaningful to show. */
+    LttvProcessState *process = lttv_state_find_process(tfs, pid);
+
+    if(process != NULL) {
+      LttTime birth;
+      guint pl_height = 0;
+      HashedProcessData *hashed_process_data = NULL;
+
+      ProcessList *process_list = control_flow_data->process_list;
+      
+      birth = process->creation_time;
+
+      /* Cannot use current process : this event happens on another process,
+       * action done by the parent. */
+      hashed_process_data = processlist_get_process_data(process_list,
+            pid,
+            process->last_cpu_index,
+            &birth,
+            tfc->t_context->index);
+      if(unlikely(hashed_process_data == NULL))
+      {
+        g_assert(pid == 0 || pid != process->ppid);
+        /* Process not present */
+        Drawing_t *drawing = control_flow_data->drawing;
+        const gchar *name = g_quark_to_string(process->name);
+        ProcessInfo *process_info;
+        processlist_add(process_list,
+            drawing,
+            pid,
+            process->last_cpu_index,
+            process->ppid,
+            &birth,
+            tfc->t_context->index,
+            name,
+            &pl_height,
+            &process_info,
+            &hashed_process_data);
+        gtk_widget_set_size_request(drawing->drawing_area,
+                                    -1,
+                                    pl_height);
+        gtk_widget_queue_draw(drawing->drawing_area);
+      }
+
+      /* Now, the process is in the state hash and our own process hash.
+       * We definitely can draw the items related to the ending state.
+       */
+      
+      if(likely(ltt_time_compare(hashed_process_data->next_good_time,
+                          evtime) > 0))
+      {
+        if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+          TimeWindow time_window = 
+            lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+          if(ltt_time_compare(evtime, time_window.start_time) == -1
+                || ltt_time_compare(evtime, time_window.end_time) == 1)
+                    return;
+#endif //EXTRA_CHECK
+          Drawing_t *drawing = control_flow_data->drawing;
+          guint width = drawing->width;
+          guint x;
+          convert_time_to_pixels(
+                    time_window,
+                    evtime,
+                    width,
+                    &x);
+
+          /* Draw collision indicator */
+          gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+          gdk_draw_point(hashed_process_data->pixmap,
+                         drawing->gc,
+                         x,
+                         (hashed_process_data->height/2)-3);
+          hashed_process_data->x.middle_marked = TRUE;
+        }
+      } else {
+        TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+        if(ltt_time_compare(evtime, time_window.start_time) == -1
+              || ltt_time_compare(evtime, time_window.end_time) == 1)
+                  return;
+#endif //EXTRA_CHECK
+        Drawing_t *drawing = control_flow_data->drawing;
+        guint width = drawing->width;
+        guint x;
+
+        convert_time_to_pixels(
+            time_window,
+            evtime,
+            width,
+            &x);
+
+
+        /* Jump over draw if we are at the same x position */
+        if(unlikely(x == hashed_process_data->x.middle &&
+               hashed_process_data->x.middle_used))
+        { 
+          if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+            /* Draw collision indicator */
+            gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+            gdk_draw_point(hashed_process_data->pixmap,
+                           drawing->gc,
+                           x,
+                           (hashed_process_data->height/2)-3);
+            hashed_process_data->x.middle_marked = TRUE;
+          }
+          /* jump */
+        } else {
+          DrawContext draw_context;
+
+          /* Now create the drawing context that will be used to draw
+           * items related to the last state. */
+          draw_context.drawable = hashed_process_data->pixmap;
+          draw_context.gc = drawing->gc;
+          draw_context.pango_layout = drawing->pango_layout;
+          draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+          draw_context.drawinfo.end.x = x;
+
+          draw_context.drawinfo.y.over = 1;
+          draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+          draw_context.drawinfo.y.under = hashed_process_data->height;
+
+          draw_context.drawinfo.start.offset.over = 0;
+          draw_context.drawinfo.start.offset.middle = 0;
+          draw_context.drawinfo.start.offset.under = 0;
+          draw_context.drawinfo.end.offset.over = 0;
+          draw_context.drawinfo.end.offset.middle = 0;
+          draw_context.drawinfo.end.offset.under = 0;
+
+          {
+            /* Draw the line */
+            PropertiesLine prop_line = prepare_s_e_line(process);
+            draw_line((void*)&prop_line, (void*)&draw_context);
+
+          }
+          /* become the last x position */
+          hashed_process_data->x.middle = x;
+          hashed_process_data->x.middle_used = TRUE;
+          hashed_process_data->x.middle_marked = FALSE;
+
+          /* Calculate the next good time */
+          convert_pixels_to_time(width, x+1, time_window,
+                                 &hashed_process_data->next_good_time);
+        }
+      }
+    }
+
   }
   return 0;
 
@@ -2496,6 +2659,8 @@ int after_process_hook(void *hook_data, void *call_data)
 
     birth = process_child->creation_time;
 
+    /* Cannot use current process, because this action is done by the parent
+     * on its child. */
     hashed_process_data_child = processlist_get_process_data(process_list,
             child_pid,
             process_child->last_cpu_index,
@@ -3059,11 +3224,11 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data)
 #ifdef EXTRA_CHECK
     g_assert(lttv_traceset_number(tsc->ts) > 0);
 #endif //EXTRA_CHECK
-    /* tracefiles[0] is ok here, because we draw for every PID, and
-     * assume CPU 0 for PID 0 //FIXME */
-    LttvTracefileState *tfs =
-      (LttvTracefileState*)tsc->traces[process_info->trace_num]->tracefiles[0];
 
+    LttvTracefileState *tfs =
+     (LttvTracefileState*)tsc->traces[process_info->trace_num]->
+                         tracefiles[process_info->cpu];
     LttvProcessState *process;
     process = lttv_state_find_process(tfs,
                                       process_info->pid);
index d3ef83b2bb91aee6b7e4c7ddc49898b4fff94809..2e0273886f216b7dc666db4461a6b3a59a1a304e 100644 (file)
@@ -273,7 +273,6 @@ void copy_pixmap_to_screen(ProcessList *process_list,
   if(process_list->index_to_pixmap->len == 0) return;
   guint cell_height = process_list->cell_height;
 
-  //cell_height = 24; //FIXME
   /* Get indexes */
   gint begin = floor(y/(double)cell_height);
   gint end = MIN(ceil((y+height)/(double)cell_height),
@@ -577,7 +576,6 @@ int processlist_add(  ProcessList *process_list,
 
   hashed_process_data->height = process_list->cell_height;
 
-  //hashed_process_data->height = 24; // FIXME
   g_assert(hashed_process_data->height != 0);
 
   *height = hashed_process_data->height * process_list->number_of_process;
index 687ac407e7e58c2d111e679854161aa91bdb9d51..1de9b09a0dac4947f8b31057f1238cccad00fbfe 100644 (file)
@@ -88,7 +88,6 @@ typedef struct _HashedProcessData {
 
   LttTime next_good_time; /* precalculate the next time where the next
                              pixel is.*/
-  // FIXME : add info on last event ?
 
 } HashedProcessData;
   
This page took 0.034201 seconds and 4 git commands to generate.