ltt traceread: fix offsets calculation, should be per tracefile
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Fri, 20 Aug 2010 16:02:42 +0000 (12:02 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Fri, 20 Aug 2010 16:02:42 +0000 (12:02 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
ltt/event.c
ltt/event.h
ltt/marker-field.h
ltt/marker.c
ltt/tracefile.c

index 4297bf0c29ad2acfd8147112f26942aedf475214..3745d896d8362d8d25b3670f8d2bfa303444558b 100644 (file)
@@ -153,6 +153,8 @@ LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep)
 guint32 ltt_event_get_unsigned(LttEvent *e, struct marker_field *f)
 {
   gboolean reverse_byte_order;
+  struct LttField *eventfield;
+  int offset, size;
 
   if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) {
     reverse_byte_order = (g_ntohs(0x1) != 0x1);
@@ -160,22 +162,25 @@ guint32 ltt_event_get_unsigned(LttEvent *e, struct marker_field *f)
     reverse_byte_order = LTT_GET_BO(e->tracefile);
   }
 
-  switch(f->size) {
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  size = eventfield->size;
+  switch(size) {
   case 1:
     {
-      guint8 x = *(guint8 *)(e->data + f->offset);
-      return (guint32) x;    
+      guint8 x = *(guint8 *)(e->data + offset);
+      return (guint32) x;
     }
     break;
   case 2:
-    return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset);
+    return (guint32)ltt_get_uint16(reverse_byte_order, e->data + offset);
     break;
   case 4:
-    return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset);
+    return (guint32)ltt_get_uint32(reverse_byte_order, e->data + offset);
     break;
   case 8:
   default:
-    g_critical("ltt_event_get_unsigned : field size %li unknown", f->size);
+    g_critical("ltt_event_get_unsigned : field size %i unknown", size);
     return 0;
     break;
   }
@@ -184,28 +189,34 @@ guint32 ltt_event_get_unsigned(LttEvent *e, struct marker_field *f)
 gint32 ltt_event_get_int(LttEvent *e, struct marker_field *f)
 {
   gboolean reverse_byte_order;
+  struct LttField *eventfield;
+  int offset, size;
+
   if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) {
     reverse_byte_order = (g_ntohs(0x1) != 0x1);
   } else {
     reverse_byte_order = LTT_GET_BO(e->tracefile);
   }
 
-  switch(f->size) {
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  size = eventfield->size;
+  switch(size) {
   case 1:
     {
-      gint8 x = *(gint8 *)(e->data + f->offset);
-      return (gint32) x;    
+      gint8 x = *(gint8 *)(e->data + offset);
+      return (gint32) x;
     }
     break;
   case 2:
-    return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset);
+    return (gint32)ltt_get_int16(reverse_byte_order, e->data + offset);
     break;
   case 4:
-    return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset);
+    return (gint32)ltt_get_int32(reverse_byte_order, e->data + offset);
     break;
   case 8:
   default:
-    g_critical("ltt_event_get_int : field size %li unknown", f->size);
+    g_critical("ltt_event_get_int : field size %i unknown", size);
     return 0;
     break;
   }
@@ -214,30 +225,36 @@ gint32 ltt_event_get_int(LttEvent *e, struct marker_field *f)
 guint64 ltt_event_get_long_unsigned(LttEvent *e, struct marker_field *f)
 {
   gboolean reverse_byte_order;
+  struct LttField *eventfield;
+  int offset, size;
+
   if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) {
     reverse_byte_order = (g_ntohs(0x1) != 0x1);
   } else {
     reverse_byte_order = LTT_GET_BO(e->tracefile);
   }
   
-  switch(f->size) {
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  size = eventfield->size;
+  switch(size) {
   case 1:
     {
-      guint8 x = *(guint8 *)(e->data + f->offset);
-      return (guint64) x;    
+      guint8 x = *(guint8 *)(e->data + offset);
+      return (guint64) x;
     }
     break;
   case 2:
-    return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset);
+    return (guint64)ltt_get_uint16(reverse_byte_order, e->data + offset);
     break;
   case 4:
-    return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset);
+    return (guint64)ltt_get_uint32(reverse_byte_order, e->data + offset);
     break;
   case 8:
-    return ltt_get_uint64(reverse_byte_order, e->data + f->offset);
+    return ltt_get_uint64(reverse_byte_order, e->data + offset);
     break;
   default:
-    g_critical("ltt_event_get_long_unsigned : field size %li unknown", f->size);
+    g_critical("ltt_event_get_long_unsigned : field size %i unknown", size);
     return 0;
     break;
   }
@@ -246,30 +263,36 @@ guint64 ltt_event_get_long_unsigned(LttEvent *e, struct marker_field *f)
 gint64 ltt_event_get_long_int(LttEvent *e, struct marker_field *f)
 {
   gboolean reverse_byte_order;
+  struct LttField *eventfield;
+  int offset, size;
+
   if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) {
     reverse_byte_order = (g_ntohs(0x1) != 0x1);
   } else {
     reverse_byte_order = LTT_GET_BO(e->tracefile);
   }
   
-  switch(f->size) {
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  size = eventfield->size;
+  switch(size) {
   case 1:
     {
-      gint8 x = *(gint8 *)(e->data + f->offset);
+      gint8 x = *(gint8 *)(e->data + offset);
       return (gint64) x;    
     }
     break;
   case 2:
-    return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset);
+    return (gint64)ltt_get_int16(reverse_byte_order, e->data + offset);
     break;
   case 4:
-    return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset);
+    return (gint64)ltt_get_int32(reverse_byte_order, e->data + offset);
     break;
   case 8:
-    return ltt_get_int64(reverse_byte_order, e->data + f->offset);
+    return ltt_get_int64(reverse_byte_order, e->data + offset);
     break;
   default:
-    g_critical("ltt_event_get_long_int : field size %li unknown", f->size);
+    g_critical("ltt_event_get_long_int : field size %i unknown", size);
     return 0;
     break;
   }
@@ -279,6 +302,9 @@ gint64 ltt_event_get_long_int(LttEvent *e, struct marker_field *f)
 float ltt_event_get_float(LttEvent *e, struct marker_field *f)
 {
   gboolean reverse_byte_order;
+  struct LttField *eventfield;
+  int offset, size;
+
   if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) {
     reverse_byte_order = (g_ntohs(0x1) != 0x1);
   } else {
@@ -286,11 +312,14 @@ float ltt_event_get_float(LttEvent *e, struct marker_field *f)
     reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
   }
 
-  g_assert(f->field_type.type_class == LTT_FLOAT && f->size == 4);
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  size = eventfield->size;
+  g_assert(f->field_type.type_class == LTT_FLOAT && size == 4);
 
-  if(reverse_byte_order == 0) return *(float *)(e->data + f->offset);
+  if(reverse_byte_order == 0) return *(float *)(e->data + offset);
   else{
-    void *ptr = e->data + f->offset;
+    void *ptr = e->data + offset;
     guint32 value = bswap_32(*(guint32*)ptr);
     return *(float*)&value;
   }
@@ -299,6 +328,9 @@ float ltt_event_get_float(LttEvent *e, struct marker_field *f)
 double ltt_event_get_double(LttEvent *e, struct marker_field *f)
 {
   gboolean reverse_byte_order;
+  struct LttField *eventfield;
+  int offset, size;
+
   if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) {
     reverse_byte_order = (g_ntohs(0x1) != 0x1);
   } else {
@@ -306,14 +338,17 @@ double ltt_event_get_double(LttEvent *e, struct marker_field *f)
     reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
   }
 
-  if(f->size == 4)
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  size = eventfield->size;
+  if(size == 4)
     return ltt_event_get_float(e, f);
     
-  g_assert(f->field_type.type_class == LTT_FLOAT && f->size == 8);
+  g_assert(f->field_type.type_class == LTT_FLOAT && size == 8);
 
-  if(reverse_byte_order == 0) return *(double *)(e->data + f->offset);
+  if(reverse_byte_order == 0) return *(double *)(e->data + offset);
   else {
-    void *ptr = e->data + f->offset;
+    void *ptr = e->data + offset;
     guint64 value = bswap_64(*(guint64*)ptr);
     return *(double*)&value;
   }
@@ -326,11 +361,16 @@ double ltt_event_get_double(LttEvent *e, struct marker_field *f)
  ****************************************************************************/
 gchar *ltt_event_get_string(LttEvent *e, struct marker_field *f)
 {
+  struct LttField *eventfield;
+  int offset;
+
   g_assert(f->type == LTT_TYPE_STRING);
 
   //caused memory leaks
   //return (gchar*)g_strdup((gchar*)(e->data + f->offset));
-  return (gchar*)(e->data + f->offset);
+  eventfield = ltt_event_field(e, marker_field_get_index(f));
+  offset = eventfield->offset;
+  return (gchar*)(e->data + offset);
 }
 
 
index 8293d15fcf59c59c010604d2527a8037e95a034c..456f229edf5736fe83ad6815d6a3fb4adcd853de 100644 (file)
 
 struct marker_field;
 
+struct LttField {
+  int offset;
+  int size;
+};
+
 /*
  * Structure LttEvent and LttEventPosition must begin with the _exact_ same
  * fields in the exact same order. LttEventPosition is a parent of LttEvent.
@@ -31,6 +36,7 @@ struct LttEvent {
        LttTime event_time;
 
        void *data;             /* event data */
+       GArray *fields_offsets; /* current field offsets table */
        guint data_size;
        guint event_size;       /* event_size field of the header :
                                   used to verify data_size from marker. */
@@ -108,4 +114,9 @@ static inline LttCycleCount ltt_event_cycle_count(const LttEvent *e)
   return e->tsc;
 }
 
+static inline struct LttField *ltt_event_field(const LttEvent *e, int index)
+{
+       return &g_array_index(e->fields_offsets, struct LttField, index);
+}
+
 #endif //_LTT_EVENT_H
index 252bd8925fc7b4ee0b001474787d1f02488a0ad9..7092b92b2c7dac39966a9e45317cb9e9c8b68164 100644 (file)
@@ -19,11 +19,18 @@ enum ltt_type {
        LTT_TYPE_NONE,
 };
 
