fix heartbeat
[lttv.git] / ltt / branches / poly / ltt / tracefile.c
index 37a7c0354b287bbf709080bec0db76ea275a15f4..79063373e838d6e0f060f0767c850bcb860c64fd 100644 (file)
@@ -3,19 +3,19 @@
  *
  * Complete rewrite from the original version made by XangXiu Yang.
  * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
  *
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
- * MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -106,7 +106,7 @@ static int ltt_seek_next_event(LttTracefile *tf);
 void ltt_update_event_size(LttTracefile *tf);
 
 
-void precompute_offsets(LttTracefile *tf, LttEventType *event);
+void precompute_offsets(LttFacility *fac, LttEventType *event);
 
 #if 0
 /* Functions to parse system.xml file (using glib xml parser) */
@@ -232,7 +232,7 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
     t->ltt_minor_version = any->minor_version;
     t->flight_recorder = any->flight_recorder;
     t->has_heartbeat = any->has_heartbeat;
-    t->has_tsc = any->has_tsc;
+    t->freq_scale = any->freq_scale;
   }
  
 
@@ -250,13 +250,13 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
         return 1;
       }
       break;
-    case 6:
+    case 7:
       {
-        struct ltt_trace_header_0_5 *vheader =
-          (struct ltt_trace_header_0_5 *)header;
+        struct ltt_trace_header_0_7 *vheader =
+          (struct ltt_trace_header_0_7 *)header;
         tf->buffer_header_size =
          sizeof(struct ltt_block_start_header) 
-            + sizeof(struct ltt_trace_header_0_5);
+            + sizeof(struct ltt_trace_header_0_7);
         if(t) {
           t->start_freq = ltt_get_uint64(LTT_GET_BO(tf),
                                          &vheader->start_freq);
@@ -858,6 +858,8 @@ static int ltt_get_facility_description(LttFacility *f,
   const gchar *text;
   guint textlen;
   gint err;
+       gint arch_spec;
+       gint fac_name_len;
 
   text = g_quark_to_string(t->pathname);
   textlen = strlen(text);
@@ -871,9 +873,21 @@ static int ltt_get_facility_description(LttFacility *f,
   strcat(desc_file_name, text);
   
   text = g_quark_to_string(f->name);
-  textlen+=strlen(text);
+       fac_name_len = strlen(text);
+  textlen+=fac_name_len;
   if(textlen >= PATH_MAX) goto name_error;
   strcat(desc_file_name, text);
+
+       /* arch specific facilities are named like this : name_arch */
+       if(fac_name_len+1 < sizeof("_arch"))
+               arch_spec = 0;
+       else {
+               if(!strcmp(&text[fac_name_len+1-sizeof("_arch")], "_arch"))
+                       arch_spec = 1;
+               else
+                       arch_spec = 0;
+       }
+
 #if 0
   text = "_";
   textlen+=strlen(text);
@@ -887,6 +901,41 @@ static int ltt_get_facility_description(LttFacility *f,
   textlen=strlen(desc_file_name);
   
 #endif //0
+       
+       if(arch_spec) {
+               switch(t->arch_type) {
+                       case LTT_ARCH_TYPE_I386:
+                               text = "_i386";
+                               break;
+                       case LTT_ARCH_TYPE_PPC:
+                               text = "_ppc";
+                               break;
+                       case LTT_ARCH_TYPE_SH:
+                               text = "_sh";
+                               break;
+                       case LTT_ARCH_TYPE_S390:
+                               text = "_s390";
+                               break;
+                       case LTT_ARCH_TYPE_MIPS:
+                               text = "_mips";
+                               break;
+                       case LTT_ARCH_TYPE_ARM:
+                               text = "_arm";
+                               break;
+                       case LTT_ARCH_TYPE_PPC64:
+                               text = "_ppc64";
+                               break;
+                       case LTT_ARCH_TYPE_X86_64:
+                               text = "_x86_64";
+                               break;
+                       default:
+                               g_error("Trace from unsupported architecture.");
+               }
+               textlen+=strlen(text);
+               if(textlen >= PATH_MAX) goto name_error;
+               strcat(desc_file_name, text);
+       }
+       
   text = ".xml";
   textlen+=strlen(text);
   if(textlen >= PATH_MAX) goto name_error;
@@ -951,6 +1000,7 @@ static int ltt_process_facility_tracefile(LttTracefile *tf)
       struct LttFacilityLoad *fac_load_data;
       struct LttStateDumpFacilityLoad *fac_state_dump_load_data;
       char *fac_name;
+      void *pos;
 
       // FIXME align
       switch((enum ltt_core_events)tf->event.event_id) {
@@ -958,9 +1008,10 @@ static int ltt_process_facility_tracefile(LttTracefile *tf)
           fac_name = (char*)(tf->event.data);
           g_debug("Doing LTT_EVENT_FACILITY_LOAD of facility %s",
               fac_name);
-          fac_load_data =
-            (struct LttFacilityLoad *)
-                (tf->event.data + strlen(fac_name) + 1);
+          pos = (tf->event.data + strlen(fac_name) + 1);
+          pos += ltt_align((size_t)pos, sizeof(guint32), tf->has_alignment);
+          fac_load_data = (struct LttFacilityLoad *)pos;
+
           fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
               ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id));
           /* facility may already exist if trace is paused/unpaused */
@@ -988,7 +1039,7 @@ static int ltt_process_facility_tracefile(LttTracefile *tf)
           /* Preset the field offsets */
           for(i=0; i<fac->events->len; i++){
             et = &g_array_index(fac->events, LttEventType, i);
-            precompute_offsets(tf, et);
+            precompute_offsets(fac, et);
           }
 
           fac->exists = 1;
@@ -1013,9 +1064,10 @@ static int ltt_process_facility_tracefile(LttTracefile *tf)
           fac_name = (char*)(tf->event.data);
           g_debug("Doing LTT_EVENT_STATE_DUMP_FACILITY_LOAD of facility %s",
               fac_name);
-          fac_state_dump_load_data =
-            (struct LttStateDumpFacilityLoad *)
-                (tf->event.data + strlen(fac_name) + 1);
+          pos = (tf->event.data + strlen(fac_name) + 1);
+          pos += ltt_align((size_t)pos, sizeof(guint32), tf->has_alignment);
+          fac_state_dump_load_data = (struct LttStateDumpFacilityLoad *)pos;
+
           fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
               ltt_get_uint32(LTT_GET_BO(tf), &fac_state_dump_load_data->id));
           /* facility may already exist if trace is paused/unpaused */
@@ -1043,7 +1095,7 @@ static int ltt_process_facility_tracefile(LttTracefile *tf)
           /* Preset the field offsets */
           for(i=0; i<fac->events->len; i++){
             et = &g_array_index(fac->events, LttEventType, i);
-            precompute_offsets(tf, et);
+            precompute_offsets(fac, et);
           }
 
           fac->exists = 1;
@@ -1530,6 +1582,10 @@ int ltt_tracefile_seek_position(LttTracefile *tf, const LttEventPosition *ep) {
 
   tf->event.offset = ep->offset;
 
+       /* Put back the event real tsc */
+       tf->event.tsc = ep->tsc;
+       tf->buffer.tsc = ep->tsc;
+
   err = ltt_tracefile_read_update_event(tf);
   if(err) goto fail;
   err = ltt_tracefile_read_op(tf);
@@ -1548,12 +1604,11 @@ LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event)
 {
   LttTime time;
 
-  g_assert(tf->trace->has_tsc);
-
 //  time = ltt_time_from_uint64(
 //      cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count)));
   time = ltt_time_from_uint64(
-      (double)(tf->buffer.tsc - tf->trace->start_tsc) * 1000000.0
+      (double)(tf->buffer.tsc - tf->trace->start_tsc) 
+                                                                                                                                       * (1000000000.0 / tf->trace->freq_scale)
                                   / (double)tf->trace->start_freq);
   //time = ltt_time_add(tf->buffer.begin.timestamp, time);
   time = ltt_time_add(tf->trace->start_time_from_tsc, time);
@@ -1669,43 +1724,29 @@ int ltt_tracefile_read_update_event(LttTracefile *tf)
        /* Align the head */
        pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment);
   
-  if(tf->trace->has_tsc) {
-    if(tf->trace->has_heartbeat) {
-      event->time.timestamp = ltt_get_uint32(LTT_GET_BO(tf),
-                                            pos);
-      /* 32 bits -> 64 bits tsc */
-      /* note : still works for seek and non seek cases. */
-      if(event->time.timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
-        tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
-                            + 0x100000000ULL)
-                                | (guint64)event->time.timestamp;
-        event->tsc = tf->buffer.tsc;
-      } else {
-        /* no overflow */
-        tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) 
-                                | (guint64)event->time.timestamp;
-        event->tsc = tf->buffer.tsc;
-      }
-      pos += sizeof(guint32);
-    } else {
-      event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
-      tf->buffer.tsc = event->tsc;
-      pos += sizeof(guint64);
-    }
-    
-    event->event_time = ltt_interpolate_time(tf, event);
-  } else {
-    event->time.delta.tv_sec = 0;
-    event->time.delta.tv_nsec = ltt_get_uint32(LTT_GET_BO(tf),
-                                          pos) * NSEC_PER_USEC;
-    tf->buffer.tsc = 0;
-    event->tsc = tf->buffer.tsc;
-
-    event->event_time = ltt_time_add(tf->buffer.begin.timestamp,
-                                     event->time.delta);
-    pos += sizeof(guint32);
-  }
-
+       if(tf->trace->has_heartbeat) {
+               event->timestamp = ltt_get_uint32(LTT_GET_BO(tf),
+                                                                                                                                                                       pos);
+               /* 32 bits -> 64 bits tsc */
+               /* note : still works for seek and non seek cases. */
+               if(event->timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
+                       tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+                                                                                                       + 0x100000000ULL)
+                                                                                                                       | (guint64)event->timestamp;
+                       event->tsc = tf->buffer.tsc;
+               } else {
+                       /* no overflow */
+                       tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) 
+                                                                                                                       | (guint64)event->timestamp;
+                       event->tsc = tf->buffer.tsc;
+               }
+               pos += sizeof(guint32);
+       } else {
+               event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
+               tf->buffer.tsc = event->tsc;
+               pos += sizeof(guint64);
+       }
+       event->event_time = ltt_interpolate_time(tf, event);
   event->facility_id = *(guint8*)pos;
   pos += sizeof(guint8);
 
