free bugfix
[lttv.git] / ltt / branches / poly / ltt / tracefile.c
index 9da89781e2f4aa1de9f340ca4df8aadc442e507c..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);
@@ -191,6 +194,93 @@ guint ltt_trace_get_num_cpu(LttTrace *t)
 }
 
 
+/* trace can be NULL
+ *
+ * Return value : 0 success, 1 bad tracefile
+ */
+int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
+{
+  guint32 *magic_number = (guint32*)header;
+  struct ltt_trace_header_any *any = (struct ltt_trace_header_any *)header;
+
+  if(*magic_number == LTT_MAGIC_NUMBER)
+    tf->reverse_bo = 0;
+  else if(*magic_number == LTT_REV_MAGIC_NUMBER)
+    tf->reverse_bo = 1;
+  else  /* invalid magic number, bad tracefile ! */
+    return 1;
+    
+  /* Get float byte order : might be different from int byte order
+   * (or is set to 0 if the trace has no float (kernel trace)) */
+  tf->float_word_order = any->float_word_order;
+
+  if(t) {
+    t->arch_type = ltt_get_uint32(LTT_GET_BO(tf),
+                          &any->arch_type);
+    t->arch_variant = ltt_get_uint32(LTT_GET_BO(tf),
+        &any->arch_variant);
+    t->arch_size = any->arch_size;
+    t->ltt_major_version = any->major_version;
+    t->ltt_minor_version = any->minor_version;
+    t->flight_recorder = any->flight_recorder;
+    t->has_heartbeat = any->has_heartbeat;
+    t->has_alignment = any->has_alignment;
+    t->has_tsc = any->has_tsc;
+  }
+
+  switch(any->major_version) {
+
+  case 0:
+    switch(any->minor_version) {
+    case 3:
+      {
+        tf->buffer_header_size =
+         sizeof(struct ltt_block_start_header) 
+            + sizeof(struct ltt_trace_header_0_3);
+        g_warning("Unsupported trace version : %hhu.%hhu",
+              any->major_version, any->minor_version);
+        return 1;
+      }
+      break;
+    case 4:
+      {
+        struct ltt_trace_header_0_4 *vheader =
+          (struct ltt_trace_header_0_4 *)header;
+        tf->buffer_header_size =
+         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),
+                                       &vheader->start_time);
+        }
+      }
+      break;
+    default:
+      g_warning("Unsupported trace version : %hhu.%hhu",
+            any->major_version, any->minor_version);
+      return 1;
+    }
+    break;
+
+  default:
+    g_warning("Unsupported trace version : %hhu.%hhu",
+            any->major_version, any->minor_version);
+    return 1;
+  }
+
+
+  return 0;
+}
+
+
+
 /*****************************************************************************
  *Function name
  *    ltt_tracefile_open : open a trace file, construct a LttTracefile
@@ -224,7 +314,9 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   }
 
   // Is the file large enough to contain a trace 
-  if(lTDFStat.st_size < (off_t)(sizeof(struct ltt_block_start_header))){
+  if(lTDFStat.st_size <
+      (off_t)(sizeof(struct ltt_block_start_header) 
+                     + sizeof(struct ltt_trace_header_any))){
     g_print("The input data file %s does not contain a trace\n", fileName);
     goto close_file;
   }
@@ -232,7 +324,8 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   /* Temporarily map the buffer start header to get trace information */
   /* Multiple of pages aligned head */
   tf->buffer.head = mmap(0,
-      PAGE_ALIGN(sizeof(struct ltt_block_start_header)), PROT_READ, 
+      PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+          + sizeof(struct ltt_trace_header_any)), PROT_READ, 
       MAP_PRIVATE, tf->fd, 0);
   if(tf->buffer.head == MAP_FAILED) {
     perror("Error in allocating memory for buffer of tracefile");
@@ -242,12 +335,10 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   
   header = (struct ltt_block_start_header*)tf->buffer.head;
   
-  if(header->trace.magic_number == LTT_MAGIC_NUMBER)
-    tf->reverse_bo = 0;
-  else if(header->trace.magic_number == LTT_REV_MAGIC_NUMBER)
-    tf->reverse_bo = 1;
-  else  /* invalid magic number, bad tracefile ! */
+  if(parse_trace_header(header->trace, tf, NULL)) {
+    g_warning("parse_trace_header error");
     goto unmap_file;
+  }
     
   //store the size of the file
   tf->file_size = lTDFStat.st_size;
@@ -255,9 +346,11 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   tf->num_blocks = tf->file_size / tf->buf_size;
 
   if(munmap(tf->buffer.head,
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)))) {
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)))) {
     g_warning("unmap size : %u\n",
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)));
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)));
     perror("munmap error");
     g_assert(0);
   }