+/*
+ * Fields "offset" and "size" below are only valid while the event is being
+ * read. They are also being shared with events of the same type coming from
+ * other per-cpu tracefiles. Therefore, the "LttEvent" fields_offsets offset and
+ * size should be used rather than these.
+ */
 struct marker_field {
   GQuark name;
   enum ltt_type type;
-  unsigned long offset; /* offset in the event data */
-  unsigned long size;
+  unsigned int index;  /* Field index within the event */
+  unsigned long _offset; /* offset in the event data, USED ONLY INTERNALLY BY LIB */
+  unsigned long _size; /* size of field. USED ONLY INTERNALLY BY LIB */
   unsigned long alignment;
   unsigned long attributes;
   int static_offset;   /* boolean - private - is the field offset statically
@@ -41,9 +48,17 @@ static inline enum ltt_type marker_field_get_type(struct marker_field *field)
        return field->type;
 }
 
-static inline unsigned long marker_field_get_size(struct marker_field *field)
+/*
+ * Returns 0 if size is not known statically.
+ */
+static inline long marker_field_get_size(struct marker_field *field)
+{
+       return field->_size;
+}
+
+static inline unsigned int marker_field_get_index(struct marker_field *field)
 {
-       return field->size;
+       return field->index;
 }
 
 #endif //_LTT_MARKERS_FIELD_H
index 07b5c08efe41a0b17873cf6f552bb277be5c0fe1..ade05e16a0a256a02e2688f2f01da55f03a4d17a 100644 (file)
@@ -250,30 +250,31 @@ static inline long add_type(struct marker_info *info,
     field->name = g_quark_from_string(tmpname);
   }
   field->type = trace_type;
+  field->index = info->fields->len-1;
   field->fmt = g_string_new(field_fmt->str);
 
   switch (trace_type) {
   case LTT_TYPE_SIGNED_INT:
   case LTT_TYPE_UNSIGNED_INT:
   case LTT_TYPE_POINTER:
-    field->size = trace_size;
+    field->_size = trace_size;
     field->alignment = trace_size;
     info->largest_align = max((guint8)field->alignment,
                               (guint8)info->largest_align);
     field->attributes = attributes;
     if (offset == -1) {
-      field->offset = -1;
+      field->_offset = -1;
       field->static_offset = 0;
       return -1;
     } else {
-      field->offset = offset + ltt_align(offset, field->alignment,
+      field->_offset = offset + ltt_align(offset, field->alignment,
                                          info->alignment);
       field->static_offset = 1;
-      return field->offset + trace_size;
+      return field->_offset + trace_size;
     }
   case LTT_TYPE_STRING:
-    field->offset = offset;
-    field->size = 0;  /* Variable length, size is 0 */
+    field->_offset = offset;
+    field->_size = 0;  /* Variable length, size is 0 */
     field->alignment = 1;
     if (offset == -1)
       field->static_offset = 0;
@@ -296,7 +297,7 @@ long marker_update_fields_offsets(struct marker_info *info, const char *data)
   for (i = info->fields->len - 1; i >= 0; i--) {
     field = &g_array_index(info->fields, struct marker_field, i);
     if (field->static_offset) {
-      offset = field->offset;
+      offset = field->_offset;
       break;
     }
   }
@@ -308,12 +309,12 @@ long marker_update_fields_offsets(struct marker_info *info, const char *data)
     case LTT_TYPE_SIGNED_INT:
     case LTT_TYPE_UNSIGNED_INT:
     case LTT_TYPE_POINTER:
-      field->offset = offset + ltt_align(offset, field->alignment,
+      field->_offset = offset + ltt_align(offset, field->alignment,
                                           info->alignment);
-      offset = field->offset + field->size;
+      offset = field->_offset + field->_size;
       break;
     case LTT_TYPE_STRING:
-      field->offset = offset;
+      field->_offset = offset;
       offset = offset + strlen(&data[offset]) + 1;
       // not aligning on pointer size, breaking genevent backward compatibility.
       break;
@@ -325,6 +326,24 @@ long marker_update_fields_offsets(struct marker_info *info, const char *data)
   return offset;
 }
 
+void marker_update_event_fields_offsets(GArray *fields_offsets,
+                                       struct marker_info *info)
+{
+  unsigned int i;
+
+  g_array_set_size(fields_offsets, info->fields->len);
+  for (i = 0; i < info->fields->len; i++) {
+    struct marker_field *mfield =
+      &g_array_index(info->fields, struct marker_field, i);
+    struct LttField *eventfield =
+      &g_array_index(fields_offsets, struct LttField, i);
+    eventfield->offset = mfield->_offset;
+    eventfield->size = mfield->_size;
+    g_assert(eventfield->offset != -1);
+    g_assert(eventfield->size != -1);
+  }
+}
+
 static void format_parse(const char *fmt, struct marker_info *info)
 {
   char trace_size = 0, c_size = 0;  /*
index 54da74705ef6dd1b9d00de71181394502d95d2b4..0d8a248eb859900525e528445520119247ecc485 100644 (file)
@@ -55,6 +55,8 @@
 
 /* from marker.c */
 extern long marker_update_fields_offsets(struct marker_info *info, const char *data);
+extern void marker_update_event_fields_offsets(GArray *fields_offsets,
+                                              struct marker_info *info);
 
 /* Tracefile names used in this file */
 
@@ -333,7 +335,13 @@ static gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
     perror("Cannot map block for tracefile");
     goto close_file;
   }
-  
+  /* Create fields offset table */
+  tf->event.fields_offsets = g_array_sized_new(FALSE, FALSE,
+                                               sizeof(struct LttField), 1);
+  if (!tf->event.fields_offsets)
+    goto close_file;
+
   return 0;
 
   /* Error */
@@ -376,6 +384,7 @@ static void ltt_tracefile_close(LttTracefile *t)
   close(t->fd);
   if (t->buf_index)
     g_array_free(t->buf_index, TRUE);
+  g_array_free(t->event.fields_offsets, TRUE);
 }
 
 /****************************************************************************
@@ -1593,8 +1602,9 @@ void ltt_update_event_size(LttTracefile *tf)
     if (info->size != -1)
       size = info->size;
     else
-      size = marker_update_fields_offsets(marker_get_info_from_id(tf->mdata,
-                                   tf->event.event_id), tf->event.data);
+      size = marker_update_fields_offsets(info, tf->event.data);
+    /* Update per-tracefile offsets */
+    marker_update_event_fields_offsets(tf->event.fields_offsets, info);
   }
 
   tf->event.data_size = size;
This page took 0.03343 seconds and 4 git commands to generate.