@@ -1863,6 +1904,7 @@ void ltt_update_event_size(LttTracefile *tf)
   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);
+    size += ltt_align(size, sizeof(guint32), tf->has_alignment);
     size += sizeof(struct LttFacilityLoad);
     break;
   case LTT_EVENT_FACILITY_UNLOAD:
@@ -1871,6 +1913,7 @@ void ltt_update_event_size(LttTracefile *tf)
     break;
   case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
     size = strlen((char*)tf->event.data) + 1;
+    size += ltt_align(size, sizeof(guint32), tf->has_alignment);
     //g_debug("Update Event facility load state dump of facility %s",
     //    (char*)tf->event.data);
     size += sizeof(struct LttStateDumpFacilityLoad);
@@ -1908,7 +1951,7 @@ void ltt_update_event_size(LttTracefile *tf)
     }
     
     /* Compute the dynamic offsets */
-    compute_offsets(tf, event_type, &size, tf->event.data);
+    compute_offsets(tf, f, event_type, &size, tf->event.data);
 
     //g_debug("Event root field : f.e %hhu.%hhu size %zd",
     //    tf->event.facility_id,
@@ -1918,6 +1961,10 @@ void ltt_update_event_size(LttTracefile *tf)
   tf->event.data_size = size;
   
   /* Check consistency between kernel and LTTV structure sizes */
