From dd3a6d3981f13150b4262a418f5ee00c715eda71 Mon Sep 17 00:00:00 2001 From: compudj Date: Thu, 15 Mar 2007 04:08:42 +0000 Subject: [PATCH] Add custom event data support git-svn-id: http://ltt.polymtl.ca/svn@2424 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/ltt/event.c | 35 ++++++++--- ltt/branches/poly/ltt/facility.c | 2 + ltt/branches/poly/ltt/ltt-private.h | 3 + ltt/branches/poly/ltt/parser.c | 98 +++++++++++++++++------------ ltt/branches/poly/ltt/parser.h | 42 ++++++++----- ltt/branches/poly/ltt/trace.h | 2 - ltt/branches/poly/ltt/tracefile.c | 89 +++++++++++++++++++------- 7 files changed, 179 insertions(+), 92 deletions(-) diff --git a/ltt/branches/poly/ltt/event.c b/ltt/branches/poly/ltt/event.c index f3645887..0c208c48 100644 --- a/ltt/branches/poly/ltt/event.c +++ b/ltt/branches/poly/ltt/event.c @@ -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; isize; 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; idynamic_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; ifields->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; ifields->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; ifields->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); } } diff --git a/ltt/branches/poly/ltt/facility.c b/ltt/branches/poly/ltt/facility.c index c313eef1..8cb8cff4 100644 --- a/ltt/branches/poly/ltt/facility.c +++ b/ltt/branches/poly/ltt/facility.c @@ -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 = diff --git a/ltt/branches/poly/ltt/ltt-private.h b/ltt/branches/poly/ltt/ltt-private.h index d2bacd6f..a4801c1c 100644 --- a/ltt/branches/poly/ltt/ltt-private.h +++ b/ltt/branches/poly/ltt/ltt-private.h @@ -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 }; diff --git a/ltt/branches/poly/ltt/parser.c b/ltt/branches/poly/ltt/parser.c index 0ac6f545..2a7dd1e5 100644 --- a/ltt/branches/poly/ltt/parser.c +++ b/ltt/branches/poly/ltt/parser.c @@ -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)); // 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 or "); @@ -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 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) { // getFieldAttributes(in, f); @@ -647,7 +662,7 @@ void parseFields(parse_file_t *in, field_t *f, // 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); // //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); // /* 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); // //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); // getLAnglebracket(in); diff --git a/ltt/branches/poly/ltt/parser.h b/ltt/branches/poly/ltt/parser.h index 8fd75743..a4b3723b 100644 --- a/ltt/branches/poly/ltt/parser.h +++ b/ltt/branches/poly/ltt/parser.h @@ -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); diff --git a/ltt/branches/poly/ltt/trace.h b/ltt/branches/poly/ltt/trace.h index ce1c083a..85dfe866 100644 --- a/ltt/branches/poly/ltt/trace.h +++ b/ltt/branches/poly/ltt/trace.h @@ -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 */ diff --git a/ltt/branches/poly/ltt/tracefile.c b/ltt/branches/poly/ltt/tracefile.c index 7014869a..e4325b1d 100644 --- a/ltt/branches/poly/ltt/tracefile.c +++ b/ltt/branches/poly/ltt/tracefile.c @@ -34,6 +34,7 @@ #include #include #include +#include // For realpath #include @@ -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; ifields->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: -- 2.34.1