free bugfix
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 13 Sep 2005 00:15:26 +0000 (00:15 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 13 Sep 2005 00:15:26 +0000 (00:15 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1171 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/ltt/ltt-private.h
ltt/branches/poly/ltt/tracefile.c
ltt/branches/poly/lttv/lttv/state.c
ltt/branches/poly/lttv/lttv/state.h

index 1bbe0a10ddcf9e56f0367e4785a77c0aceb19b13..9e263c565b2675bbb5422cb3292eb04a8874b38f 100644 (file)
@@ -184,6 +184,8 @@ struct ltt_trace_header_0_4 {
   uint8_t         has_heartbeat;
   uint8_t         has_alignment;  /* Event header alignment */
        uint8_t         has_tsc;
+  uint64_t        start_freq;
+  uint64_t        start_tsc;
   uint64_t        start_monotonic;
   struct timespec start_time;
 } LTT_PACKED_STRUCT;
@@ -354,7 +356,8 @@ typedef struct _LttBuffer {
   /* Timekeeping */
   uint64_t                tsc;       /* Current timestamp counter */
   uint64_t                freq; /* Frequency in khz */
-  double                  nsecs_per_cycle;  /* Precalculated from freq */
+  //double                  nsecs_per_cycle;  /* Precalculated from freq */
+  guint32                 cyc2ns_scale;
 } LttBuffer;
 
 struct _LttTracefile{
@@ -411,6 +414,8 @@ struct _LttTrace{
   guint8    has_heartbeat;
   guint8    has_alignment;
        guint8          has_tsc;
+  uint64_t  start_freq;
+  uint64_t  start_tsc;
   uint64_t  start_monotonic;
   LttTime   start_time;
 
index 6500a2d2e229dd88c73dbded7f9ed773a33fa7a2..470eb5e09a619570bffa7a6e57d2a456fe3cb02c 100644 (file)
@@ -93,7 +93,10 @@ static inline void preset_field_type_size(LttTracefile *tf,
 static gint map_block(LttTracefile * tf, guint block_num);
 
 /* calculate nsec per cycles for current block */
-static double calc_nsecs_per_cycle(LttTracefile * t);
+#if 0
+static guint32 calc_nsecs_per_cycle(LttTracefile * t);
+static guint64 cycles_2_ns(LttTracefile *tf, guint64 cycles);
+#endif //0
 
 /* go to the next event */
 static int ltt_seek_next_event(LttTracefile *tf);
@@ -248,6 +251,10 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
          sizeof(struct ltt_block_start_header) 
             + sizeof(struct ltt_trace_header_0_4);
         if(t) {
+          t->start_freq = ltt_get_uint64(LTT_GET_BO(tf),
+                                         &vheader->start_freq);
+          t->start_tsc = ltt_get_uint64(LTT_GET_BO(tf),
+                                        &vheader->start_tsc);
           t->start_monotonic = ltt_get_uint64(LTT_GET_BO(tf),
                                               &vheader->start_monotonic);
           t->start_time = ltt_get_time(LTT_GET_BO(tf),
@@ -1523,10 +1530,12 @@ LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event)
 
   g_assert(tf->trace->has_tsc);
 
-  time = ltt_time_from_uint64(
-      (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count) * 
-                                          tf->buffer.nsecs_per_cycle);
-  time = ltt_time_add(tf->buffer.begin.timestamp, time);
+//  time = ltt_time_from_uint64(
+//      cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count)));
+  time = ltt_time_from_uint64((tf->buffer.tsc - tf->trace->start_tsc) * 1000000
+                                  / (double)tf->trace->start_freq);
+  //time = ltt_time_add(tf->buffer.begin.timestamp, time);
+  time = ltt_time_add(tf->trace->start_time, time);
 
   return time;
 }
@@ -1741,25 +1750,35 @@ static gint map_block(LttTracefile * tf, guint block_num)
 
   header = (struct ltt_block_start_header*)tf->buffer.head;
 
+#if 0
   tf->buffer.begin.timestamp = ltt_time_add(
                                 ltt_time_from_uint64(
                                  ltt_get_uint64(LTT_GET_BO(tf),
                                   &header->begin.timestamp)
                                     - tf->trace->start_monotonic),
                                   tf->trace->start_time);
+#endif //0
   //g_debug("block %u begin : %lu.%lu", block_num,
   //    tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec);
   tf->buffer.begin.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
                                               &header->begin.cycle_count);
   tf->buffer.begin.freq = ltt_get_uint64(LTT_GET_BO(tf),
                                          &header->begin.freq);
+  tf->buffer.begin.timestamp = ltt_time_add(
+                                ltt_time_from_uint64(
+                                  (tf->buffer.begin.cycle_count
+                                  - tf->trace->start_tsc) * 1000000
+                                    / (double)tf->trace->start_freq),
+                                tf->trace->start_time);
+#if 0
+
   tf->buffer.end.timestamp = ltt_time_add(
                                 ltt_time_from_uint64(
                                  ltt_get_uint64(LTT_GET_BO(tf),
                                   &header->end.timestamp)
                                     - tf->trace->start_monotonic),
                                   tf->trace->start_time);
-
+#endif //0
   //g_debug("block %u end : %lu.%lu", block_num,
   //    tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec);
   tf->buffer.end.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
@@ -1768,7 +1787,13 @@ static gint map_block(LttTracefile * tf, guint block_num)
                                        &header->end.freq);
   tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf),
                                         &header->lost_size);
-  
+  tf->buffer.end.timestamp = ltt_time_add(
+                                ltt_time_from_uint64(
+                                  (tf->buffer.end.cycle_count
+                                  - tf->trace->start_tsc) * 1000000
+                                    / (double)tf->trace->start_freq),
+                                tf->trace->start_time);
   tf->buffer.tsc =  tf->buffer.begin.cycle_count;
   tf->event.tsc = tf->buffer.tsc;
   tf->buffer.freq = tf->buffer.begin.freq;
@@ -1782,7 +1807,8 @@ static gint map_block(LttTracefile * tf, guint block_num)
   /* Now that the buffer is mapped, calculate the time interpolation for the
    * block. */
   
-  tf->buffer.nsecs_per_cycle = calc_nsecs_per_cycle(tf);
+//  tf->buffer.nsecs_per_cycle = calc_nsecs_per_cycle(tf);
+  //tf->buffer.cyc2ns_scale = calc_nsecs_per_cycle(tf);
  
   /* Make the current event point to the beginning of the buffer :
    * it means that the event read must get the first event. */
@@ -1931,7 +1957,7 @@ error:
   return ENOPROTOOPT;
 }
 
-
+#if 0
 /*****************************************************************************
  *Function name
  *    calc_nsecs_per_cycle : calculate nsecs per cycle for current block
@@ -1942,15 +1968,22 @@ error:
  ****************************************************************************/
 /* from timer_tsc.c */
 #define CYC2NS_SCALE_FACTOR 10
-static double calc_nsecs_per_cycle(LttTracefile * tf)
+static guint32 calc_nsecs_per_cycle(LttTracefile * tf)
 {
   //return 1e6 / (double)tf->buffer.freq;
-  guint64 cpu_mhz = tf->buffer.freq / 1000;
-  guint64 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+  guint32 cpu_mhz = tf->buffer.freq / 1000;
+  guint32 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
   
-  return cyc2ns_scale >> CYC2NS_SCALE_FACTOR;
+  return cyc2ns_scale;
  // return 1e6 / (double)tf->buffer.freq;
 }
+
+static guint64 cycles_2_ns(LttTracefile *tf, guint64 cycles)
+{
+  return (cycles * tf->buffer.cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+}
+#endif //0
+
 #if 0
 void setFieldsOffset(LttTracefile *tf, LttEventType *evT,void *evD)
 {
index 56552b22012c649c2bbfe8348ba97eb62f058673..52815dd922dfd4335c287f5e974c74934ad6e944 100644 (file)
@@ -85,7 +85,8 @@ LttvProcessStatus
   LTTV_STATE_EXIT,
   LTTV_STATE_ZOMBIE,
   LTTV_STATE_WAIT,
-  LTTV_STATE_RUN;
+  LTTV_STATE_RUN,
+  LTTV_STATE_DEAD;
 
 static GQuark
   LTTV_STATE_TRACEFILES,
@@ -1211,18 +1212,16 @@ static gboolean schedchange(void *hook_data, void *call_data)
 
     if(unlikely(process->state->s == LTTV_STATE_EXIT)) {
       process->state->s = LTTV_STATE_ZOMBIE;
+      process->state->change = s->parent.timestamp;
     } else {
       if(unlikely(state_out == 0)) process->state->s = LTTV_STATE_WAIT_CPU;
       else process->state->s = LTTV_STATE_WAIT;
-    } /* FIXME : we do not remove process here, because the kernel
-       * still has them : they may be zombies. We need to know
-       * exactly when release_task is executed on the PID to 
-       * know when the zombie is destroyed.
-       */
-    //else
-    //  exit_process(s, process);
-
-    process->state->change = s->parent.timestamp;
+      process->state->change = s->parent.timestamp;
+    }
+
+    if(state_out == 32)
+       exit_process(s, process); /* EXIT_DEAD */
+          /* see sched.h for states */
   }
   process = ts->running_process[cpu] =
               lttv_state_find_process_or_create(
@@ -1263,7 +1262,7 @@ static gboolean process_fork(void *hook_data, void *call_data)
    * in a SMP case where we don't have enough precision on the clocks.
    *
    * Test reenabled after precision fixes on time. (Mathieu) */
-  
+#if 0 
   zombie_process = lttv_state_find_process(ts, ANY_CPU, child_pid);
 
   if(unlikely(zombie_process != NULL)) {
@@ -1278,7 +1277,7 @@ static gboolean process_fork(void *hook_data, void *call_data)
 
     exit_process(s, zombie_process);
   }
-
+#endif //0
   g_assert(process->pid != child_pid);
   // FIXME : Add this test in the "known state" section
   // g_assert(process->pid == parent_pid);
@@ -1288,10 +1287,13 @@ static gboolean process_fork(void *hook_data, void *call_data)
                               child_pid, &s->parent.timestamp);
   } else {
     /* The process has already been created :  due to time imprecision between
-     * multiple CPUs : it has been scheduled in before creation.
+     * multiple CPUs : it has been scheduled in before creation. Note that we
+     * shouldn't have this kind of imprecision.
      *
      * Simply put a correct parent.
      */
+    g_assert(0); /* This is a problematic case : the process has been created
+                    before the fork event */
     child_process->ppid = process->pid;
   }
 
