Add custom event data support
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 15 Mar 2007 04:08:42 +0000 (04:08 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 15 Mar 2007 04:08:42 +0000 (04:08 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@2424 04897980-b3bd-0310-b5e0-8ef037075253

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

index f3645887fe7245a13cc975b4d5825209a5432813..0c208c48dd8f4ce2a7728b90e5b2326f4fedd65d 100644 (file)
@@ -39,7 +39,7 @@
 
 
 void compute_fields_offsets(LttTracefile *tf,
-    LttFacility *fac, LttField *field, off_t *offset, void *root);
+    LttFacility *fac, LttField *field, off_t *offset, void *root, guint is_compact);
 
 
 LttEvent *ltt_event_new()
@@ -364,7 +364,7 @@ LttField *ltt_event_field_element_select(LttEvent *e, LttField *f, gulong i)
     new_offset = g_array_index(f->dynamic_offsets, off_t, i);
   }
   compute_fields_offsets(e->tracefile, 
-      ltt_event_facility(e), field, &new_offset, e->data);
+      ltt_event_facility(e), field, &new_offset, e->data, 0);
 
   return field;
 }
@@ -570,10 +570,24 @@ char *ltt_event_get_string(LttEvent *e, LttField *f)
 
 
 void compute_fields_offsets(LttTracefile *tf, 
-    LttFacility *fac, LttField *field, off_t *offset, void *root)
+    LttFacility *fac, LttField *field, off_t *offset, void *root, guint is_compact)
 {
   LttType *type = &field->field_type;
 
+  if(unlikely(is_compact)) {
+    g_assert(field->field_size != 0);
+    /* FIXME THIS IS A HUUUUUGE hack :
+     * offset is between the compact_data field in struct LttEvent
+     * and the address of the field root in the memory map.
+     * ark. Both will stay at the same addresses while the event
+     * is readable, so it's ok.
+     */
+    field->offset_root = (unsigned long)(&tf->event.compact_data)
+                               - (unsigned long)root;
+    field->fixed_root = FIELD_FIXED;
+    return;
+  }
+
   switch(type->type_class) {
     case LTT_INT_FIXED:
     case LTT_UINT_FIXED:
@@ -641,7 +655,7 @@ void compute_fields_offsets(LttTracefile *tf,
                                                     0);
           for(i=0; i<type->size; i++) {
             g_array_append_val(field->dynamic_offsets, *offset);
-            compute_fields_offsets(tf, fac, child, offset, root);
+            compute_fields_offsets(tf, fac, child, offset, root, is_compact);
           }
         }
   //      local_offset = field->array_offset;
@@ -663,7 +677,7 @@ void compute_fields_offsets(LttTracefile *tf,
           field->offset_root = *offset;
 
           child = &g_array_index(type->fields, LttField, 0);
-          compute_fields_offsets(tf, fac, child, offset, root);
+          compute_fields_offsets(tf, fac, child, offset, root, is_compact);
           child = &g_array_index(type->fields, LttField, 1);
           *offset += ltt_align(*offset, get_alignment(child),
                                fac->alignment);
@@ -678,7 +692,7 @@ void compute_fields_offsets(LttTracefile *tf,
         num_elem = ltt_event_field_element_number(&tf->event, field);
         for(i=0; i<num_elem; i++) {
           g_array_append_val(field->dynamic_offsets, *offset);
-          compute_fields_offsets(tf, fac, child, offset, root);
+          compute_fields_offsets(tf, fac, child, offset, root, is_compact);
         }
         g_assert(num_elem == field->dynamic_offsets->len);
 
@@ -706,7 +720,7 @@ void compute_fields_offsets(LttTracefile *tf,
         }
         for(i=0; i<type->fields->len; i++) {
           child = &g_array_index(type->fields, LttField, i);
-          compute_fields_offsets(tf, fac, child, offset, root);
+          compute_fields_offsets(tf, fac, child, offset, root, is_compact);
         }
       }
       break;
@@ -724,7 +738,7 @@ void compute_fields_offsets(LttTracefile *tf,
         for(i=0; i<type->fields->len; i++) {
           *offset = field->offset_root;
           child = &g_array_index(type->fields, LttField, i);
-          compute_fields_offsets(tf, fac, child, offset, root);
+          compute_fields_offsets(tf, fac, child, offset, root, is_compact);
         }
         *offset = field->offset_root + field->field_size;
       }
@@ -754,7 +768,10 @@ void compute_offsets(LttTracefile *tf, LttFacility *fac,
   for(i=0; i<event->fields->len; i++) {
     //g_debug("computing offset %u of %u\n", i, event->fields->len-1);
     LttField *field = &g_array_index(event->fields, LttField, i);
-    compute_fields_offsets(tf, fac, field, offset, root);
+    if(event->has_compact_data && i == 0)
+           compute_fields_offsets(tf, fac, field, offset, root, 1);
+    else
+           compute_fields_offsets(tf, fac, field, offset, root, 0);
   }
 
 }
index c313eef1d2b061bfdba091adb816db2f555483f0..8cb8cff44e3c7f1f4b061a4eb5bd17640a4d5b7e 100644 (file)
@@ -249,6 +249,8 @@ void generateFacility(LttFacility *f, facility_t *fac, guint32 checksum)
     event_type->index = i;
     event_type->facility = f;
 
+    event_type->has_compact_data = parser_event->compact_data;
+
     event_type->fields = g_array_sized_new(FALSE, TRUE,
         sizeof(LttField), parser_event->fields.position);
     event_type->fields = 
index d2bacd6f1742b501263484e0994f3af22f036615..a4801c1ca18d61dc090e2357da9af8d071ba8612 100644 (file)
@@ -263,6 +263,7 @@ struct _LttEventType{
   LttFacility * facility; //the facility that contains the event type
   GArray * fields;        //event's fields (LttField)
   GData *fields_by_name;
+  int has_compact_data;       //event header contains compact data (first field)
 };
 
 /* Structure LttEvent and LttEventPosition must begin with the _exact_ same
@@ -290,6 +291,7 @@ struct _LttEvent{
   guint  data_size;
   guint  event_size;         //event_size field of the header : 
                              //used to verify data_size from facility.
+  uint32_t compact_data;
 
   int      count;                    //the number of overflow of cycle count
   gint64 overflow_nsec;              //precalculated nsec for overflows
@@ -440,6 +442,7 @@ struct _LttTrace{
   LttTime   start_time;
   LttTime   start_time_from_tsc;
   GArray    *compact_facilities;
+  uint8_t   compact_event_bits;
 
   GData     *tracefiles;                    //tracefiles groups
 };
index 0ac6f5454da87294dc2f28f3714bb44bd35d5ac0..2a7dd1e532311351baee1c0ed8577c61444283d2 100644 (file)
@@ -195,7 +195,7 @@ char *allocAndCopy(char *str)
  **************************************************************************/
 
 void getTypeAttributes(parse_file_t *in, type_descriptor_t *t,
-                          sequence_t * unnamed_types, table_t * named_types) 
+         sequence_t * unnamed_types, table_t * named_types) 
 {
   char * token;
   int car;
@@ -203,7 +203,7 @@ void getTypeAttributes(parse_file_t *in, type_descriptor_t *t,
   t->fmt = NULL;
   t->size = 0;
   t->custom_write = 0;
-       t->network = 0;
+  t->network = 0;
   
   while(1) {
     token = getToken(in); 
@@ -226,26 +226,26 @@ void getTypeAttributes(parse_file_t *in, type_descriptor_t *t,
       t->size = getSize(in);
     } else if(!strcmp("custom_write", token)) {
       t->custom_write = 1;
-               } else if(!strcmp("byte_order",token)) {
-       getEqual(in);
-       car = seekNextChar(in);
-       if(car == EOF) in->error(in,"byte order was expected (network?)");
-       else if(car == '\"') token = getQuotedString(in);
-       else token = getName(in);
-                       if(!strcmp("network", token)) {
-                       t->network = 1;
-                       }
-               } else if(!strcmp("write",token)) {
-       getEqual(in);
-       car = seekNextChar(in);
-       if(car == EOF) in->error(in,"write type was expected (custom?)");
-       else if(car == '\"') token = getQuotedString(in);
-       else token = getName(in);
-                       if(!strcmp("custom", token)) {
-                       t->custom_write = 1;
-                       }
-         }
-       }
+    } else if(!strcmp("byte_order",token)) {
+       getEqual(in);
+       car = seekNextChar(in);
+       if(car == EOF) in->error(in,"byte order was expected (network?)");
+       else if(car == '\"') token = getQuotedString(in);
+       else token = getName(in);
+       if(!strcmp("network", token)) {
+         t->network = 1;
+       }
+    } else if(!strcmp("write",token)) {
+       getEqual(in);
+       car = seekNextChar(in);
+       if(car == EOF) in->error(in,"write type was expected (custom?)");
+       else if(car == '\"') token = getQuotedString(in);
+       else token = getName(in);
+       if(!strcmp("custom", token)) {
+         t->custom_write = 1;
+       }
+    }
+  }
 }
 
 /**************************************************************************
@@ -271,6 +271,8 @@ void getEventAttributes(parse_file_t *in, event_t *ev)
   ev->param_buffer = 0;
   ev->no_instrument_function = 0;
   ev->high_priority = 0;
+  ev->force = 0;
+  ev->compact_data = 0;
 
   while(1) {
     token = getToken(in); 
@@ -310,6 +312,10 @@ void getEventAttributes(parse_file_t *in, event_t *ev)
         ev->no_instrument_function = 1;
       else if(!strcmp(token, "high_priority"))
         ev->high_priority = 1;
+      else if(!strcmp(token, "force"))
+        ev->force = 1;
+      else if(!strcmp(token, "compact_data"))
+        ev->compact_data = 1;
     }
   }
 }
@@ -333,7 +339,8 @@ void getFacilityAttributes(parse_file_t *in, facility_t *fac)
   
   fac->name = NULL;
   fac->arch = NULL;
-       fac->user = 0;
+  fac->align = 1;
+  fac->user = 0;
 
   while(1) {
     token = getToken(in); 
@@ -354,8 +361,12 @@ void getFacilityAttributes(parse_file_t *in, facility_t *fac)
       getEqual(in);
       car = seekNextChar(in);
       if(car == '\"') fac->arch = allocAndCopy(getQuotedString(in));
-                       else fac->arch = allocAndCopy(getName(in));
-               }
+      else fac->arch = allocAndCopy(getName(in));
+    } else if(!strcmp("align", token)) {
+      getEqual(in);
+      fac->align = getSize(in);
+    }
+
   }
 }
 
@@ -530,9 +541,9 @@ void parseFacility(parse_file_t *in, facility_t * fac)
     if(strcmp("event",token) == 0){
       ev = (event_t*) memAlloc(sizeof(event_t));
       sequence_push(&(fac->events),ev);
-      parseEvent(in,ev, &(fac->unnamed_types), &(fac->named_types));    
+      parseEvent(fac, in, ev, &(fac->unnamed_types), &(fac->named_types));    
     }else if(strcmp("type",token) == 0){
-      parseTypeDefinition(in, &(fac->unnamed_types), &(fac->named_types));
+      parseTypeDefinition(fac, in, &(fac->unnamed_types), &(fac->named_types));
     }else if(in->type == FORWARDSLASH){
       break;
     }else in->error(in,"event or type token expected\n");
@@ -546,7 +557,8 @@ void parseFacility(parse_file_t *in, facility_t * fac)
 /*****************************************************************************
  *Function name
  *    parseEvent    : generate event from event definition 
- *Input params 
+ *Input params
+ *    fac           : facility holding the event
  *    in            : input file handle          
  *    ev            : new event                              
  *    unnamed_types : array of unamed types
@@ -555,12 +567,13 @@ void parseFacility(parse_file_t *in, facility_t * fac)
  *    ev            : new event (parameters are passed to it)   
  ****************************************************************************/
 