@@ -274,9 +367,11 @@ gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
   /* Error */
 unmap_file:
   if(munmap(tf->buffer.head,
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)))) {
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)))) {
     g_warning("unmap size : %u\n",
-        PAGE_ALIGN(sizeof(struct ltt_block_start_header)));
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)));
     perror("munmap error");
     g_assert(0);
   }
@@ -734,7 +829,7 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path,
 
 /* ltt_get_facility_description
  *
- * Opens the trace corresponding to the requested facility (identified by fac_id
+ * Opens the file corresponding to the requested facility (identified by fac_id
  * and checksum).
  *
  * The name searched is : %trace root%/eventdefs/facname_checksum.xml
@@ -766,7 +861,7 @@ static int ltt_get_facility_description(LttFacility *f,
   textlen+=strlen(text);
   if(textlen >= PATH_MAX) goto name_error;
   strcat(desc_file_name, text);
-
+#if 0
   text = "_";
   textlen+=strlen(text);
   if(textlen >= PATH_MAX) goto name_error;
@@ -778,11 +873,12 @@ static int ltt_get_facility_description(LttFacility *f,
 
   textlen=strlen(desc_file_name);
   
+#endif //0
   text = ".xml";
   textlen+=strlen(text);
   if(textlen >= PATH_MAX) goto name_error;
   strcat(desc_file_name, text);
+
   err = ltt_facility_open(f, t, desc_file_name);
   if(err) goto facility_error;
 
@@ -1045,15 +1141,8 @@ LttTrace *ltt_trace_open(const gchar *pathname)
   g_assert(group->len > 0);
   tf = &g_array_index (group, LttTracefile, 0);
   header = (struct ltt_block_start_header*)tf->buffer.head;
-  t->arch_type = ltt_get_uint32(LTT_GET_BO(tf), &header->trace.arch_type);
-  t->arch_variant = ltt_get_uint32(LTT_GET_BO(tf), &header->trace.arch_variant);
-  t->arch_size = header->trace.arch_size;
-  t->ltt_major_version = header->trace.major_version;
-  t->ltt_minor_version = header->trace.minor_version;
-  t->flight_recorder = header->trace.flight_recorder;
-  t->has_heartbeat = header->trace.has_heartbeat;
-  t->has_alignment = header->trace.has_alignment;
-  t->has_tsc = header->trace.has_tsc;
+  g_assert(parse_trace_header(header->trace,
+                                  tf, t) == 0);
 
   t->num_cpu = group->len;
   
@@ -1254,11 +1343,17 @@ void ltt_trace_time_span_get(LttTrace *t, LttTime *start, LttTime *end)
  *Get the name of a tracefile
  ****************************************************************************/
 
-GQuark ltt_tracefile_name(LttTracefile *tf)
+GQuark ltt_tracefile_name(const LttTracefile *tf)
 {
   return tf->name;
 }
 
+GQuark ltt_tracefile_long_name(const LttTracefile *tf)
+{
+  return tf->long_name;
+}
+
+
 
 guint ltt_tracefile_num(LttTracefile *tf)
 {
@@ -1362,16 +1457,16 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time)
         if(ret == ERANGE) goto range; /* ERANGE or EPERM */
         else if(ret) goto fail;
 
-        if(ltt_time_compare(time, tf->event.event_time) >= 0)
+        if(ltt_time_compare(time, tf->event.event_time) <= 0)
           goto found;
       }
 
     } else if(ltt_time_compare(time, tf->buffer.begin.timestamp) < 0) {
       /* go to lower part */
-      high = block_num;
+      high = block_num - 1;
     } else if(ltt_time_compare(time, tf->buffer.end.timestamp) > 0) {
       /* go to higher part */
-      low = block_num;
+      low = block_num + 1;
     } else {/* The event is right in the buffer!
                (or in the next buffer first event) */
       while(1) {
@@ -1379,7 +1474,7 @@ int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time)
         if(ret == ERANGE) goto range; /* ERANGE or EPERM */
         else if(ret) goto fail;
 
-        if(ltt_time_compare(time, tf->event.event_time) >= 0)
+        if(ltt_time_compare(time, tf->event.event_time) <= 0)
           break;
       }
       goto found;
@@ -1435,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;
 }
@@ -1653,25 +1750,53 @@ static gint map_block(LttTracefile * tf, guint block_num)
 
   header = (struct ltt_block_start_header*)tf->buffer.head;
 