@@ -1346,15 +1348,21 @@ static gboolean process_free(void *hook_data, void *call_data)
     //Clearly due to time imprecision, we disable it. (Mathieu)
     //If this weird case happen, we have no choice but to put the 
     //Currently running process on the cpu to 0.
+    //I re-enable it following time precision fixes. (Mathieu)
+    //Well, in the case where an process is freed by a process on another CPU
+    //and still scheduled, it happens that this is the schedchange that will
+    //drop the last reference count. Do not free it here!
     guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
     guint i;
     for(i=0; i< num_cpus; i++) {
       //g_assert(process != ts->running_process[i]);
       if(process == ts->running_process[i]) {
-        ts->running_process[i] = lttv_state_find_process(ts, i, 0);
+        //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
+        break;
       }
     }
-    exit_process(s, process);
+    if(i == num_cpus) /* process is not scheduled */
+      exit_process(s, process);
   }
 
   return FALSE;
@@ -2124,6 +2132,7 @@ static void module_init()
   LTTV_STATE_ZOMBIE = g_quark_from_string("zombie");
   LTTV_STATE_WAIT = g_quark_from_string("wait for I/O");
   LTTV_STATE_RUN = g_quark_from_string("running");
+  LTTV_STATE_DEAD = g_quark_from_string("dead");
   LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
   LTTV_STATE_PROCESSES = g_quark_from_string("processes");
   LTTV_STATE_PROCESS = g_quark_from_string("process");
index 9d1598b476adb146b628b3ba6114120ab44c2fa5..69f35edf1867f8cfcfa4c67099d46475332094a4 100644 (file)
@@ -168,7 +168,8 @@ extern LttvProcessStatus
   LTTV_STATE_EXIT,
   LTTV_STATE_ZOMBIE,
   LTTV_STATE_WAIT,
-  LTTV_STATE_RUN;
+  LTTV_STATE_RUN,
+  LTTV_STATE_DEAD;
 
 
 typedef struct _LttvExecutionState {
This page took 0.030522 seconds and 4 git commands to generate.