*
* Complete rewrite from the original version made by XangXiu Yang.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation;
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
*
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
void ltt_update_event_size(LttTracefile *tf);
-void precompute_offsets(LttTracefile *tf, LttEventType *event);
+void precompute_offsets(LttFacility *fac, LttEventType *event);
#if 0
/* Functions to parse system.xml file (using glib xml parser) */
t->ltt_minor_version = any->minor_version;
t->flight_recorder = any->flight_recorder;
t->has_heartbeat = any->has_heartbeat;
- t->has_tsc = any->has_tsc;
}
return 1;
}
break;
- case 6:
+ case 7:
{
- struct ltt_trace_header_0_5 *vheader =
- (struct ltt_trace_header_0_5 *)header;
+ struct ltt_trace_header_0_7 *vheader =
+ (struct ltt_trace_header_0_7 *)header;
tf->buffer_header_size =
sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_0_5);
+ + sizeof(struct ltt_trace_header_0_7);
if(t) {
t->start_freq = ltt_get_uint64(LTT_GET_BO(tf),
&vheader->start_freq);
+ t->freq_scale = ltt_get_uint32(LTT_GET_BO(tf),
+ &vheader->freq_scale);
t->start_tsc = ltt_get_uint64(LTT_GET_BO(tf),
&vheader->start_tsc);
t->start_monotonic = ltt_get_uint64(LTT_GET_BO(tf),
t->start_time.tv_nsec *= 1000; /* microsec to nanosec */
t->start_time_from_tsc = ltt_time_from_uint64(
- (double)t->start_tsc * 1000000.0 / (double)t->start_freq);
+ (double)t->start_tsc
+ * (1000000000.0 / tf->trace->freq_scale)
+ / (double)t->start_freq);
}
}
break;
* The left side is the name, the right side is the number.
*/
-int get_tracefile_name_number(const gchar *raw_name,
+int get_tracefile_name_number(gchar *raw_name,
GQuark *name,
- guint *num)
+ guint *num,
+ guint *tid,
+ guint *pgid,
+ guint64 *creation)
{
guint raw_name_len = strlen(raw_name);
gchar char_name[PATH_MAX];
int underscore_pos;
long int cpu_num;
gchar *endptr;
+ gchar *tmpptr;
for(i=raw_name_len-1;i>=0;i--) {
if(raw_name[i] == '_') break;
}
- if(i==0) /* Either not found or name length is 0 */
- return -1;
- underscore_pos = i;
-
- cpu_num = strtol(raw_name+underscore_pos+1, &endptr, 10);
+ if(i==-1) { /* Either not found or name length is 0 */
+ /* This is a userspace tracefile */
+ strncpy(char_name, raw_name, raw_name_len);
+ char_name[raw_name_len] = '\0';
+ *name = g_quark_from_string(char_name);
+ *num = 0; /* unknown cpu */
+ for(i=0;i<raw_name_len;i++) {
+ if(raw_name[i] == '/') {
+ break;
+ }
+ }
+ i++;
+ for(;i<raw_name_len;i++) {
+ if(raw_name[i] == '/') {
+ break;
+ }
+ }
+ i++;
+ for(;i<raw_name_len;i++) {
+ if(raw_name[i] == '-') {
+ break;
+ }
+ }
+ if(i == raw_name_len) return -1;
+ i++;
+ tmpptr = &raw_name[i];
+ for(;i<raw_name_len;i++) {
+ if(raw_name[i] == '.') {
+ raw_name[i] = ' ';
+ break;
+ }
+ }
+ *tid = strtoul(tmpptr, &endptr, 10);
+ if(endptr == tmpptr)
+ return -1; /* No digit */
+ if(*tid == ULONG_MAX)
+ return -1; /* underflow / overflow */
+ i++;
+ tmpptr = &raw_name[i];
+ for(;i<raw_name_len;i++) {
+ if(raw_name[i] == '.') {
+ raw_name[i] = ' ';
+ break;
+ }
+ }
+ *pgid = strtoul(tmpptr, &endptr, 10);
+ if(endptr == tmpptr)
+ return -1; /* No digit */
+ if(*pgid == ULONG_MAX)
+ return -1; /* underflow / overflow */
+ i++;
+ tmpptr = &raw_name[i];
+ *creation = strtoull(tmpptr, &endptr, 10);
+ if(endptr == tmpptr)
+ return -1; /* No digit */
+ if(*creation == G_MAXUINT64)
+ return -1; /* underflow / overflow */
+ } else {
+ underscore_pos = i;
+
+ cpu_num = strtol(raw_name+underscore_pos+1, &endptr, 10);
+
+ if(endptr == raw_name+underscore_pos+1)
+ return -1; /* No digit */
+ if(cpu_num == LONG_MIN || cpu_num == LONG_MAX)
+ return -1; /* underflow / overflow */
+
+ strncpy(char_name, raw_name, underscore_pos);
+ char_name[underscore_pos] = '\0';
- if(endptr == raw_name+underscore_pos+1)
- return -1; /* No digit */
- if(cpu_num == LONG_MIN || cpu_num == LONG_MAX)
- return -1; /* underflow / overflow */
-
- strncpy(char_name, raw_name, underscore_pos);
-
- char_name[underscore_pos] = '\0';
+ *name = g_quark_from_string(char_name);
+ *num = cpu_num;
+ }
- *name = g_quark_from_string(char_name);
- *num = cpu_num;
return 0;
}
if(ret < 0) continue;
} else if(S_ISREG(stat_buf.st_mode)) {
GQuark name;
- guint num;
+ guint num, tid, pgid;
+ guint64 creation;
GArray *group;
-
- if(get_tracefile_name_number(rel_path, &name, &num))
+ num = tid = pgid = 0;
+ creation = 0;
+ if(get_tracefile_name_number(rel_path, &name, &num, &tid, &pgid, &creation))
continue; /* invalid name */
g_debug("Opening file.\n");
tmp_tf.cpu_online = 1;
tmp_tf.cpu_num = num;
tmp_tf.name = name;
+ tmp_tf.tid = tid;
+ tmp_tf.pgid = pgid;
+ tmp_tf.creation = creation;
group = g_datalist_id_get_data(&trace->tracefiles, name);
if(group == NULL) {
const gchar *text;
guint textlen;
gint err;
+ gint arch_spec;
+ gint fac_name_len;
text = g_quark_to_string(t->pathname);
textlen = strlen(text);
strcat(desc_file_name, text);
text = g_quark_to_string(f->name);
- textlen+=strlen(text);
+ fac_name_len = strlen(text);
+ textlen+=fac_name_len;
if(textlen >= PATH_MAX) goto name_error;
strcat(desc_file_name, text);
+
+ /* arch specific facilities are named like this : name_arch */
+ if(fac_name_len+1 < sizeof("_arch"))
+ arch_spec = 0;
+ else {
+ if(!strcmp(&text[fac_name_len+1-sizeof("_arch")], "_arch"))
+ arch_spec = 1;
+ else
+ arch_spec = 0;
+ }
+
#if 0
text = "_";
textlen+=strlen(text);
textlen=strlen(desc_file_name);
#endif //0
+
+ if(arch_spec) {
+ switch(t->arch_type) {
+ case LTT_ARCH_TYPE_I386:
+ text = "_i386";
+ break;
+ case LTT_ARCH_TYPE_PPC:
+ text = "_ppc";
+ break;
+ case LTT_ARCH_TYPE_SH:
+ text = "_sh";
+ break;
+ case LTT_ARCH_TYPE_S390:
+ text = "_s390";
+ break;
+ case LTT_ARCH_TYPE_MIPS:
+ text = "_mips";
+ break;
+ case LTT_ARCH_TYPE_ARM:
+ text = "_arm";
+ break;
+ case LTT_ARCH_TYPE_PPC64:
+ text = "_ppc64";
+ break;
+ case LTT_ARCH_TYPE_X86_64:
+ text = "_x86_64";
+ break;
+ case LTT_ARCH_TYPE_C2:
+ text = "_c2";
+ break;
+ case LTT_ARCH_TYPE_POWERPC:
+ text = "_powerpc";
+ break;
+ default:
+ g_error("Trace from unsupported architecture.");
+ }
+ textlen+=strlen(text);
+ if(textlen >= PATH_MAX) goto name_error;
+ strcat(desc_file_name, text);
+ }
+
text = ".xml";
textlen+=strlen(text);
if(textlen >= PATH_MAX) goto name_error;
struct LttFacilityLoad *fac_load_data;
struct LttStateDumpFacilityLoad *fac_state_dump_load_data;
char *fac_name;
+ void *pos;
// FIXME align
switch((enum ltt_core_events)tf->event.event_id) {
fac_name = (char*)(tf->event.data);
g_debug("Doing LTT_EVENT_FACILITY_LOAD of facility %s",
fac_name);
- fac_load_data =
- (struct LttFacilityLoad *)
- (tf->event.data + strlen(fac_name) + 1);
+ pos = (tf->event.data + strlen(fac_name) + 1);
+ pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment);
+ fac_load_data = (struct LttFacilityLoad *)pos;
+
fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id));
/* facility may already exist if trace is paused/unpaused */
fac->id = ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id);
fac->pointer_size = ltt_get_uint32(LTT_GET_BO(tf),
&fac_load_data->pointer_size);
- fac->int_size = ltt_get_uint32(LTT_GET_BO(tf),
- &fac_load_data->int_size);
+ fac->int_size = ltt_get_uint32(LTT_GET_BO(tf),
+ &fac_load_data->int_size);
fac->long_size = ltt_get_uint32(LTT_GET_BO(tf),
&fac_load_data->long_size);
fac->size_t_size = ltt_get_uint32(LTT_GET_BO(tf),
/* Preset the field offsets */
for(i=0; i<fac->events->len; i++){
et = &g_array_index(fac->events, LttEventType, i);
- precompute_offsets(tf, et);
+ precompute_offsets(fac, et);
}
fac->exists = 1;
fac_name = (char*)(tf->event.data);
g_debug("Doing LTT_EVENT_STATE_DUMP_FACILITY_LOAD of facility %s",
fac_name);
- fac_state_dump_load_data =
- (struct LttStateDumpFacilityLoad *)
- (tf->event.data + strlen(fac_name) + 1);
+ pos = (tf->event.data + strlen(fac_name) + 1);
+ pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment);
+ fac_state_dump_load_data = (struct LttStateDumpFacilityLoad *)pos;
+
fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
ltt_get_uint32(LTT_GET_BO(tf), &fac_state_dump_load_data->id));
/* facility may already exist if trace is paused/unpaused */
&fac_state_dump_load_data->id);
fac->pointer_size = ltt_get_uint32(LTT_GET_BO(tf),
&fac_state_dump_load_data->pointer_size);
- fac->int_size = ltt_get_uint32(LTT_GET_BO(tf),
- &fac_state_dump_load_data->int_size);
+ fac->int_size = ltt_get_uint32(LTT_GET_BO(tf),
+ &fac_state_dump_load_data->int_size);
fac->long_size = ltt_get_uint32(LTT_GET_BO(tf),
&fac_state_dump_load_data->long_size);
fac->size_t_size = ltt_get_uint32(LTT_GET_BO(tf),
/* Preset the field offsets */
for(i=0; i<fac->events->len; i++){
et = &g_array_index(fac->events, LttEventType, i);
- precompute_offsets(tf, et);
+ precompute_offsets(fac, et);
}
fac->exists = 1;
-guint ltt_tracefile_num(LttTracefile *tf)
+guint ltt_tracefile_cpu(LttTracefile *tf)
{
return tf->cpu_num;
}
+guint ltt_tracefile_tid(LttTracefile *tf)
+{
+ return tf->tid;
+}
+
+guint ltt_tracefile_pgid(LttTracefile *tf)
+{
+ return tf->pgid;
+}
+
+guint64 ltt_tracefile_creation(LttTracefile *tf)
+{
+ return tf->creation;
+}
/*****************************************************************************
* Get the number of blocks in the tracefile
****************************************************************************/
tf->event.offset = ep->offset;
+ /* Put back the event real tsc */
+ tf->event.tsc = ep->tsc;
+ tf->buffer.tsc = ep->tsc;
+
err = ltt_tracefile_read_update_event(tf);
if(err) goto fail;
err = ltt_tracefile_read_op(tf);
return 1;
}
-/* Calculate the real event time based on the buffer boundaries */
-LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event)
+LttTime ltt_interpolate_time_from_tsc(LttTracefile *tf, guint64 tsc)
{
LttTime time;
-
- g_assert(tf->trace->has_tsc);
-
-// time = ltt_time_from_uint64(
-// cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count)));
- time = ltt_time_from_uint64(
- (double)(tf->buffer.tsc - tf->trace->start_tsc) * 1000000.0
- / (double)tf->trace->start_freq);
- //time = ltt_time_add(tf->buffer.begin.timestamp, time);
- time = ltt_time_add(tf->trace->start_time_from_tsc, time);
-
+
+ if(tsc > tf->trace->start_tsc) {
+ time = ltt_time_from_uint64(
+ (double)(tsc - tf->trace->start_tsc)
+ * (1000000000.0 / tf->trace->freq_scale)
+ / (double)tf->trace->start_freq);
+ time = ltt_time_add(tf->trace->start_time_from_tsc, time);
+ } else {
+ time = ltt_time_from_uint64(
+ (double)(tf->trace->start_tsc - tsc)
+ * (1000000000.0 / tf->trace->freq_scale)
+ / (double)tf->trace->start_freq);
+ time = ltt_time_sub(tf->trace->start_time_from_tsc, time);
+ }
return time;
}
+/* Calculate the real event time based on the buffer boundaries */
+LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event)
+{
+ return ltt_interpolate_time_from_tsc(tf, tf->buffer.tsc);
+}
+
/* Get the current event of the tracefile : valid until the next read */
LttEvent *ltt_tracefile_get_event(LttTracefile *tf)
/* Align the head */
pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment);
- if(tf->trace->has_tsc) {
- if(tf->trace->has_heartbeat) {
- event->time.timestamp = ltt_get_uint32(LTT_GET_BO(tf),
- pos);
- /* 32 bits -> 64 bits tsc */
- /* note : still works for seek and non seek cases. */
- if(event->time.timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
- tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
- + 0x100000000ULL)
- | (guint64)event->time.timestamp;
- event->tsc = tf->buffer.tsc;
- } else {
- /* no overflow */
- tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL)
- | (guint64)event->time.timestamp;
- event->tsc = tf->buffer.tsc;
- }
- pos += sizeof(guint32);
- } else {
- event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
- tf->buffer.tsc = event->tsc;
- pos += sizeof(guint64);
- }
-
- event->event_time = ltt_interpolate_time(tf, event);
- } else {
- event->time.delta.tv_sec = 0;
- event->time.delta.tv_nsec = ltt_get_uint32(LTT_GET_BO(tf),
- pos) * NSEC_PER_USEC;
- tf->buffer.tsc = 0;
- event->tsc = tf->buffer.tsc;
-
- event->event_time = ltt_time_add(tf->buffer.begin.timestamp,
- event->time.delta);
- pos += sizeof(guint32);
- }
-
+ if(tf->trace->has_heartbeat) {
+ event->timestamp = ltt_get_uint32(LTT_GET_BO(tf),
+ pos);
+ /* 32 bits -> 64 bits tsc */
+ /* note : still works for seek and non seek cases. */
+ if(event->timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
+ tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+ + 0x100000000ULL)
+ | (guint64)event->timestamp;
+ event->tsc = tf->buffer.tsc;
+ } else {
+ /* no overflow */
+ tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+ | (guint64)event->timestamp;
+ event->tsc = tf->buffer.tsc;
+ }
+ pos += sizeof(guint32);
+ } else {
+ event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
+ tf->buffer.tsc = event->tsc;
+ pos += sizeof(guint64);
+ }
+ event->event_time = ltt_interpolate_time(tf, event);
event->facility_id = *(guint8*)pos;
pos += sizeof(guint8);
&header->begin.cycle_count);
tf->buffer.begin.freq = ltt_get_uint64(LTT_GET_BO(tf),
&header->begin.freq);
- tf->buffer.begin.timestamp = ltt_time_add(
+ if(tf->buffer.begin.freq == 0)
+ tf->buffer.begin.freq = tf->trace->start_freq;
+
+ tf->buffer.begin.timestamp = ltt_interpolate_time_from_tsc(tf,
+ tf->buffer.begin.cycle_count);
+#if 0
+ ltt_time_add(
ltt_time_from_uint64(
(double)(tf->buffer.begin.cycle_count
- tf->trace->start_tsc) * 1000000.0
/ (double)tf->trace->start_freq),
- tf->trace->start_time_from_tsc);
+ tf->trace->start_time_from_tsc);
+#endif //0
#if 0
tf->buffer.end.timestamp = ltt_time_add(
&header->end.cycle_count);
tf->buffer.end.freq = ltt_get_uint64(LTT_GET_BO(tf),
&header->end.freq);
+ if(tf->buffer.end.freq == 0)
+ tf->buffer.end.freq = tf->trace->start_freq;
+
tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf),
&header->lost_size);
- tf->buffer.end.timestamp = ltt_time_add(
+ tf->buffer.end.timestamp = ltt_interpolate_time_from_tsc(tf,
+ tf->buffer.end.cycle_count);
+#if 0
+ ltt_time_add(
ltt_time_from_uint64(
(double)(tf->buffer.end.cycle_count
- tf->trace->start_tsc) * 1000000.0
/ (double)tf->trace->start_freq),
tf->trace->start_time_from_tsc);
-
+#endif //0
tf->buffer.tsc = tf->buffer.begin.cycle_count;
tf->event.tsc = tf->buffer.tsc;
tf->buffer.freq = tf->buffer.begin.freq;
void ltt_update_event_size(LttTracefile *tf)
{
off_t size = 0;
-
- /* Specific handling of core events : necessary to read the facility control
- * tracefile. */
LttFacility *f = ltt_trace_get_facility_by_num(tf->trace,
tf->event.facility_id);
-
- if(likely(tf->event.facility_id == LTT_FACILITY_CORE)) {
- switch((enum ltt_core_events)tf->event.event_id) {
- case LTT_EVENT_FACILITY_LOAD:
- size = strlen((char*)tf->event.data) + 1;
- //g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
- size += sizeof(struct LttFacilityLoad);
- break;
- case LTT_EVENT_FACILITY_UNLOAD:
- //g_debug("Update Event facility unload");
- size = sizeof(struct LttFacilityUnload);
- break;
- case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
- size = strlen((char*)tf->event.data) + 1;
- //g_debug("Update Event facility load state dump of facility %s",
- // (char*)tf->event.data);
- size += sizeof(struct LttStateDumpFacilityLoad);
- break;
- case LTT_EVENT_HEARTBEAT:
- //g_debug("Update 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 {
- if(!f->exists) {
- g_error("Unknown facility %hhu (0x%hhx) in tracefile %s",
+
+ if(!f->exists) {
+ /* Specific handling of core events : necessary to read the facility control
+ * tracefile. */
+
+ if(likely(tf->event.facility_id == LTT_FACILITY_CORE)) {
+ switch((enum ltt_core_events)tf->event.event_id) {
+ case LTT_EVENT_FACILITY_LOAD:
+ size = strlen((char*)tf->event.data) + 1;
+ //g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
+ size += ltt_align(size, sizeof(guint32), tf->has_alignment);
+ size += sizeof(struct LttFacilityLoad);
+ break;
+ case LTT_EVENT_FACILITY_UNLOAD:
+ //g_debug("Update Event facility unload");
+ size = sizeof(struct LttFacilityUnload);
+ break;
+ case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
+ size = strlen((char*)tf->event.data) + 1;
+ size += ltt_align(size, sizeof(guint32), tf->has_alignment);
+ //g_debug("Update Event facility load state dump of facility %s",
+ // (char*)tf->event.data);
+ size += sizeof(struct LttStateDumpFacilityLoad);
+ break;
+ case LTT_EVENT_HEARTBEAT:
+ //g_debug("Update 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;
+
+ }
+ goto no_offset; /* Skip the field computation */
+ } else {
+ g_warning("Unknown facility %hhu (0x%hhx) in tracefile %s",
tf->event.facility_id,
tf->event.facility_id,
g_quark_to_string(tf->name));
goto facility_error;
}
+ }
- LttEventType *event_type =
- ltt_facility_eventtype_get(f, tf->event.event_id);
+ LttEventType *event_type =
+ ltt_facility_eventtype_get(f, tf->event.event_id);
- if(!event_type) {
- g_error("Unknown event id %hhu in facility %s in tracefile %s",
- tf->event.event_id,
- g_quark_to_string(f->name),
- g_quark_to_string(tf->name));
- goto event_type_error;
- }
-
- /* Compute the dynamic offsets */
- compute_offsets(tf, event_type, &size, tf->event.data);
-
- //g_debug("Event root field : f.e %hhu.%hhu size %zd",
- // tf->event.facility_id,
- // tf->event.event_id, size);
+ if(!event_type) {
+ g_warning("Unknown event id %hhu in facility %s in tracefile %s",
+ tf->event.event_id,
+ g_quark_to_string(f->name),
+ g_quark_to_string(tf->name));
+ goto event_type_error;
}
+ /* Compute the dynamic offsets */
+ compute_offsets(tf, f, event_type, &size, tf->event.data);
+
+ //g_debug("Event root field : f.e %hhu.%hhu size %zd",
+ // tf->event.facility_id,
+ // tf->event.event_id, size);
+
+no_offset:
tf->event.data_size = size;
/* Check consistency between kernel and LTTV structure sizes */
+ if(tf->event.event_size == 0xFFFF) {
+ /* Event size too big to fit in the event size field */
+ tf->event.event_size = tf->event.data_size;
+ }
g_assert(tf->event.data_size == tf->event.event_size);
return;
facility_error:
event_type_error:
event_id_error:
- tf->event.data_size = 0;
+ if(tf->event.event_size == 0xFFFF) {
+ g_error("Cannot jump over an unknown event bigger than 0xFFFE bytes");
+ }
+ /* The facility is unknown : use the kernel information about this event
+ * to jump over it. */
+ tf->event.data_size = tf->event.event_size;
}
*Function name
* get_alignment : Get the alignment needed for a field.
*Input params
- * tf : tracefile
* field : field
*
* returns : The size on which it must be aligned.
*
****************************************************************************/
-off_t get_alignment(LttTracefile *tf, LttField *field)
+off_t get_alignment(LttField *field)
{
LttType *type = &field->field_type;
case LTT_FLOAT:
case LTT_ENUM:
/* Align offset on type size */
+ g_assert(field->field_size != 0);
return field->field_size;
break;
case LTT_STRING:
- return 0;
+ return 1;
break;
case LTT_ARRAY:
g_assert(type->fields->len == 1);
{
LttField *child = &g_array_index(type->fields, LttField, 0);
- return get_alignment(tf, child);
+ return get_alignment(child);
}
break;
case LTT_SEQUENCE:
g_assert(type->fields->len == 2);
{
- off_t localign = 0;
+ off_t localign = 1;
LttField *child = &g_array_index(type->fields, LttField, 0);
- localign = max(localign, get_alignment(tf, child));
+ localign = max(localign, get_alignment(child));
child = &g_array_index(type->fields, LttField, 1);
- localign = max(localign, get_alignment(tf, child));
+ localign = max(localign, get_alignment(child));
return localign;
}
case LTT_UNION:
{
guint i;
- off_t localign = 0;
+ off_t localign = 1;
for(i=0; i<type->fields->len; i++) {
LttField *child = &g_array_index(type->fields, LttField, i);
- localign = max(localign, get_alignment(tf, child));
+ localign = max(localign, get_alignment(child));
}
return localign;
}
case LTT_NONE:
default:
g_error("get_alignment : unknown type");
+ return -1;
}
-
}
/*****************************************************************************
*
****************************************************************************/
-void field_compute_static_size(LttTracefile *tf, LttField *field)
+void field_compute_static_size(LttFacility *fac, LttField *field)
{
LttType *type = &field->field_type;
g_assert(type->fields->len == 1);
{
LttField *child = &g_array_index(type->fields, LttField, 0);
- field_compute_static_size(tf, child);
+ field_compute_static_size(fac, child);
if(child->field_size != 0) {
field->field_size = type->size * child->field_size;
{
off_t local_offset = 0;
LttField *child = &g_array_index(type->fields, LttField, 1);
- field_compute_static_size(tf, child);
+ field_compute_static_size(fac, child);
field->field_size = 0;
type->size = 0;
if(child->field_size != 0) {
guint i;
for(i=0;i<type->fields->len;i++) {
LttField *child = &g_array_index(type->fields, LttField, i);
- field_compute_static_size(tf, child);
+ field_compute_static_size(fac, child);
if(child->field_size != 0) {
- type->size += ltt_align(type->size, get_alignment(tf, child),
- tf->has_alignment);
+ type->size += ltt_align(type->size, get_alignment(child),
+ fac->alignment);
type->size += child->field_size;
} else {
/* As soon as we find a child with variable size, we have
*Function name
* precompute_fields_offsets : set the precomputable offset of the fields
*Input params
- * tf : tracefile
+ * fac : facility
* field : the field
* offset : pointer to the current offset, must be incremented
*
****************************************************************************/
-gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset)
+gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset)
{
LttType *type = &field->field_type;
case LTT_OFF_T:
case LTT_FLOAT:
case LTT_ENUM:
+ g_assert(field->field_size != 0);
/* Align offset on type size */
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
{
LttField *child = &g_array_index(type->fields, LttField, 0);
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
LttField *child;
guint ret;
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
child = &g_array_index(type->fields, LttField, 0);
- ret = precompute_fields_offsets(tf, child, offset);
+ ret = precompute_fields_offsets(fac, child, offset);
g_assert(ret == 0); /* Seq len cannot have variable len */
child = &g_array_index(type->fields, LttField, 1);
- *offset += ltt_align(*offset, get_alignment(tf, child),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(child),
+ fac->alignment);
field->array_offset = *offset;
- /* Set the offset position at position 0 */
- ret = precompute_fields_offsets(tf, child, offset);
+ /* Let the child be variable. */
+ //ret = precompute_fields_offsets(fac, child, offset);
/* Cannot precompute fields offsets of sequence members, and has
* variable length. */
guint i;
gint ret=0;
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
for(i=0; i< type->fields->len; i++) {
child = &g_array_index(type->fields, LttField, i);
- ret = precompute_fields_offsets(tf, child, offset);
+ ret = precompute_fields_offsets(fac, child, offset);
if(ret) break;
}
guint i;
gint ret=0;
- *offset += ltt_align(*offset, get_alignment(tf, field),
- tf->has_alignment);
+ *offset += ltt_align(*offset, get_alignment(field),
+ fac->alignment);
/* remember offset */
field->offset_root = *offset;
field->fixed_root = FIELD_FIXED;
for(i=0; i< type->fields->len; i++) {
*offset = field->offset_root;
child = &g_array_index(type->fields, LttField, i);
- ret = precompute_fields_offsets(tf, child, offset);
+ ret = precompute_fields_offsets(fac, child, offset);
if(ret) break;
}
* event : event type
*
****************************************************************************/
-void precompute_offsets(LttTracefile *tf, LttEventType *event)
+void precompute_offsets(LttFacility *fac, LttEventType *event)
{
guint i;
off_t offset = 0;
* arrays, struct and unions, which is not done by the parser */
for(i=0; i<event->fields->len; i++) {
LttField *field = &g_array_index(event->fields, LttField, i);
- field_compute_static_size(tf, field);
+ field_compute_static_size(fac, field);
}
/* Precompute all known offsets */
for(i=0; i<event->fields->len; i++) {
LttField *field = &g_array_index(event->fields, LttField, i);
- ret = precompute_fields_offsets(tf, field, &offset);
+ ret = precompute_fields_offsets(fac, field, &offset);
if(ret) break;
}
}
size_t max_size;
switch(type->type_class) {
+ case LTT_INT_FIXED:
+ case LTT_UINT_FIXED:
+ case LTT_CHAR:
+ case LTT_UCHAR:
+ case LTT_SHORT:
+ case LTT_USHORT:
case LTT_INT:
case LTT_UINT:
case LTT_FLOAT:
field->fixed_size = FIELD_FIXED;
}
break;
+ case LTT_NONE:
+ g_error("unexpected type NONE");
+ break;
}
}
different = 1;
goto end;
}
+ if(type1->network != type2->network) {
+ different = 1;
+ goto end;
+ }
switch(type1->type_class) {
case LTT_INT_FIXED:
}
switch(type1->type_class) {
+ case LTT_INT_FIXED:
+ case LTT_UINT_FIXED:
+ case LTT_POINTER:
+ case LTT_CHAR:
+ case LTT_UCHAR:
+ case LTT_SHORT:
+ case LTT_USHORT:
case LTT_INT:
case LTT_UINT:
case LTT_FLOAT: