all needed functions should be done.
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 12 Aug 2005 19:31:06 +0000 (19:31 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 12 Aug 2005 19:31:06 +0000 (19:31 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1008 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/ltt-newlib/event.c
ltt/branches/poly/ltt-newlib/facility.c
ltt/branches/poly/ltt-newlib/ltt-private.h
ltt/branches/poly/ltt-newlib/ltt.h
ltt/branches/poly/ltt-newlib/trace.h
ltt/branches/poly/ltt-newlib/tracefile.c
ltt/branches/poly/ltt-newlib/type.c
ltt/branches/poly/ltt-newlib/type.h

index 02ecf271de2ab614df1201bd569e24dbed514004..d38095e485a84ec9d5a9ee302fdf225d98cf37af 100644 (file)
@@ -46,6 +46,8 @@ void ltt_event_destroy(LttEvent *event)
 }
 
 
+#if 0
+/* Use get_field_type_size instead */
 /*****************************************************************************
  *Function name
  *    ltt_event_refresh_fields   : refresh fields of an event 
@@ -172,6 +174,8 @@ int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
 
   return size;
 }
+#endif //0
+
 
 /*****************************************************************************
  *Function name
@@ -217,7 +221,7 @@ LttEventType *ltt_event_eventtype(LttEvent *e)
 {
   LttFacility* facility = ltt_event_facility(e);
   if(!facility) return NULL;
-  return facility->events[e->event_id - facility->base_id];
+  return &g_array_index(facility->events, LttEventType, e->event_id);
 }
 
 /*****************************************************************************
@@ -237,17 +241,6 @@ LttField *ltt_event_field(LttEvent *e)
   field = event_type->root_field;
   if(unlikely(!field)) return NULL;
 
-  //check if the field need refresh
-  if(likely(e->which_block != event_type->latest_block ||
-            e->which_event != event_type->latest_event)){
-
-    event_type->latest_block = e->which_block;
-    event_type->latest_event = e->which_event;
-    
-    if(unlikely(field->field_fixed != 1))
-      ltt_event_refresh_fields(0, 0, field, e->data,
-          e->tracefile->trace->reverse_byte_order);
-  }
   return field;
 }
 
@@ -276,7 +269,7 @@ LttTime ltt_event_time(LttEvent *e)
 
 LttCycleCount ltt_event_cycle_count(LttEvent *e)
 {
-  return e->event_cycle_count;
+  return e->tsc;
 }
 
 /*****************************************************************************
@@ -289,24 +282,10 @@ LttCycleCount ltt_event_cycle_count(LttEvent *e)
 
 void ltt_event_position(LttEvent *e, LttEventPosition *ep)
 {
-  ep->block_num         = e->which_block;
-  ep->event_num         = e->which_event;
-  ep->event_time        = e->event_time;
-  ep->event_cycle_count = e->event_cycle_count;
-  ep->heart_beat_number = e->tracefile->cur_heart_beat_number;
-  ep->old_position      = TRUE;
-  ep->event_offset      = e->data - e->tracefile->buffer - EVENT_HEADER_SIZE ;
-  ep->tf                = e->tracefile;
-  ep->overflow_nsec     = e->overflow_nsec;
-  /* This is a workaround for fast position seek */
-  ep->last_event_pos = e->last_event_pos;
-  ep->prev_block_end_time = e->prev_block_end_time;
-  ep->prev_event_time = e->prev_event_time;
-  ep->pre_cycle_count = e->pre_cycle_count;
-  ep->count = e->count;
-  ep->last_heartbeat = e->last_heartbeat;
-
-  /* end of workaround */
+  ep->tracefile = e->tracefile;
+  ep->block = e->block;
+  ep->offset = e->offset;
+  ep->tsc = e->tsc;
 }
 
 LttEventPosition * ltt_event_position_new()
@@ -314,44 +293,6 @@ LttEventPosition * ltt_event_position_new()
   return g_new(LttEventPosition, 1);
 }
 
-/*****************************************************************************
- *Function name
- *    ltt_event_position_get : get the block number and index of the event
- *Input params
- *    ep                     : a pointer to event's position structure
- *    block_number           : the block number of the event
- *    index_in_block         : the index of the event within the block
- ****************************************************************************/
-
-void ltt_event_position_get(LttEventPosition *ep,
-    unsigned *block_number, unsigned *index_in_block, LttTracefile ** tf)
-{
-  *block_number   = ep->block_num;
-  *index_in_block = ep->event_num;
-  *tf             = ep->tf;
-}
-
-/*****************************************************************************
- *Function name
- *    ltt_event_position_set : set the block number and index of the event
- *    It does put the old_position gboolean to FALSE, as it is impossible
- *    to know the quick position to seek in the tracefile.
- *Input params
- *    ep                     : a pointer to event's position structure
- *    block_number           : the block number of the event
- *    index_in_block         : the index of the event within the block
- ****************************************************************************/
-
-void ltt_event_position_set(LttEventPosition *ep,
-    unsigned block_number, unsigned index_in_block)
-{
-  if(ep->block_num != block_number || ep->event_num != index_in_block)
-    ep->old_position = FALSE;
-
-  ep->block_num = block_number;
-  ep->event_num = index_in_block;
-  
-}
 
 /*****************************************************************************
  * Function name
@@ -370,58 +311,23 @@ void ltt_event_position_set(LttEventPosition *ep,
 gint ltt_event_position_compare(const LttEventPosition *ep1,
                                 const LttEventPosition *ep2)
 {
-  if(ep1->tf != ep2->tf)
-    g_error("ltt_event_position_compare on different tracefiles makes no sense");
   if(ep1 == NULL && ep2 == NULL)
       return 0;
   if(ep1 != NULL && ep2 == NULL)
       return -1;
   if(ep1 == NULL && ep2 != NULL)
       return 1;
-    
-  if(ep1->block_num < ep2->block_num)
-    return -1;
-  if(ep1->block_num > ep2->block_num)
-    return 1;
-  if(ep1->event_num < ep2->event_num)
-    return -1;
-  if(ep1->event_num > ep2->event_num)
-    return 1;
-  return 0;
-}
 
-/*****************************************************************************
- * Function name
- *    ltt_event_event_position_compare : compare two positions, one in event,
- *    other in position opaque structure.
- * Input params
- *    event                  : a pointer to event structure
- *    ep                     : a pointer to event's position structure
- * Return
- *    -1 is event < ep
- *    1 if event > ep
- *    0 if event == ep
- ****************************************************************************/
-
-gint ltt_event_event_position_compare(const LttEvent *event,
-                                      const LttEventPosition *ep)
-{
-  if(event == NULL && ep == NULL)
-      return 0;
-  if(event != NULL && ep == NULL)
-      return -1;
-  if(event == NULL && ep != NULL)
-      return 1;
-
-  g_assert(event->tracefile == ep->tf);
-  if(event->which_block < ep->block_num)
+   if(ep1->tracefile != ep2->tracefile)
+    g_error("ltt_event_position_compare on different tracefiles makes no sense");
+   
+  if(ep1->block < ep2->block)
     return -1;
-  if(event->which_block > ep->block_num)
+  if(ep1->block > ep2->block)
     return 1;
-  if(event->which_event < ep->event_num)
+  if(ep1->offset < ep2->offset)
     return -1;
-  if(event->which_event > ep->event_num)
+  if(ep1->offset > ep2->offset)
     return 1;
   return 0;
 }
@@ -455,23 +361,8 @@ void ltt_event_position_copy(LttEventPosition *dest,
  ****************************************************************************/
 
 unsigned ltt_event_cpu_id(LttEvent *e)
-{ 
-  gchar * c1, * c2, * c3;
-  c1 = strrchr(e->tracefile->name,'\\');
-  c2 = strrchr(e->tracefile->name,'/');
-  if(c1 == NULL && c2 == NULL){
-    return (unsigned)atoi(e->tracefile->name);
-  }else if(c1 == NULL){
-    c2++;
-    return (unsigned)atoi(c2);    
-  }else if(c2 == NULL){
-    c1++;
-    return (unsigned)atoi(c1);    
-  }else{
-    c3 = (c1 > c2) ? c1 : c2;
-    c3++;
-    return (unsigned)atoi(c3);        
-  }
+{
+  return e->tracefile->cpu_num;
 }
 
 /*****************************************************************************
@@ -500,7 +391,6 @@ void *ltt_event_data(LttEvent *e)
  *Return value
  *    unsigned       : the number of elements for an array/sequence field
  ****************************************************************************/
-
 unsigned ltt_event_field_element_number(LttEvent *e, LttField *f)
 {
   if(f->field_type->type_class != LTT_ARRAY &&
@@ -509,7 +399,7 @@ unsigned ltt_event_field_element_number(LttEvent *e, LttField *f)
   
   if(f->field_type->type_class == LTT_ARRAY)
     return f->field_type->element_number;
-  return (unsigned)  getIntNumber(e->tracefile->trace->reverse_byte_order,
+  return (unsigned)  get_unsigned(LTT_GET_BO(e->tracefile),
       f->sequ_number_size, e + f->offset_root);
 }
 
@@ -523,14 +413,13 @@ unsigned ltt_event_field_element_number(LttEvent *e, LttField *f)
  *    f              : a field of the instance
  *    i              : the ith element
  ****************************************************************************/
-
 void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
 {
   unsigned element_number;
   LttField *fld;
   unsigned int k;
-  int size;
-  void *evD;
+  size_t size;
+  void *data;
  
   if(f->field_type->type_class != LTT_ARRAY &&
      f->field_type->type_class != LTT_SEQUENCE)
@@ -543,11 +432,11 @@ void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
   
   fld = f->child[0];
   
-  evD = e->data + f->offset_root;
+  data = e->data + f->offset_root;
   size = 0;
   for(k=0;k<i;k++){
     size += ltt_event_refresh_fields(f->offset_root+size,size, fld, evD+size,
-                                e->tracefile->trace->reverse_byte_order);
+                                LTT_GET_BO(e->tracefile));
   }
   f->current_element = i - 1;
 }
@@ -556,12 +445,9 @@ void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
  * These functions extract data from an event after architecture specific
  * conversions
  ****************************************************************************/
-
 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
 {
-  //int revFlag = e->tracefile->trace->my_arch_endian == 
-  //              e->tracefile->trace->system_description->endian ? 0:1;
-  gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
 
   LttTypeEnum t = f->field_type->type_class;
 
@@ -590,9 +476,7 @@ guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
 
 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
 {
-  gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
-  //int revFlag = e->tracefile->trace->my_arch_endian == 
-  //              e->tracefile->trace->system_description->endian ? 0:1;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
 
   g_assert(f->field_type->type_class == LTT_INT);
 
@@ -619,9 +503,8 @@ gint32 ltt_event_get_int(LttEvent *e, LttField *f)
 
 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
 {
-  gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
-  //int revFlag = e->tracefile->trace->my_arch_endian == 
-  //              e->tracefile->trace->system_description->endian ? 0:1;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
+
   LttTypeEnum t = f->field_type->type_class;
 
   g_assert(t == LTT_UINT || t == LTT_ENUM);
@@ -644,7 +527,7 @@ gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
 {
   //int revFlag = e->tracefile->trace->my_arch_endian == 
   //              e->tracefile->trace->system_description->endian ? 0:1;
-  gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
 
   g_assert( f->field_type->type_class == LTT_INT);
 
@@ -664,9 +547,7 @@ gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
 
 float ltt_event_get_float(LttEvent *e, LttField *f)
 {
-  //int revFlag = e->tracefile->trace->my_arch_endian == 
-  //              e->tracefile->trace->system_description->endian ? 0:1;
-  gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
 
   g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 4);
 
@@ -681,9 +562,7 @@ float ltt_event_get_float(LttEvent *e, LttField *f)
 
 double ltt_event_get_double(LttEvent *e, LttField *f)
 {
-  gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
-  //int revFlag = e->tracefile->trace->my_arch_endian == 
-  //              e->tracefile->trace->system_description->endian ? 0:1;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
 
   g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 8);
 
@@ -700,7 +579,6 @@ double ltt_event_get_double(LttEvent *e, LttField *f)
  * The string obtained is only valid until the next read from
  * the same tracefile.
  ****************************************************************************/
-
 char *ltt_event_get_string(LttEvent *e, LttField *f)
 {
   g_assert(f->field_type->type_class == LTT_STRING);
index dac585dcf200fd58848532522f49fa683925d590..9eb5627f562665402a41033aee6bc9ea38f0d5af 100644 (file)
@@ -255,10 +255,10 @@ void constructTypeAndFields(LttFacility * fac, type_descriptor * td,
 
   if(td->type == LTT_ENUM){
     fld->field_type->element_number = td->labels.position;
-    fld->field_type->enum_strings = g_new(char*,td->labels.position);
+    fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
     for(i=0;i<td->labels.position;i++){
       fld->field_type->enum_strings[i] 
-                          = g_strdup(((char*)(td->labels.array[i])));
+                     = g_quark_from_string(((char*)(td->labels.array[i])));
     }
   }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
     if(td->type == LTT_ARRAY)
@@ -419,8 +419,6 @@ void freeLttType(LttType ** type)
   if((*type)->fmt)
     g_free((*type)->fmt);
   if((*type)->enum_strings){
-    for(i=0;i<(*type)->element_number;i++)
-      g_free((*type)->enum_strings[i]);
     g_free((*type)->enum_strings);
   }
 
index e2317591dcf7519cb0a3ab0684e1e85fa8407166..4c86aaf027fdf0ba233f5089036d995676d951d5 100644 (file)
 /* Hardcoded facilities */
 #define LTT_FACILITY_CORE 0
 
-/* Hardcoded events */
+/* Hardcoded core events */
 enum ltt_core_events {
     LTT_EVENT_FACILITY_LOAD,
     LTT_EVENT_FACILITY_UNLOAD,
-    LTT_EVENT_STATE_DUMP_FACILITY_LOAD
-};
-
-/* Hardcoded events */
-enum ltt_heartbeat_events {
+    LTT_EVENT_STATE_DUMP_FACILITY_LOAD,
     LTT_EVENT_HEARTBEAT
 };
 
 
-
-
 #if 0
 /* enumeration definition */
 
@@ -102,6 +96,15 @@ struct LttFacilityUnload {
   guint32 id;
 };
 
+struct LttStateDumpFacilityLoad {
+  guint32 checksum;
+  guint32 id;
+  guint32 long_size;
+  guint32 pointer_size;
+  guint32 size_t_size;
+  guint32 alignment;
+};
+
 
 
 typedef struct _TimeHeartbeat {
@@ -173,13 +176,20 @@ struct _LttEventType{
   LttField * root_field;  //root field
 };
 
+/* Structure LttEvent and LttEventPosition must begin with the _exact_ same
+ * fields in the exact same order. LttEventPosition is a parent of LttEvent. */
 struct _LttEvent{
   
-  /* Where is this event ? */
+  /* Begin of LttEventPosition fields */
   LttTracefile  *tracefile;
   unsigned int  block;
   void          *offset;
+
+  /* Timekeeping */
+  uint64_t                tsc;       /* Current timestamp counter */
   
+  /* End of LttEventPosition fields */
+
        union {                                                                                 /* choice by trace has_tsc */
          guint32  timestamp;                           /* truncated timestamp */
        guint32  delta;
@@ -194,43 +204,59 @@ struct _LttEvent{
 
   int      count;                    //the number of overflow of cycle count
   gint64 overflow_nsec;              //precalculated nsec for overflows
-  TimeHeartbeat * last_heartbeat;    //last heartbeat
 };
 
+struct _LttEventPosition{
+  LttTracefile  *tracefile;
+  unsigned int  block;
+  void          *offset;
+  
+  /* Timekeeping */
+  uint64_t                tsc;       /* Current timestamp counter */
+};
+
+
+enum field_status { FIELD_UNKNOWN, FIELD_VARIABLE, FIELD_FIXED };
 
 struct _LttField{
-  unsigned field_pos;        //field position within its parent
+  //guint field_pos;           //field position within its parent
   LttType * field_type;      //field type, if it is root field
                              //then it must be struct type
 
   off_t offset_root;         //offset from the root, -1:uninitialized 
-  short fixed_root;          //offset fixed according to the root
+  enum field_status fixed_root;          //offset fixed according to the root
                              //-1:uninitialized, 0:unfixed, 1:fixed
   off_t offset_parent;       //offset from the parent,-1:uninitialized
-  short fixed_parent;        //offset fixed according to its parent
+  enum field_status fixed_parent;        //offset fixed according to its parent
                              //-1:uninitialized, 0:unfixed, 1:fixed
   //  void * base_address;       //base address of the field  ????
   
-  int  field_size;           //>0: size of the field, 
-                             //0 : uncertain
-                             //-1: uninitialize
-  int sequ_number_size;      //the size of unsigned used to save the
+  guint field_size;     //      //>0: size of the field, 
+                          //   //0 : uncertain
+                           //  //-1: uninitialize
+  enum field_status fixed_size;
+
+  /* for sequence */
+  gint sequ_number_size;      //the size of unsigned used to save the
                              //number of elements in the sequence
 
-  int element_size;          //the element size of the sequence
-  int field_fixed;           //0: field has string or sequence
+  gint element_size;          //the element size of the sequence
+  //int field_fixed;           //0: field has string or sequence
                              //1: field has no string or sequenc
                              //-1: uninitialize
 
   struct _LttField * parent;
-  struct _LttField ** child; //for array, sequence and struct
+  struct _LttField ** child; //for array, sequence, struct and union
                              //list of fields, it may have only one
-                             //field if the element is not a struct 
+                             //field if the element is not a struct or
+                             //union
   unsigned current_element;  //which element is currently processed
+                             // Used for sequences and arrays.
 };
 
 
 struct _LttFacility{
+  LttTrace  *trace;
   //gchar * name;               //facility name 
   GQuark name;
   guint32 checksum;      //checksum of the facility 
@@ -241,10 +267,10 @@ struct _LttFacility{
   guint32 alignment;
 
 
-  LttEventType ** events;    //array of event types 
-  unsigned int event_number;          //number of events in the facility 
-  LttType ** named_types;
-  unsigned int named_types_number;
+  //LttEventType ** events;    //array of event types 
+  //unsigned int event_number;          //number of events in the facility 
+  //LttType ** named_types;
+  //unsigned int named_types_number;
 
   GArray *events;
   GData *events_by_name;
@@ -277,6 +303,7 @@ typedef struct _LttBuffer {
 struct _LttTracefile{
   gboolean cpu_online;               //is the cpu online ?
   GQuark name;                       //tracefile name
+  guint cpu_num;                     //cpu number of the tracefile
   LttTrace * trace;                  //trace containing the tracefile
   int fd;                            //file descriptor 
   off_t file_size;                   //file size
@@ -323,15 +350,6 @@ struct _LttTrace{
   GData     *tracefiles;                    //tracefiles groups
 };
 
-struct _LttEventPosition{
-  LttTracefile  *tracefile;
-  unsigned int  block;
-  void          *offset;
-  
-  /* Timekeeping */
-  uint64_t                tsc;       /* Current timestamp counter */
-};
-
 /* The characteristics of the system on which the trace was obtained
    is described in a LttSystemDescription structure. */
 
@@ -349,7 +367,6 @@ struct _LttSystemDescription {
   gchar *processor;
   gchar *hardware_platform;
   gchar *operating_system;
-  //unsigned ltt_block_size;
   LttTime trace_start;
   LttTime trace_end;
 };
index 0aa6daf9cd03c236fd74a3d50dd21ae5840af471..4434f8cf74d79d4dcbf0a99de9abb209863c66c0 100644 (file)
@@ -127,7 +127,8 @@ typedef enum _LttArchEndian
 } LttArchEndian;
 
 typedef enum _LttTypeEnum 
-{ LTT_INT, LTT_UINT, LTT_FLOAT, LTT_STRING, LTT_ENUM, LTT_ARRAY, 
+{ LTT_INT, LTT_UINT, LTT_POINTER, LTT_LONG, LTT_ULONG, LTT_SIZE_T, 
+  LTT_SSIZE_T, LTT_OFF_T, LTT_FLOAT, LTT_STRING, LTT_ENUM, LTT_ARRAY, 
   LTT_SEQUENCE, LTT_STRUCT, LTT_UNION
 } LttTypeEnum;
 
index 1cf3525159f7ba8a51ac6da2580af7f4e8f5ef20..1956bb7856648f422b1d94e5a0b9e2049edb08d3 100644 (file)
@@ -154,9 +154,7 @@ gint ltt_tracefile_open_control(LttTrace *t, gchar * control_name);
 void getDataEndianType(LttArchSize * size, LttArchEndian * endian);
 
 /* get an integer number */
-
-gint64 getIntNumber(gboolean reverse_byte_order, int size1, void *evD);
-
+gint64 get_int(gboolean reverse_byte_order, gint size, void *data);
 
 /* get the node name of the system */
 
index ee98502a02671b9aa2e66fb1b590569a7fcd9905..0fce811c7c42249a13cadc773852de1e0f99c208 100644 (file)
@@ -74,19 +74,29 @@ static inline LttTime getEventTime(LttTracefile * tf);
 
 /* set the offset of the fields belonging to the event,
    need the information of the archecture */
-void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace *t);
+void set_fields_offsets(LttTracefile *tf, LttEventType *event_type);
+size_t get_fields_offsets(LttTracefile *tf, LttEventType *event_type, void *data);
+
+/* get the size of the field type according to 
+ * The facility size information. */
+static inline void preset_field_type_size(LttTracefile *tf,
+    LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    enum field_status *fixed_root, enum field_status *fixed_parent,
+    LttField *field)
+
+
+static inline size_t get_field_type_size(LttTracefile *tf,
+    LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    LttField *field, void *data)
 
-/* get the size of the field type according to the archtecture's
-   size and endian type(info of the archecture) */
-static inline gint getFieldtypeSize(LttTracefile * tf,
-         LttEventType * evT, gint offsetRoot,
-                    gint offsetParent, LttField *fld, void *evD, LttTrace* t);
 
 /* map a fixed size or a block information from the file (fd) */
 int map_block(LttTracefile * tf, unsigned int block_num);
 
-/* calculate cycles per nsec for current block */
-void getCyclePerNsec(LttTracefile * t);
+/* calculate nsec per cycles for current block */
+static double calc_nsecs_per_cycle(LttTracefile * t);
 
 /* go to the next event */
 static int ltt_seek_next_event(LttTracefile *tf);
@@ -166,6 +176,15 @@ static void  parser_characters   (GMarkupParseContext __UNUSED__ *context,
   des->description = g_strdup(text);
 }
 
+static inline LttFacility *ltt_trace_get_facility_by_num(LttTrace *t,
+    guint num)
+{
+  g_assert(num < t->facilities_by_num->len);
+  
+  return &g_array_index(t->facilities_by_num, LttFacility, num);
+
+}
+
 
 /*****************************************************************************
  *Function name
@@ -627,6 +646,7 @@ static int open_tracefiles(LttTrace *trace, char *root_path, GData *tracefiles)
         continue; /* error opening the tracefile : bad magic number ? */
       }
       tf->cpu_online = 1;
+      tf->cpu_num = num;
                }
        }
        
@@ -652,6 +672,7 @@ static int ltt_get_facility_description(LttFacility *f,
   char *text;
   guint textlen;
   gint err;
+  int i, j;
 
   text = g_quark_to_string(t->pathname);
   textlen = strlen(text);
@@ -688,6 +709,17 @@ static int ltt_get_facility_description(LttFacility *f,
   err = ltt_facility_open(f, t, desc_file_name);
   if(err) goto facility_error;
   
+  for(i=0;i<t->facilities_by_num->len;i++){
+    f = &g_array_index(t->facilities_by_num, LttFacility, i);
+    if(f->exists) {
+      for(j=0; j<f->events->len; j++){
+        et = &g_array_index(f->events, LttEventType, j);
+        setFieldsOffset(NULL, et, NULL);
+      }
+    }
+  }
+
+
   return 0;
 
 facility_error:
@@ -770,7 +802,8 @@ static int ltt_process_facility_tracefile(LttTracefile *tf)
 
           if(ltt_get_facility_description(fac, tf->trace))
             goto facility_error;
-
+          
+          fac->trace = tf->trace;
           fac->exists = 1;
 
           fac_ids = g_datalist_get_data(tf->facilities_by_name, fac->name);
@@ -881,9 +914,6 @@ LttTrace *ltt_trace_open(const gchar *pathname)
 
   g_datalist_init(t->tracefiles_by_name);
   
-  /* Load trace XML event descriptions */
-  //TODO
-  
   /* Parse each trace control/facilitiesN files : get runtime fac. info */
   group = g_datalist_get_data(t->tracefiles, LTT_TRACEFILE_NAME_FACILITIES);
   if(group == NULL) {
@@ -929,52 +959,12 @@ LttTrace *ltt_trace_copy(LttTrace *self)
   return ltt_trace_open(self->pathname);
 }
 
-//FIXME TODO
 void ltt_trace_close(LttTrace *t)
 {
-  unsigned int i;
-  LttTracefile * tf;
-  LttFacility * f;
-
-  g_free(t->pathname);
-  //free system_description
-  g_free(t->system_description->description);
-  g_free(t->system_description->node_name);
-  g_free(t->system_description->domain_name);
-  g_free(t->system_description->kernel_name);
-  g_free(t->system_description->kernel_release);
-  g_free(t->system_description->kernel_version);
-  g_free(t->system_description->machine);
-  g_free(t->system_description->processor);
-  g_free(t->system_description->hardware_platform);
-  g_free(t->system_description->operating_system);
-  g_free(t->system_description);
-
-  //free control_tracefiles
-  for(i=0;i<t->control_tracefile_number;i++){
-    tf = (LttTracefile*)g_ptr_array_index(t->control_tracefiles,i);
-    ltt_tracefile_close(tf);
-  }
-  g_ptr_array_free(t->control_tracefiles, TRUE);
-
-  //free per_cpu_tracefiles
-  for(i=0;i<t->per_cpu_tracefile_number;i++){
-    tf = (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles,i);
-    ltt_tracefile_close(tf);
-  }
-  g_ptr_array_free(t->per_cpu_tracefiles, TRUE);
-
-  //free facilities
-  for(i=0;i<t->facility_number;i++){
-    f = (LttFacility*)g_ptr_array_index(t->facilities,i);
-    ltt_facility_close(f);
-  }
-  g_ptr_array_free(t->facilities, TRUE);
-
+  g_datalist_free(t->tracefiles_by_name);
+  g_array_free(t->facilities_by_num, TRUE);
+  g_datalist_clear(t->tracefiles);
   g_free(t);
-  g_blow_chunks();
 }
 
 
@@ -1004,6 +994,7 @@ GArray *ltt_trace_facility_get_by_name(LttTrace *t, GQuark name)
  * Functions to discover all the event types in the trace 
  ****************************************************************************/
 
+#if 0
 unsigned ltt_trace_eventtype_number(LttTrace *t)
 {
   unsigned int i;
@@ -1017,7 +1008,11 @@ unsigned ltt_trace_eventtype_number(LttTrace *t)
   }
   return count;
 }
+#endif //0
 
+#if 0
+//use an iteration on all the trace facilities, and inside iteration on all the
+//event types in each facilities instead.
 LttEventType *ltt_trace_eventtype_get(LttTrace *t, unsigned evId)
 {
   LttEventType *event_type;
@@ -1030,6 +1025,7 @@ LttEventType *ltt_trace_eventtype_get(LttTrace *t, unsigned evId)
 
   return event_type;
 }
+#endif //0
 
 #if 0
 /*****************************************************************************
@@ -1376,19 +1372,9 @@ int ltt_tracefile_read_op(LttTracefile *tf)
    /* do event specific operation */
 
   /* do something if its an heartbeat event : increment the heartbeat count */
-  if(event->facility_id != 0) { /* except core */
-    f = (LttFacility*)g_ptr_array_index(tf->trace->facilities,
-                                          event->facility_id);
-    g_assert(f != NULL);
-
-    if(unlikely(ltt_facility_name(f)
-          != LTT_FACILITY_NAME_HEARTBEAT)) {
-      LttEventType *et = ltt_facility_eventtype_get_by_name(f, 
-                    LTT_EVENT_NAME_HEARTBEAT);
-      if(et->id == event->event_id)
-        t->cur_heart_beat_number++;
-    }
-  }
+  if(event->facility_id == LTT_FACILITY_CORE)
+    if(event->event_id == LTT_EVENT_HEARTBEAT)
+      t->cur_heart_beat_number++;
   
   return 0;
 }
@@ -1419,10 +1405,12 @@ int ltt_tracefile_read_update_event(LttTracefile *tf)
       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;
     }
 
     event->event_time = ltt_interpolate_time(tf, event);
@@ -1432,6 +1420,7 @@ int ltt_tracefile_read_update_event(LttTracefile *tf)
     event->time.delta = ltt_get_uint32(LTT_GET_BO(tf),
                                           pos);
     tf->buffer.tsc = 0;
+    event->tsc = tf->buffer.tsc;
 
     event->event_time = ltt_time_add(tf->buffer.begin.timestamp,
                                      event->time_delta);
@@ -1504,6 +1493,7 @@ static int map_block(LttTracefile * tf, int block_num)
                                               header->lost_size);
   
   tf->buffer.tsc =  tf->buffer.begin.cycle_count;
+  tf->event.tsc = tf->buffer.tsc;
 
   /* FIXME
    * eventually support variable buffer size : will need a partial pre-read of
@@ -1528,6 +1518,50 @@ map_error:
 
 }
 
+ssize_t ltt_get_event_size(LttTracefile *tf)
+{
+  ssize_t size = 0;
+
+  /* Specific handling of core events : necessary to read the facility control
+   * tracefile. */
+  if(unlikely(tf->event.facility_id == LTT_FACILITY_CORE)) {
+    switch((enum ltt_core_events)tf->event.event_id) {
+  case LTT_EVENT_FACILITY_LOAD:
+    size = sizeof(struct LttFacilityLoad);
+    break;
+  case LTT_EVENT_FACILITY_UNLOAD:
+    size = sizeof(struct LttFacilityUnload);
+    break;
+  case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
+    size = sizeof(struct LttStateDumpFacilityLoad);
+    break;
+  case LTT_EVENT_HEARTBEAT:
+    size = sizeof(TimeHeartbeat);
+    break;
+  default:
+    g_warning("Error in getting event size : tracefile %s, "
+        "unknown event id %hhu in core facility.",
+        g_quark_to_string(tf->name),
+        tf->event.event_id);
+    goto event_id_error;
+
+    }
+
+  } else {
+    LttFacility *f = ltt_trace_get_facility_by_num(tf->trace, 
+                                            tf->event.facility_id);
+    LttEventType *event_type = 
+      ltt_facility_eventtype_get(f, tf->event.event_id);
+    size = get_fields_offsets(tf, event_type, tf->event.data);
+  }
+
+  return size;
+  
+event_id_error:
+  return -1;
+}
+
+
 /* Take the tf current event offset and use the event facility id and event id
  * to figure out where is the next event offset.
  *
@@ -1543,6 +1577,7 @@ static int ltt_seek_next_event(LttTracefile *tf)
 {
   int ret = 0;
   void *pos;
+  ssize_t event_size;
   
   /* seek over the buffer header if we are at the buffer start */
   if(tf->event.offset == tf->buffer.head) {
@@ -1558,11 +1593,11 @@ static int ltt_seek_next_event(LttTracefile *tf)
 
   pos = tf->event.data;
 
-  /* FIXME : do this function. Remember to hardcode the sizes of heartbeat and
-   * core */
-  pos += ltt_facility_get_event_size(tf->event.facility_id, tf->event.event_id);
-  on error : goto error;
+  event_size = ltt_get_event_size(tf);
+  if(event_size < 0) goto error;
 
+  pos += (size_t)event_size;
+  
   tf->event.offset = pos;
 
 found:
@@ -1603,30 +1638,318 @@ static double calc_nsecs_per_cycle(LttTracefile * t)
   return lBufTotalNSec / (double)lBufTotalCycle;
 
 }
+#if 0
+void setFieldsOffset(LttTracefile *tf, LttEventType *evT,void *evD)
+{
+  LttField * rootFld = evT->root_field;
+  //  rootFld->base_address = evD;
+
+  if(likely(rootFld))
+    rootFld->field_size = getFieldtypeSize(tf, evT->facility,
+        evT, 0,0,rootFld, evD);  
+}
+#endif //0
 
 /*****************************************************************************
  *Function name
- *    setFieldsOffset : set offset of the fields
+ *    set_fields_offsets : set the precomputable offset of the fields
  *Input params 
  *    tracefile       : opened trace file  
- *    evT             : the event type
- *    evD             : event data, it may be NULL
+ *    event_type      : the event type
  ****************************************************************************/
 
-void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace* t)
+void set_fields_offsets(LttTracefile *tf, LttEventType *event_type)
 {
-  LttField * rootFld = evT->root_field;
-  //  rootFld->base_address = evD;
+  LttField *field = event_type->root_field;
 
-  if(likely(rootFld))
-    rootFld->field_size = getFieldtypeSize(tf, evT, 0,0,rootFld, evD,t);  
+  if(likely(field))
+    preset_field_type_size(tf, event_type->facility, event_type, 0, 0, 
+        FIELD_FIXED, FIELD_FIXED,
+        field);
+
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    preset_field_type_size : set the fixed sizes of the field type
+ *Input params 
+ *    tf              : tracefile
+ *    event_type      : event type
+ *    offset_root     : offset from the root
+ *    offset_parent   : offset from the parent
+ *    fixed_root      : Do we know a fixed offset to the root ?
+ *    fixed_parent    : Do we know a fixed offset to the parent ?
+ *    field           : field
+ ****************************************************************************/
+void preset_field_type_size(LttTracefile *tf, LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    enum field_status *fixed_root, enum field_status *fixed_parent,
+    LttField *field)
+{
+  guint i;
+  LttType *type;
+  
+  g_assert(field->fixed_root == FIELD_UNKNOWN);
+  g_assert(field->fixed_parent == FIELD_UNKNOWN);
+  g_assert(field->fixed_size == FIELD_UNKNOWN);
+
+  type = field->field_type;
+
+  field->fixed_root = *fixed_root;
+  if(field->fixed_root == FIELD_FIXED)
+    field->offset_root = offset_root;
+  else
+    field->offset_root = 0;
+
+  field->fixed_parent = *fixed_parent;
+  if(field->fixed_parent == FIELD_FIXED)
+    field->offset_parent = offset_parent;
+  else
+    field->offset_parent = 0;
+
+  switch(type->type_class) {
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_FLOAT:
+    case LTT_ENUM:
+      field->field_size = (off_t) ltt_type_size(LTT_GET_BO(tf),
+                                            event_type->facility, type);
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_POINTER:
+      field->field_size = (off_t)event_type->facility->pointer_size; 
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_LONG:
+    case LTT_ULONG:
+      field->field_size = (off_t)event_type->facility->pointer_size; 
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+      field->field_size = (off_t)event_type->facility->size_t_size; 
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_SEQUENCE:
+      preset_field_type_size(tf, event_type->facility, event_type,
+        0, 0, 
+        FIELD_VARIABLE, FIELD_VARIABLE,
+        field->child[0]);
+      field->fixed_size = FIELD_VARIABLE;
+      field->field_size = 0;
+      break;
+    case LTT_STRING:
+      field->fixed_size = FIELD_VARIABLE;
+      field->field_size = 0;
+      break;
+    case LTT_ARRAY:
+      preset_field_type_size(tf, event_type->facility, event_type,
+        0, 0, 
+        FIELD_VARIABLE, FIELD_VARIABLE,
+        field->child[0]);
+      field->fixed_size = field->child[0]->fixed_size;
+      if(field->fixed_size == FIELD_FIXED)
+        field->field_size = type->element_number * field->child[0]->field_size;
+      else
+        field->field_size = 0;
+      break;
+    case LTT_STRUCT:
+      size_t current_root_offset = field->offset_root;
+      size_t current_offset = 0;
+      enum field_status current_child_status = FIELD_FIXED;
+      for(i=0;i<type->element_number;i++) {
+        preset_field_type_size(tf, event_type->facility, event_type,
+          current_root_offset, current_offset, 
+          fixed_root, &current_child_status,
+          field->child[i]);
+        if(current_child_status == FIELD_FIXED) {
+          current_root_offset += field->child[i]->field_size;
+          current_offset += field->child[i]->field_size;
+        } else {
+          current_root_offset = 0;
+          current_offset = 0;
+        }
+      }
+      if(current_child_status != FIELD_FIXED) {
+        *fixed_parent = current_child_status;
+        field->field_size = 0;
+        field->fixed_size = current_child_status;
+      } else {
+        field->field_size = current_offset;
+        field->fixed_size = FIELD_FIXED;
+      }
+      break;
+    case LTT_UNION:
+      size_t current_root_offset = field->offset_root;
+      size_t current_offset = 0;
+      size_t max_size = 0;
+      enum field_status final_child_status = FIELD_FIXED;
+      for(i=0;i<type->element_number;i++) {
+        enum field_status current_root_child_status = FIELD_FIXED;
+        enum field_status current_child_status = FIELD_FIXED;
+        preset_field_type_size(tf, event_type->facility, event_type,
+          current_root_offset, current_offset, 
+          &current_root_child_status, &current_child_status,
+          field->child[i]);
+        if(current_child_status != FIELD_FIXED)
+          final_child_status = current_child_status;
+        else
+          max_size = max(max_size, field->child[i]->field_size);
+      }
+      if(final_child_status != FIELD_FIXED) {
+        *fixed_root = final_child_status;
+        *fixed_parent = final_child_status;
+        field->field_size = 0;
+        field->fixed_size = current_child_status;
+      } else {
+        field->field_size = max_size;
+        field->fixed_size = FIELD_FIXED;
+      }
+      break;
+  }
+
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    get_field_type_size : set the fixed and dynamic sizes of the field type
+ *    from the data read.
+ *Input params 
+ *    tf              : tracefile
+ *    event_type      : event type
+ *    offset_root     : offset from the root
+ *    offset_parent   : offset from the parent
+ *    field           : field
+ *    data            : a pointer to the event data.
+ *Returns the field type size.
+ ****************************************************************************/
+size_t get_field_type_size(LttTracefile *tf, LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    LttField *field, void *data)
+{
+  size_t size = 0;
+  guint i;
+  LttType *type;
+  
+  g_assert(field->fixed_root != FIELD_UNKNOWN);
+  g_assert(field->fixed_parent != FIELD_UNKNOWN);
+  g_assert(field->fixed_size != FIELD_UNKNOWN);
+
+  field->offset_root = offset_root;
+  field->offset_parent = offset_parent;
+  
+  type = field->field_type;
+
+  switch(type->type_class) {
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_FLOAT:
+    case LTT_ENUM:
+    case LTT_POINTER:
+    case LTT_LONG:
+    case LTT_ULONG:
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+      g_assert(field->fixed_size == FIELD_FIXED);
+      size = field->field_size;
+      break;
+    case LTT_SEQUENCE:
+      gint seqnum = ltt_get_uint(LTT_GET_BO(tf),
+                      field->sequ_number_size,
+                      data + offset_root);
+
+      if(field->child[0]->fixed_size == FIELD_FIXED) {
+        size = field->sequ_number_size + 
+          (seqnum * get_field_type_size(tf, event_type->facility, event_type,
+                                        offset_root, offset_parent,
+                                        field->child[0], data));
+      } else {
+        size += field->sequ_number_size;
+        for(i=0;i<seqnum;i++) {
+          size_t child_size;
+          child_size = get_field_type_size(tf, event_type->facility,
+                                  event_type,
+                                  offset_root, offset_parent,
+                                  field->child[0], data);
+          offset_root += child_size;
+          offset_parent += child_size;
+          size += child_size;
+        }
+      }
+      field->field_size = size;
+      break;
+    case LTT_STRING:
+      size = strlen((char*)(data+offset_root)) + 1;// length + \0
+      field->field_size = size;
+      break;
+    case LTT_ARRAY:
+      if(field->fixed_size == FIELD_FIXED)
+        size = field->field_size;
+      else {
+        for(i=0;i<seqnum;i++) {
+          size_t child_size;
+          child_size = get_field_type_size(tf, event_type->facility,
+                                  event_type,
+                                  offset_root, offset_parent,
+                                  field->child[0], data);
+          offset_root += child_size;
+          offset_parent += child_size;
+          size += child_size;
+        }
+        field->field_size = size;
+      }
+      break;
+    case LTT_STRUCT:
+      if(field->fixed_size == FIELD_FIXED)
+        size = field->field_size;
+      else {
+        size_t current_root_offset = offset_root;
+        size_t current_offset = 0;
+        size_t child_size = 0;
+        for(i=0;i<type->element_number;i++) {
+          child_size = get_field_type_size(tf, event_type->facility,
+                     event_type, current_root_offset, current_offset, 
+                     field->child[i], data);
+          current_offset += child_size;
+          current_root_offset += child_size;
+          
+        }
+        size = current_offset;
+        field->field_size = size;
+      }
+      break;
+    case LTT_UNION:
+      if(field->fixed_size == FIELD_FIXED)
+        size = field->field_size;
+      else {
+        size_t current_root_offset = field->offset_root;
+        size_t current_offset = 0;
+        for(i=0;i<type->element_number;i++) {
+          size = get_field_type_size(tf, event_type->facility, event_type,
+                 current_root_offset, current_offset, 
+                 field->child[i], data);
+          size = max(size, field->child[i]->field_size);
+        }
+        field->field_size = size;
+      }
+      break;
+  }
+
+  return size;
 }
 
+
+
+#if 0
 /*****************************************************************************
  *Function name
  *    getFieldtypeSize: get the size of the field type (primitive type)
  *Input params 
- *    tracefile       : opened trace file 
  *    evT             : event type
  *    offsetRoot      : offset from the root
  *    offsetParent    : offset from the parrent
@@ -1636,151 +1959,146 @@ void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace* t)
  *    int             : size of the field
  ****************************************************************************/
 
-static inline gint getFieldtypeSize(LttTracefile * t,
+static inline gint getFieldtypeSize(LttTracefile *tf,
        LttEventType * evT, gint offsetRoot,
-            gint offsetParent, LttField * fld, void *evD, LttTrace *trace)
+            gint offsetParent, LttField * fld, void *evD)
 {
   gint size, size1, element_number, i, offset1, offset2;
   LttType * type = fld->field_type;
 
-  if(unlikely(t && evT->latest_block==t->which_block &&
-                   evT->latest_event==t->which_event)){
-    size = fld->field_size;
-    goto end_getFieldtypeSize;
-  } else {
-    /* This likely has been tested with gcov : half of them.. */
-    if(unlikely(fld->field_fixed == 1)){
-      /* tested : none */
-      if(unlikely(fld == evT->root_field)) {
-        size = fld->field_size;
-        goto end_getFieldtypeSize;
-      }
+  /* This likely has been tested with gcov : half of them.. */
+  if(unlikely(fld->field_fixed == 1)){
+    /* tested : none */
+    if(unlikely(fld == evT->root_field)) {
+      size = fld->field_size;
+      goto end_getFieldtypeSize;
     }
+  }
 
-    /* From gcov profiling : half string, half struct, can we gain something
-     * from that ? (Mathieu) */
-    switch(type->type_class) {
-      case LTT_ARRAY:
-        element_number = (int) type->element_number;
-        if(fld->field_fixed == -1){
-          size = getFieldtypeSize(t, evT, offsetRoot,
-                                  0,fld->child[0], NULL, trace);
-          if(size == 0){ //has string or sequence
-            fld->field_fixed = 0;
-          }else{
-            fld->field_fixed = 1;
-            size *= element_number; 
-          }
-        }else if(fld->field_fixed == 0){// has string or sequence
-          size = 0;
-          for(i=0;i<element_number;i++){
-            size += getFieldtypeSize(t, evT, offsetRoot+size,size, 
-            fld->child[0], evD+size, trace);
-          }
-        }else size = fld->field_size;
-        if(unlikely(!evD)){
-          fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
-          fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
-        }
-
-        break;
-
-      case LTT_SEQUENCE:
-        size1 = (int) ltt_type_size(trace, type);
-        if(fld->field_fixed == -1){
-          fld->sequ_number_size = size1;
+  /* From gcov profiling : half string, half struct, can we gain something
+   * from that ? (Mathieu) */
+  switch(type->type_class) {
+    case LTT_ARRAY:
+      element_number = (int) type->element_number;
+      if(fld->field_fixed == -1){
+        size = getFieldtypeSize(tf, evT, offsetRoot,
+                                0,fld->child[0], NULL);
+        if(size == 0){ //has string or sequence
           fld->field_fixed = 0;
-          size = getFieldtypeSize(t, evT, offsetRoot,
-                                  0,fld->child[0], NULL, trace);      
-          fld->element_size = size;
-        }else{//0: sequence
-          element_number = getIntNumber(t->trace->reverse_byte_order,size1,evD);
-          type->element_number = element_number;
-          if(fld->element_size > 0){
-            size = element_number * fld->element_size;
-          }else{//sequence has string or sequence
-            size = 0;
-            for(i=0;i<element_number;i++){
-              size += getFieldtypeSize(t, evT, offsetRoot+size+size1,size+size1, 
-                                       fld->child[0], evD+size+size1, trace);
-            }
-          }
-          size += size1;
-        }
-        if(unlikely(!evD)){
-          fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
-          fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+        }else{
+          fld->field_fixed = 1;
+          size *= element_number; 
         }
-
-        break;
-        
-      case LTT_STRING:
+      }else if(fld->field_fixed == 0){// has string or sequence
         size = 0;
-        if(fld->field_fixed == -1){
-          fld->field_fixed = 0;
-        }else{//0: string
-          /* Hope my implementation is faster than strlen (Mathieu) */
-          char *ptr=(char*)evD;
-          size = 1;
-          /* from gcov : many many strings are empty, make it the common case.*/
-          while(unlikely(*ptr != '\0')) { size++; ptr++; }
-          //size = ptr - (char*)evD + 1; //include end : '\0'
+        for(i=0;i<element_number;i++){
+          size += getFieldtypeSize(tf, evT, offsetRoot+size,size, 
+          fld->child[0], evD+size);
         }
+      }else size = fld->field_size;
+      if(unlikely(!evD)){
         fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
         fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      }
 
-        break;
-        
-      case LTT_STRUCT:
-        element_number = (int) type->element_number;
-        size = 0;
-        /* tested with gcov */
-        if(unlikely(fld->field_fixed == -1)){
-          offset1 = offsetRoot;
-          offset2 = 0;
+      break;
+
+    case LTT_SEQUENCE:
+      size1 = (int) ltt_type_size(fac, type);
+      if(fld->field_fixed == -1){
+        fld->sequ_number_size = size1;
+        fld->field_fixed = 0;
+        size = getFieldtypeSize(evT, offsetRoot,
+                                0,fld->child[0], NULL);      
+        fld->element_size = size;
+      }else{//0: sequence
+        element_number = getIntNumber(tf,size1,evD);
+        type->element_number = element_number;
+        if(fld->element_size > 0){
+          size = element_number * fld->element_size;
+        }else{//sequence has string or sequence
+          size = 0;
           for(i=0;i<element_number;i++){
-            size1=getFieldtypeSize(t, evT,offset1,offset2,
-                                   fld->child[i], NULL, trace);
-            if(likely(size1 > 0 && size >= 0)){
-              size += size1;
-              if(likely(offset1 >= 0)) offset1 += size1;
-                offset2 += size1;
-            }else{
-              size = -1;
-              offset1 = -1;
-              offset2 = -1;
-            }
+            size += getFieldtypeSize(tf, evT,
+                                     offsetRoot+size+size1,size+size1, 
+                                     fld->child[0], evD+size+size1);
           }
-          if(unlikely(size == -1)){
-             fld->field_fixed = 0;
-             size = 0;
-          }else fld->field_fixed = 1;
-        }else if(likely(fld->field_fixed == 0)){
-          offset1 = offsetRoot;
-          offset2 = 0;
-          for(i=0;unlikely(i<element_number);i++){
-            size=getFieldtypeSize(t,evT,offset1,offset2,
-                                  fld->child[i],evD+offset2, trace);
-            offset1 += size;
-            offset2 += size;
-          }      
-          size = offset2;
-        }else size = fld->field_size;
+        }
+        size += size1;
+      }
+      if(unlikely(!evD)){
         fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
         fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
-        break;
+      }
 
-      default:
-        if(unlikely(fld->field_fixed == -1)){
-          size = (int) ltt_type_size(trace, type);
-          fld->field_fixed = 1;
-        }else size = fld->field_size;
-        if(unlikely(!evD)){
-          fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
-          fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      break;
+      
+    case LTT_STRING:
+      size = 0;
+      if(fld->field_fixed == -1){
+        fld->field_fixed = 0;
+      }else{//0: string
+        /* Hope my implementation is faster than strlen (Mathieu) */
+        char *ptr=(char*)evD;
+        size = 1;
+        /* from gcov : many many strings are empty, make it the common case.*/
+        while(unlikely(*ptr != '\0')) { size++; ptr++; }
+        //size = ptr - (char*)evD + 1; //include end : '\0'
+      }
+      fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+      fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+
+      break;
+      
+    case LTT_STRUCT:
+      element_number = (int) type->element_number;
+      size = 0;
+      /* tested with gcov */
+      if(unlikely(fld->field_fixed == -1)){
+        offset1 = offsetRoot;
+        offset2 = 0;
+        for(i=0;i<element_number;i++){
+          size1=getFieldtypeSize(tf, evT,offset1,offset2,
+                                 fld->child[i], NULL);
+          if(likely(size1 > 0 && size >= 0)){
+            size += size1;
+            if(likely(offset1 >= 0)) offset1 += size1;
+              offset2 += size1;
+          }else{
+            size = -1;
+            offset1 = -1;
+            offset2 = -1;
+          }
         }
-        break;
-    }
+        if(unlikely(size == -1)){
+           fld->field_fixed = 0;
+           size = 0;
+        }else fld->field_fixed = 1;
+      }else if(likely(fld->field_fixed == 0)){
+        offset1 = offsetRoot;
+        offset2 = 0;
+        for(i=0;unlikely(i<element_number);i++){
+          size=getFieldtypeSize(tf, evT, offset1, offset2,
+                                fld->child[i], evD+offset2);
+          offset1 += size;
+          offset2 += size;
+        }      
+        size = offset2;
+      }else size = fld->field_size;
+      fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+      fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      break;
+
+    default:
+      if(unlikely(fld->field_fixed == -1)){
+        size = (int) ltt_type_size(LTT_GET_BO(tf), type);
+        fld->field_fixed = 1;
+      }else size = fld->field_size;
+      if(unlikely(!evD)){
+        fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+        fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      }
+      break;
   }
 
   fld->offset_root     = offsetRoot;
@@ -1791,35 +2109,66 @@ end_getFieldtypeSize:
 
   return size;
 }
-
+#endif //0
 
 /*****************************************************************************
  *Function name
- *    getIntNumber    : get an integer number
+ *    get_int    : get an integer number
  *Input params 
+ *    reverse_byte_order: must we reverse the byte order ?
  *    size            : the size of the integer
- *    evD             : the event data
+ *    ptr             : the data pointer
  *Return value
  *    gint64          : a 64 bits integer
  ****************************************************************************/
 
-gint64 getIntNumber(gboolean reverse_byte_order, int size, void *evD)
+gint64 get_int(gboolean reverse_byte_order, gint size, void *data)
 {
-  gint64 i;
+  gint64 val;
 
   switch(size) {
-    case 1: i = *((gint8*)evD); break;
-    case 2: i = ltt_get_int16(reverse_byte_order, evD); break;
-    case 4: i = ltt_get_int32(reverse_byte_order, evD); break;
-    case 8: i = ltt_get_int64(reverse_byte_order, evD); break;
-    default: i = ltt_get_int64(reverse_byte_order, evD);
-             g_critical("getIntNumber : integer size %d unknown", size);
+    case 1: val = *((gint8*)data); break;
+    case 2: val = ltt_get_int16(reverse_byte_order, data); break;
+    case 4: val = ltt_get_int32(reverse_byte_order, data); break;
+    case 8: val = ltt_get_int64(reverse_byte_order, data); break;
+    default: val = ltt_get_int64(reverse_byte_order, data);
+             g_critical("get_int : integer size %d unknown", size);
              break;
   }
 
-  return i;
+  return val;
 }
 
+/*****************************************************************************
+ *Function name
+ *    get_uint    : get an unsigned integer number
+ *Input params 
+ *    reverse_byte_order: must we reverse the byte order ?
+ *    size            : the size of the integer
+ *    ptr             : the data pointer
+ *Return value
+ *    guint64         : a 64 bits unsigned integer
+ ****************************************************************************/
+
+guint64 get_uint(gboolean reverse_byte_order, gint size, void *data)
+{
+  guint64 val;
+
+  switch(size) {
+    case 1: val = *((gint8*)data); break;
+    case 2: val = ltt_get_uint16(reverse_byte_order, data); break;
+    case 4: val = ltt_get_uint32(reverse_byte_order, data); break;
+    case 8: val = ltt_get_uint64(reverse_byte_order, data); break;
+    default: val = ltt_get_uint64(reverse_byte_order, data);
+             g_critical("get_uint : unsigned integer size %d unknown",
+                 size);
+             break;
+  }
+
+  return val;
+}
+
+
 /* get the node name of the system */
 
 char * ltt_trace_system_description_node_name (LttSystemDescription * s)
index 7f134eda1908101cfdb15a3f3049481a0783fa7d..44f218f1a3db579e97904c42e6c67adbd7e955af 100644 (file)
@@ -49,10 +49,10 @@ static unsigned floatSizes[] = {
  *Input params
  *    et                 : an  event type   
  *Return value
- *    char *             : the name of the event type
+ *    GQuark             : the name of the event type
  ****************************************************************************/
 
-gchar *ltt_eventtype_name(LttEventType *et)
+GQuark ltt_eventtype_name(LttEventType *et)
 {
   return et->name;
 }
@@ -85,20 +85,6 @@ LttFacility *ltt_eventtype_facility(LttEventType *et)
   return et->facility;
 }
 
-/*****************************************************************************
- *Function name
- *    ltt_eventtype_relative_id : get the relative id of the event type
- *Input params
- *    et                        : an  event type   
- *Return value
- *    unsigned                  : the relative id
- ****************************************************************************/
-
-unsigned ltt_eventtype_relative_id(LttEventType *et)
-{
-  return et->index;
-}
-
 /*****************************************************************************
  *Function name
  *    ltt_eventtype_id : get the id of the event type
@@ -108,9 +94,9 @@ unsigned ltt_eventtype_relative_id(LttEventType *et)
  *    unsigned         : the id
  ****************************************************************************/
 
-unsigned ltt_eventtype_id(LttEventType *et)
+guint8 ltt_eventtype_id(LttEventType *et)
 {
-  return et->facility->base_id + et->index;
+  return et->index;
 }
 
 /*****************************************************************************
@@ -151,7 +137,7 @@ LttField *ltt_eventtype_field(LttEventType *et)
  *    char *         : the name of the type
  ****************************************************************************/
 
-gchar *ltt_type_name(LttType *t)
+GQuark ltt_type_name(LttType *t)
 {
   return t->element_name;
 }
@@ -173,47 +159,58 @@ LttTypeEnum ltt_type_class(LttType *t)
 /*****************************************************************************
  *Function name
  *    ltt_type_size : obtain the type size. The size is the number of bytes 
- *                    for primitive types (INT, UINT, FLOAT, ENUM), or the 
- *                    size for the unsigned integer length count for sequences
+ *                    for primitive types (INT, UINT, FLOAT, ENUM)
+ *                    or the size for the unsigned integer length count for
+ *                    sequences
  *Input params
  *    tf            : trace file
  *    t             : a type   
  *Return value
- *    unsigned      : the type size
+ *                  : the type size
  *    returns 0 if erroneous, and show a critical warning message.
  ****************************************************************************/
 
-unsigned ltt_type_size(LttTrace * trace, LttType *t)
+size_t ltt_type_size(LttTrace * trace, LttType *t)
 {
-  unsigned size;
-  if(unlikely(t->type_class==LTT_STRUCT || t->type_class==LTT_ARRAY || 
-              t->type_class==LTT_STRING || t->type_class==LTT_UNION)) {
-    size = 0;
-  } else {
-    if(t->type_class == LTT_FLOAT){
-      size = floatSizes[t->size];
-    }else{
+  size_t size;
+
+  switch(t->type_class) {
+
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_SEQUENCE:
+    case LTT_ENUM:
       if(likely(t->size < INT_SIZES_NUMBER))
         size = intSizes[t->size];
-      else{
-        LttArchSize archsize = trace->system_description->size;
-        if(archsize == LTT_LP32){
-          if(t->size == 5) size = intSizes[SIZE_INT16];
-          else size = intSizes[SIZE_INT32];
-        }
-        else if(archsize == LTT_ILP32 || archsize == LTT_LP64){
-          if(t->size == 5) size = intSizes[SIZE_INT32];
-          else{
-            if(archsize == LTT_ILP32) size = intSizes[SIZE_INT32];
-            else size = intSizes[SIZE_INT64];
-          }
-        }
-        else if(archsize == LTT_ILP64) size = intSizes[SIZE_INT64];
-      }
-    }
+      else
+        goto error;
+      break;
+    case LTT_FLOAT:
+      if(likely(t->size < FLOAT_SIZES_NUMBER))
+        size = floatSizes[t->size];
+      else
+        goto error;
+      break;
+    case LTT_POINTER:
+    case LTT_LONG:
+    case LTT_ULONG:
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+    case LTT_STRING:
+    case LTT_ARRAY:
+    case LTT_STRUCT:
+    case LTT_UNION:
+      goto error;
+      break;
   }
 
   return size;
+
+
+error:
+  g_warning("no size known for the type");
+  return 0;
 }
 
 /*****************************************************************************
index 01cbbb38ac5d003c563c0fdb7735d847f63c7d09..fca7e42d424754177339422da1080e6c2facff16 100644 (file)
@@ -31,7 +31,7 @@
 /* Obtain the name, description, facility, facility relative id, global id, 
    type and root field for an eventtype */
 
-gchar *ltt_eventtype_name(LttEventType *et);
+GQuark ltt_eventtype_name(LttEventType *et);
 
 gchar *ltt_eventtype_description(LttEventType *et);
 
@@ -50,7 +50,7 @@ LttField *ltt_eventtype_field(LttEventType *et);
    primitive types (INT, UINT, FLOAT, ENUM), or the size for the unsigned
    integer length count for sequences. */
  
-gchar *ltt_type_name(LttType *t);
+GQuark ltt_type_name(LttType *t);
 
 LttTypeEnum ltt_type_class(LttType *t);
 
@@ -74,13 +74,13 @@ unsigned ltt_type_member_number(LttType *t);
 
 /* The type of a data member in a structure. */
 
-LttType *ltt_type_member_type(LttType *t, unsigned i, char ** name);
+LttType *ltt_type_member_type(LttType *t, unsigned i, GQuark *name);
 
 
 /* For enumerations, obtain the symbolic string associated with a value
    (0 to n - 1 for an enumeration of n elements). */
 
-gchar *ltt_enum_string_get(LttType *t, unsigned i);
+GQuark ltt_enum_string_get(LttType *t, unsigned i);
 
 
 /* The fields form a tree representing a depth first search of the 
This page took 0.045252 seconds and 4 git commands to generate.