-  tf->buffer.begin.timestamp = ltt_get_time(LTT_GET_BO(tf),
-                                              &header->begin.timestamp);
-  tf->buffer.begin.timestamp.tv_nsec *= NSEC_PER_USEC;
-  g_debug("block %u begin : %lu.%lu", block_num,
-      tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec);
+#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.end.timestamp = ltt_get_time(LTT_GET_BO(tf),
-                                              &header->end.timestamp);
-  tf->buffer.end.timestamp.tv_nsec *= NSEC_PER_USEC;
-  g_debug("block %u end : %lu.%lu", block_num,
-      tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec);
+  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),
                                               &header->end.cycle_count);
+  tf->buffer.end.freq = ltt_get_uint64(LTT_GET_BO(tf),
+                                       &header->end.freq);
   tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf),
-                                              &header->lost_size);
-  
+                                        &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;
 
   /* FIXME
    * eventually support variable buffer size : will need a partial pre-read of
@@ -1682,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. */
@@ -1711,21 +1837,21 @@ void ltt_update_event_size(LttTracefile *tf)
     switch((enum ltt_core_events)tf->event.event_id) {
   case LTT_EVENT_FACILITY_LOAD:
     size = strlen((char*)tf->event.data) + 1;
-    g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
+    //g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
     size += sizeof(struct LttFacilityLoad);
     break;
   case LTT_EVENT_FACILITY_UNLOAD:
-    g_debug("Update Event facility unload");
+    //g_debug("Update Event facility unload");
     size = sizeof(struct LttFacilityUnload);
     break;
   case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
     size = strlen((char*)tf->event.data) + 1;
-    g_debug("Update Event facility load state dump of facility %s",
-        (char*)tf->event.data);
+    //g_debug("Update Event facility load state dump of facility %s",
+    //    (char*)tf->event.data);
     size += sizeof(struct LttStateDumpFacilityLoad);
     break;
   case LTT_EVENT_HEARTBEAT:
-    g_debug("Update Event heartbeat");
+    //g_debug("Update Event heartbeat");
     size = sizeof(TimeHeartbeat);
     break;
   default:
@@ -1762,9 +1888,9 @@ void ltt_update_event_size(LttTracefile *tf)
     else
       size = 0;
 
-    g_debug("Event root field : f.e %hhu.%hhu size %zd",
-        tf->event.facility_id,
-        tf->event.event_id, size);
+    //g_debug("Event root field : f.e %hhu.%hhu size %zd",
+    //    tf->event.facility_id,
+    //    tf->event.event_id, size);
   }
   
   tf->event.data_size = size;
@@ -1799,7 +1925,7 @@ static int ltt_seek_next_event(LttTracefile *tf)
   
   /* seek over the buffer header if we are at the buffer start */
   if(tf->event.offset == 0) {
-    tf->event.offset += sizeof(struct ltt_block_start_header);
+    tf->event.offset += tf->buffer_header_size;
 
     if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) {
       ret = ERANGE;
@@ -1820,6 +1946,7 @@ static int ltt_seek_next_event(LttTracefile *tf)
     ret = ERANGE;
     goto found;
   }
+  g_assert(tf->event.offset < tf->buf_size - tf->buffer.lost_size);
 
 found:
   return ret;
@@ -1830,34 +1957,33 @@ error:
   return ENOPROTOOPT;
 }
 
-
+#if 0
 /*****************************************************************************
  *Function name
  *    calc_nsecs_per_cycle : calculate nsecs per cycle for current block
+ *
+ *    1.0 / (freq(khz) *1000)  * 1000000000
  *Input Params
  *    t               : tracefile
  ****************************************************************************/
-
-static double calc_nsecs_per_cycle(LttTracefile * tf)
+/* from timer_tsc.c */
+#define CYC2NS_SCALE_FACTOR 10
+static guint32 calc_nsecs_per_cycle(LttTracefile * tf)
 {
-  LttTime           lBufTotalTime; /* Total time for this buffer */
-  double            lBufTotalNSec; /* Total time for this buffer in nsecs */
-  LttCycleCount     lBufTotalCycle;/* Total cycles for this buffer */
-
-  /* Calculate the total time for this buffer */
-  lBufTotalTime = ltt_time_sub(tf->buffer.end.timestamp,
-                               tf->buffer.begin.timestamp);
-
-  /* Calculate the total cycles for this bufffer */
-  lBufTotalCycle  = tf->buffer.end.cycle_count;
-  lBufTotalCycle -= tf->buffer.begin.cycle_count;
-
-  /* Convert the total time to double */
-  lBufTotalNSec  = ltt_time_to_double(lBufTotalTime);
+  //return 1e6 / (double)tf->buffer.freq;
+  guint32 cpu_mhz = tf->buffer.freq / 1000;
+  guint32 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
   
-  return lBufTotalNSec / (double)lBufTotalCycle;
+  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)
 {
This page took 0.028745 seconds and 4 git commands to generate.