+       if(tf->event.event_size == 0xFFFF) {
+               /* Event size too big to fit in the event size field */
+               tf->event.event_size = tf->event.data_size;
+       }
   g_assert(tf->event.data_size == tf->event.event_size);
 
   return;
@@ -2044,13 +2091,12 @@ void set_fields_offsets(LttTracefile *tf, LttEventType *event_type)
  *Function name
  *    get_alignment : Get the alignment needed for a field.
  *Input params 
- *    tf : tracefile
  *    field : field
  *
  *    returns : The size on which it must be aligned.
  *
  ****************************************************************************/
-off_t get_alignment(LttTracefile *tf, LttField *field)
+off_t get_alignment(LttField *field)
 {
   LttType *type = &field->field_type;
 
@@ -2081,7 +2127,7 @@ off_t get_alignment(LttTracefile *tf, LttField *field)
       g_assert(type->fields->len == 1);
       {
         LttField *child = &g_array_index(type->fields, LttField, 0);
-        return get_alignment(tf, child);
+        return get_alignment(child);
       }
       break;
     case LTT_SEQUENCE:
@@ -2090,10 +2136,10 @@ off_t get_alignment(LttTracefile *tf, LttField *field)
         off_t localign = 0;
         LttField *child = &g_array_index(type->fields, LttField, 0);
 
-        localign = max(localign, get_alignment(tf, child));
+        localign = max(localign, get_alignment(child));
 
         child = &g_array_index(type->fields, LttField, 1);
-        localign = max(localign, get_alignment(tf, child));
+        localign = max(localign, get_alignment(child));
         
         return localign;
       }