-void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types, 
+void parseEvent(facility_t *fac, parse_file_t *in, event_t * ev, sequence_t * unnamed_types, 
                table_t * named_types) 
 {
   char *token;
        field_t *f;
 
+  ev->fac = fac;
        sequence_init(&(ev->fields));
   //<event name=eventtype_name>
   getEventAttributes(in, ev);
@@ -588,7 +601,7 @@ void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types,
                        if(strcmp("field",token))in->error(in,"expecting a field");
                        f = (field_t *)memAlloc(sizeof(field_t));
                        sequence_push(&(ev->fields),f);
-                       parseFields(in, f, unnamed_types, named_types, 1);
+                       parseFields(fac, in, f, unnamed_types, named_types, 1);
                        break;
                default:
                        in->error(in, "expecting </event> or <field >");
@@ -621,6 +634,7 @@ void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types,
  *Function name
  *    parseField    : get field infomation from buffer 
  *Input params 
+ *    fac           : facility holding the field
  *    in            : input file handle
  *    f             : field
  *    unnamed_types : array of unamed types
@@ -628,12 +642,13 @@ void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types,
  *    tag                                              : is field surrounded by a <field> </field> tag ?
  ****************************************************************************/
 
-void parseFields(parse_file_t *in, field_t *f,
+void parseFields(facility_t *fac, parse_file_t *in, field_t *f,
     sequence_t * unnamed_types,
                table_t * named_types,
                int tag) 
 {
   char * token;
+  f->fac = fac;
        if(tag) {
                //<field name=field_name> <description> <type> </field>
                getFieldAttributes(in, f);
@@ -647,7 +662,7 @@ void parseFields(parse_file_t *in, field_t *f,
 
   //<int size=...>
   getLAnglebracket(in);
-  f->type = parseType(in,NULL, unnamed_types, named_types);
+  f->type = parseType(fac, in,NULL, unnamed_types, named_types);
 
        if(tag) {
                getLAnglebracket(in);
@@ -671,6 +686,7 @@ void parseFields(parse_file_t *in, field_t *f,
  *                     type name:
  *                        type(name,type)
  *Input params 
+ *    fac              : facility
  *    in               : input file handle
  *    inType           : a type descriptor          
  *    unnamed_types    : array of unamed types
@@ -679,7 +695,7 @@ void parseFields(parse_file_t *in, field_t *f,
  *    type_descriptor* : a type descriptor             
  ****************************************************************************/
 
-type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, 
+type_descriptor_t *parseType(facility_t *fac, parse_file_t *in, type_descriptor_t *inType, 
                           sequence_t * unnamed_types, table_t * named_types) 
 {
   char *token;
@@ -694,6 +710,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType,
     sequence_push(unnamed_types,t);
   }
   else t = inType;
+  t->fac = fac;
 
   token = getName(in);
 
@@ -708,7 +725,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType,
                        f = (field_t *)memAlloc(sizeof(field_t));
                        sequence_push(&(t->fields),f);
 
-      parseFields(in, f, unnamed_types, named_types, 1);
+      parseFields(fac, in, f, unnamed_types, named_types, 1);
       
       //next field
       getLAnglebracket(in);
@@ -731,7 +748,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType,
     while(strcmp("field",token) == 0){
                        f = (field_t *)memAlloc(sizeof(field_t));
                        sequence_push(&(t->fields),f);
-      parseFields(in, f, unnamed_types, named_types, 1);
+      parseFields(fac, in, f, unnamed_types, named_types, 1);
       
       //next field
       getLAnglebracket(in);
@@ -757,7 +774,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType,
     
     f->name = NULL;
     sequence_push(&(t->fields),f);
-    parseFields(in, f, unnamed_types, named_types, 0);
+    parseFields(fac, in, f, unnamed_types, named_types, 0);
 
     //getLAnglebracket(in); //<type struct> 
     //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
@@ -780,14 +797,14 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType,
     f = (field_t *)memAlloc(sizeof(field_t));
     f->name = NULL;
     sequence_push(&(t->fields),f);
-    parseFields(in, f, unnamed_types, named_types, 0);
+    parseFields(fac, in, f, unnamed_types, named_types, 0);
 
     //getLAnglebracket(in); //<subtype> 
                /* subfield */
     f = (field_t *)memAlloc(sizeof(field_t));
     f->name = NULL;
     sequence_push(&(t->fields),f);
-    parseFields(in, f, unnamed_types, named_types, 0);
+    parseFields(fac, in, f, unnamed_types, named_types, 0);
 
     //getLAnglebracket(in); //<type sequence> 
     //t->length_type = parseType(in, NULL, unnamed_types, named_types);
@@ -1023,12 +1040,13 @@ type_descriptor_t * create_named_type(char *name, table_t * named_types)
  *Function name
  *    parseTypeDefinition : get type information from type definition 
  *Input params 
+ *    fac                 : facility
  *    in                  : input file handle          
  *    unnamed_types       : array of unamed types
  *    named_types         : array of named types
  *****************************************************************************/
 
-void parseTypeDefinition(parse_file_t * in, sequence_t * unnamed_types,
+void parseTypeDefinition(facility_t *fac, parse_file_t * in, sequence_t * unnamed_types,
                         table_t * named_types)
 {
   char *token;
@@ -1044,7 +1062,7 @@ void parseTypeDefinition(parse_file_t * in, sequence_t * unnamed_types,
   token = getName(in);
   //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
   ungetToken(in);
-  parseType(in,t, unnamed_types, named_types);
+  parseType(fac, in,t, unnamed_types, named_types);
   
   //</type>
   getLAnglebracket(in);
index 8fd75743c96fe35c0dcb19890a885f2026db996e..a4b3723b094c9c33909afcc9ac700a40137118ae 100644 (file)
@@ -101,7 +101,11 @@ typedef enum _data_type {
   NONE
 } data_type_t;
 
+typedef struct _facility facility_t;
+typedef struct _event event_t;
+
 typedef struct _type_descriptor {
+  facility_t *fac;
   char * type_name; //used for named type
   data_type_t type;
   char *fmt;
@@ -116,9 +120,9 @@ typedef struct _type_descriptor {
 } type_descriptor_t;
 
 
-
 /* Fields within types or events */
 typedef struct _field{
+  facility_t *fac;
   char *name;
   char *description;
   type_descriptor_t *type;
@@ -127,42 +131,46 @@ typedef struct _field{
 
 /* Events definitions */
 
-typedef struct _event {  
+struct _event {  
+  facility_t *fac;
   char *name;
   char *description;
   //type_descriptor_t *type; 
-       sequence_t fields;      /* event fields */
+  sequence_t fields;  /* event fields */
   int  per_trace;   /* Is the event able to be logged to a specific trace ? */
   int  per_tracefile;  /* Must we log this event in a specific tracefile ? */
-       int param_buffer; /* For userspace tracing : takes a buffer as parameter? */
-       int no_instrument_function;
-       int high_priority;
-} event_t;
+  int param_buffer; /* For userspace tracing : takes a buffer as parameter? */
+  int no_instrument_function;
+  int high_priority;
+  int force;
+  int compact_data;
+};
 
-typedef struct _facility {
+struct _facility {
   char * name;
-       char * capname;
-       char * arch;
+  char * capname;
+  char * arch;
+  int align;  /* Alignment : default 1, 0 no alignment. */
   char * description;
   sequence_t events;
   sequence_t unnamed_types; //FIXME : remove
   table_t named_types;
-       unsigned int checksum;
-       int     user;           /* Is this a userspace facility ? */
-} facility_t;
+  unsigned int checksum;
+  int  user;    /* Is this a userspace facility ? */
+};
 
 int getSizeindex(unsigned int value);
 unsigned long long int getSize(parse_file_t *in);
 unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type);
 
 void parseFacility(parse_file_t *in, facility_t * fac);
-void parseEvent(parse_file_t *in, event_t *ev, sequence_t * unnamed_types,
+void parseEvent(facility_t *fac, parse_file_t *in, event_t *ev, sequence_t * unnamed_types,
     table_t * named_types);
-void parseTypeDefinition(parse_file_t *in,
+void parseTypeDefinition(facility_t *fac, parse_file_t *in,
     sequence_t * unnamed_types, table_t * named_types);
-type_descriptor_t *parseType(parse_file_t *in,
+type_descriptor_t *parseType(facility_t *fac, parse_file_t *in,
     type_descriptor_t *t, sequence_t * unnamed_types, table_t * named_types);
-void parseFields(parse_file_t *in, field_t *f,
+void parseFields(facility_t *fac, parse_file_t *in, field_t *f,
     sequence_t * unnamed_types,
                table_t * named_types,
                int tag);
index ce1c083a0b5b71915016f950d20c954c0733e8cd..85dfe866506c4aa00688b4f9dbfbfa948b3fa340 100644 (file)
@@ -61,8 +61,6 @@ LttSystemDescription *ltt_trace_system_description(LttTrace *t);
 
 unsigned ltt_trace_facility_number(LttTrace *t);
 
-LttFacility *ltt_trace_facility_get(LttTrace *t, unsigned i);
-
 LttFacility * ltt_trace_facility_by_id(LttTrace * trace, guint8 id);
 
 /* Returns an array of indexes (guint) that matches the facility name */
index 7014869a96551f42f6b802a6e52c726e181ecf34..e4325b1df0609914d56ff103b93f8ba874abe53f 100644 (file)
@@ -34,6 +34,7 @@
 #include <glib.h>
 #include <malloc.h>
 #include <sys/mman.h>
+#include <string.h>
 
 // For realpath
 #include <limits.h>
@@ -282,6 +283,7 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
               (double)t->start_tsc
               * (1000000000.0 / tf->trace->freq_scale)
              / (double)t->start_freq);
+         t->compact_event_bits = 0;
         }
       }
       break;
@@ -295,8 +297,8 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
        tf->tsc_lsb_truncate = vheader->tsc_lsb_truncate;
        tf->tscbits = vheader->tscbits;
        tf->tsc_msb_cutoff = 32 - tf->tsc_lsb_truncate - tf->tscbits;
-  tf->tsc_mask = ((1ULL << (tf->tscbits))-1);
-  tf->tsc_mask = tf->tsc_mask << tf->tsc_lsb_truncate;
+        tf->tsc_mask = ((1ULL << (tf->tscbits))-1);
+        tf->tsc_mask = tf->tsc_mask << tf->tsc_lsb_truncate;
        tf->tsc_mask_next_bit = (1ULL<<(tf->tscbits));
        tf->tsc_mask_next_bit = tf->tsc_mask_next_bit << tf->tsc_lsb_truncate;
         if(t) {
@@ -318,6 +320,7 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
               (double)t->start_tsc
               * (1000000000.0 / tf->trace->freq_scale)
              / (double)t->start_freq);
+         t->compact_event_bits = 0;
         }
       }
       break;
@@ -1353,7 +1356,24 @@ LttTrace *ltt_trace_open(const gchar *pathname)
   if(!t->compact_facilities)
     t->compact_facilities = ltt_trace_facility_get_by_name(t,
       g_quark_from_string("flight-compact"));
-  
+  /* FIXME : currently does not support unload/load of compact
+   * facility during tracing. Should check for the currently loaded
+   * version of the facility. */
+  g_assert(t->compact_facilities);
+  g_assert(t->compact_facilities->len == 1);
+  {
+    guint facility_id = g_array_index(t->compact_facilities, guint, 0);
+    LttFacility *fac = ltt_trace_facility_by_id(t, facility_id);
+    unsigned int num = ltt_facility_eventtype_number(fac);
+    /* Could be done much quicker, but not on much used code path */
+    if(num) {
+      t->compact_event_bits = 1;
+      while(num >>= 1)
+        t->compact_event_bits++;
+    } else
+      t->compact_event_bits = 0;
+  }
+
   return t;
 
   /* Error handling */
@@ -1898,47 +1918,52 @@ int ltt_tracefile_read_update_event(LttTracefile *tf)
         tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) 
                                 | (guint64)event->timestamp;
         event->tsc = tf->buffer.tsc;
+       event->compact_data = 0;
       }
     } else {
       /* Compact header */
       /* We keep the LSB of the previous timestamp, to make sure
        * we never go back */
       event->event_id = event->timestamp >> tf->tscbits;
+      event->event_id = event->event_id & ((1 << tf->trace->compact_event_bits) - 1);
+      event->compact_data = event->timestamp >> 
+       (tf->trace->compact_event_bits + tf->tscbits);
+      //printf("tsc bits %u, ev bits %u init data %u\n",
+      //       tf->tscbits, tf->trace->compact_event_bits, event->compact_data);
+      /* Put the compact data back in original endianness */
+      event->compact_data = ltt_get_uint32(LTT_GET_BO(tf), &event->compact_data);
       event->event_size = 0xFFFF;
-      printf("Found compact event %d\n", event->event_id);
+      //printf("Found compact event %d\n", event->event_id);
+      //printf("Compact data %d\n", event->compact_data);
       event->timestamp = event->timestamp << tf->tsc_lsb_truncate;
       event->timestamp = event->timestamp & tf->tsc_mask;
-      printf("timestamp 0x%lX\n", event->timestamp);
-      printf("mask 0x%llX\n", tf->tsc_mask);
-      printf("mask_next 0x%llX\n", tf->tsc_mask_next_bit);
-      printf("previous tsc 0x%llX\n", tf->buffer.tsc);
-      printf("previous tsc&mask 0x%llX\n", tf->tsc_mask&tf->buffer.tsc);
-      printf("previous tsc&(~mask) 0x%llX\n", tf->buffer.tsc&(~tf->tsc_mask));
+      //printf("timestamp 0x%lX\n", event->timestamp);
+      //printf("mask 0x%llX\n", tf->tsc_mask);
+      //printf("mask_next 0x%llX\n", tf->tsc_mask_next_bit);
+      //printf("previous tsc 0x%llX\n", tf->buffer.tsc);
+      //printf("previous tsc&mask 0x%llX\n", tf->tsc_mask&tf->buffer.tsc);
+      //printf("previous tsc&(~mask) 0x%llX\n", tf->buffer.tsc&(~tf->tsc_mask));
       if(event->timestamp < (tf->tsc_mask&tf->buffer.tsc)) {
-        printf("wrap\n");
+        //printf("wrap\n");
         tf->buffer.tsc = ((tf->buffer.tsc&(~tf->tsc_mask))
                             + tf->tsc_mask_next_bit)
                                 | (guint64)event->timestamp;
         event->tsc = tf->buffer.tsc;
       } else {
-        printf("no wrap\n");
+        //printf("no wrap\n");
         /* no overflow */
         tf->buffer.tsc = (tf->buffer.tsc&(~tf->tsc_mask)) 
                                 | (guint64)event->timestamp;
         event->tsc = tf->buffer.tsc;
       }
-      printf("current tsc 0x%llX\n", tf->buffer.tsc);
-      g_assert(tf->trace->compact_facilities);
-      /* FIXME : currently does not support unload/load of compact
-       * facility during tracing. Should check for the currently loaded
-       * version of the facility. */
-      g_assert(tf->trace->compact_facilities->len == 1);
+      //printf("current tsc 0x%llX\n", tf->buffer.tsc);
       event->facility_id = g_array_index(tf->trace->compact_facilities, guint, 0);
     }
                pos += sizeof(guint32);
        } else {
                event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
                tf->buffer.tsc = event->tsc;
+               event->compact_data = 0;
                pos += sizeof(guint64);
        }
        event->event_time = ltt_interpolate_time(tf, event);
@@ -2503,9 +2528,22 @@ void field_compute_static_size(LttFacility *fac, LttField *field)
  ****************************************************************************/
 
 
-gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset)
+gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset, gint is_compact)
 {
   LttType *type = &field->field_type;
+  
+  if(unlikely(is_compact)) {
+    g_assert(field->field_size != 0);
+    /* FIXME THIS IS A HUUUUUGE hack :
+     * offset is between the compact_data field in struct LttEvent
+     * and the address of the field root in the memory map.
+     * ark. Both will stay at the same addresses while the event
+     * is readable, so it's ok.
+     */
+    field->offset_root = 0;
+    field->fixed_root = FIELD_FIXED;
+    return 0;
+  }
 
   switch(type->type_class) {
     case LTT_INT_FIXED:
@@ -2580,7 +2618,7 @@ gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset)
         field->fixed_root = FIELD_FIXED;
  
         child = &g_array_index(type->fields, LttField, 0);
-        ret = precompute_fields_offsets(fac, child, offset);
+        ret = precompute_fields_offsets(fac, child, offset, is_compact);
         g_assert(ret == 0); /* Seq len cannot have variable len */
 
         child = &g_array_index(type->fields, LttField, 1);
@@ -2609,7 +2647,7 @@ gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset)
 
         for(i=0; i< type->fields->len; i++) {
           child = &g_array_index(type->fields, LttField, i);
-          ret = precompute_fields_offsets(fac, child, offset);
+          ret = precompute_fields_offsets(fac, child, offset, is_compact);
 
           if(ret) break;
         }
@@ -2631,7 +2669,7 @@ gint precompute_fields_offsets(LttFacility *fac, 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(fac, child, offset);
+          ret = precompute_fields_offsets(fac, child, offset, is_compact);
 
           if(ret) break;
         }
@@ -2673,7 +2711,10 @@ void precompute_offsets(LttFacility *fac, LttEventType *event)
   /* 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(fac, field, &offset);
+    if(event->has_compact_data && i == 0)
+      ret = precompute_fields_offsets(fac, field, &offset, 1);
+    else
+      ret = precompute_fields_offsets(fac, field, &offset, 0);
     if(ret) break;
   }
 }
@@ -2973,7 +3014,7 @@ gint check_fields_compatibility(LttEventType *event_type1,
       break;
     case LTT_NONE:
     default:
-      g_error("precompute_fields_offsets : unknown type");
+      g_error("check_fields_compatibility : unknown type");
   }
 
 end:
This page took 0.036172 seconds and 4 git commands to generate.