@@ -2106,7 +2152,7 @@ off_t get_alignment(LttTracefile *tf, LttField *field)
         
         for(i=0; i<type->fields->len; i++) {
           LttField *child = &g_array_index(type->fields, LttField, i);
-          localign = max(localign, get_alignment(tf, child));
+          localign = max(localign, get_alignment(child));
         }
         return localign;
       }
@@ -2129,7 +2175,7 @@ off_t get_alignment(LttTracefile *tf, LttField *field)
  *
  ****************************************************************************/
 
-void field_compute_static_size(LttTracefile *tf, LttField *field)
+void field_compute_static_size(LttFacility *fac, LttField *field)
 {
   LttType *type = &field->field_type;
 
@@ -2159,7 +2205,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field)
       g_assert(type->fields->len == 1);
       {
         LttField *child = &g_array_index(type->fields, LttField, 0);
-        field_compute_static_size(tf, child);
+        field_compute_static_size(fac, child);
         
         if(child->field_size != 0) {
           field->field_size = type->size * child->field_size;
@@ -2175,7 +2221,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field)
       {
         off_t local_offset = 0;
         LttField *child = &g_array_index(type->fields, LttField, 1);
-        field_compute_static_size(tf, child);
+        field_compute_static_size(fac, child);
         field->field_size = 0;
         type->size = 0;
         if(child->field_size != 0) {
@@ -2190,10 +2236,10 @@ void field_compute_static_size(LttTracefile *tf, LttField *field)
         guint i;
         for(i=0;i<type->fields->len;i++) {
           LttField *child = &g_array_index(type->fields, LttField, i);
-          field_compute_static_size(tf, child);
+          field_compute_static_size(fac, child);
           if(child->field_size != 0) {
-            type->size += ltt_align(type->size, get_alignment(tf, child),
-                                    tf->has_alignment);
+            type->size += ltt_align(type->size, get_alignment(child),
+                                    fac->alignment);
             type->size += child->field_size;
           } else {
             /* As soon as we find a child with variable size, we have
@@ -2217,7 +2263,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field)
  *Function name
  *    precompute_fields_offsets : set the precomputable offset of the fields
  *Input params 
- *    tf : tracefile
+ *    fac : facility
  *    field : the field
  *    offset : pointer to the current offset, must be incremented
  *
@@ -2226,7 +2272,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field)
  ****************************************************************************/
 
 
-gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
+gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset)
 {
   LttType *type = &field->field_type;
 
@@ -2247,9 +2293,10 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
     case LTT_OFF_T:
     case LTT_FLOAT:
     case LTT_ENUM:
+      g_assert(field->field_size != 0);
       /* Align offset on type size */
-      *offset += ltt_align(*offset, get_alignment(tf, field),
-                           tf->has_alignment);
+      *offset += ltt_align(*offset, get_alignment(field),
+                           fac->alignment);
       /* remember offset */
       field->offset_root = *offset;
       field->fixed_root = FIELD_FIXED;
@@ -2267,8 +2314,8 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
       {
         LttField *child = &g_array_index(type->fields, LttField, 0);
 
-        *offset += ltt_align(*offset, get_alignment(tf, field),
-                            tf->has_alignment);
+        *offset += ltt_align(*offset, get_alignment(field),
+                             fac->alignment);
         
         /* remember offset */
         field->offset_root = *offset;
@@ -2294,23 +2341,23 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
         LttField *child;
         guint ret;
 
-        *offset += ltt_align(*offset, get_alignment(tf, field),
-                             tf->has_alignment);
+        *offset += ltt_align(*offset, get_alignment(field),
+                             fac->alignment);
 
         /* remember offset */
         field->offset_root = *offset;
         field->fixed_root = FIELD_FIXED;
  
         child = &g_array_index(type->fields, LttField, 0);
-        ret = precompute_fields_offsets(tf, child, offset);
+        ret = precompute_fields_offsets(fac, child, offset);
         g_assert(ret == 0); /* Seq len cannot have variable len */
 
         child = &g_array_index(type->fields, LttField, 1);
-        *offset += ltt_align(*offset, get_alignment(tf, child),
-                             tf->has_alignment);
+        *offset += ltt_align(*offset, get_alignment(child),
+                             fac->alignment);
         field->array_offset = *offset;
-        /* Set the offset position at position 0 */
-        ret = precompute_fields_offsets(tf, child, offset);
+        /* Let the child be variable. */
+        //ret = precompute_fields_offsets(fac, child, offset);
 
         /* Cannot precompute fields offsets of sequence members, and has
          * variable length. */
@@ -2323,15 +2370,15 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
         guint i;
         gint ret=0;
 
-        *offset += ltt_align(*offset, get_alignment(tf, field),
-                             tf->has_alignment);
+        *offset += ltt_align(*offset, get_alignment(field),
+                             fac->alignment);
         /* remember offset */
         field->offset_root = *offset;
         field->fixed_root = FIELD_FIXED;
 
         for(i=0; i< type->fields->len; i++) {
           child = &g_array_index(type->fields, LttField, i);
-          ret = precompute_fields_offsets(tf, child, offset);
+          ret = precompute_fields_offsets(fac, child, offset);
 
           if(ret) break;
         }
@@ -2344,8 +2391,8 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
         guint i;
         gint ret=0;
 
-        *offset += ltt_align(*offset, get_alignment(tf, field),
-                             tf->has_alignment);
+        *offset += ltt_align(*offset, get_alignment(field),
+                             fac->alignment);
         /* remember offset */
         field->offset_root = *offset;
         field->fixed_root = FIELD_FIXED;
@@ -2353,7 +2400,7 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
         for(i=0; i< type->fields->len; i++) {
           *offset = field->offset_root;
           child = &g_array_index(type->fields, LttField, i);
-          ret = precompute_fields_offsets(tf, child, offset);
+          ret = precompute_fields_offsets(fac, child, offset);
 
           if(ret) break;
         }
@@ -2379,7 +2426,7 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
  *    event : event type
  *
  ****************************************************************************/
-void precompute_offsets(LttTracefile *tf, LttEventType *event)
+void precompute_offsets(LttFacility *fac, LttEventType *event)
 {
   guint i;
   off_t offset = 0;
@@ -2389,13 +2436,13 @@ void precompute_offsets(LttTracefile *tf, LttEventType *event)
    * arrays, struct and unions, which is not done by the parser */
   for(i=0; i<event->fields->len; i++) {
     LttField *field = &g_array_index(event->fields, LttField, i);
-    field_compute_static_size(tf, field);
+    field_compute_static_size(fac, field);
   }
   
   /* Precompute all known offsets */
   for(i=0; i<event->fields->len; i++) {
     LttField *field = &g_array_index(event->fields, LttField, i);
-    ret = precompute_fields_offsets(tf, field, &offset);
+    ret = precompute_fields_offsets(fac, field, &offset);
     if(ret) break;
   }
 }
@@ -2614,6 +2661,10 @@ gint check_fields_compatibility(LttEventType *event_type1,
     different = 1;
     goto end;
   }
+       if(type1->network != type2->network) {
+               different = 1;
+               goto end;
+       }
  
   switch(type1->type_class) {
     case LTT_INT_FIXED:
This page took 0.03113 seconds and 4 git commands to generate.