+ tf->buffer.end.timestamp = ltt_time_add(
+ ltt_time_from_uint64(
+ ltt_get_uint64(LTT_GET_BO(tf),
+ &header->end.timestamp)
+ - tf->trace->start_monotonic),
+ tf->trace->start_time);
+#endif //0
+ //g_debug("block %u end : %lu.%lu", block_num,
+ // tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec);
+ tf->buffer.end.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
+ &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_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;
+
+ /* FIXME
+ * eventually support variable buffer size : will need a partial pre-read of
+ * the headers to create an index when we open the trace... eventually. */
+ g_assert(tf->buf_size == ltt_get_uint32(LTT_GET_BO(tf),
+ &header->buf_size));
+
+ /* Now that the buffer is mapped, calculate the time interpolation for the
+ * block. */
+
+// tf->buffer.nsecs_per_cycle = calc_nsecs_per_cycle(tf);
+ //tf->buffer.cyc2ns_scale = calc_nsecs_per_cycle(tf);
+
+ /* Make the current event point to the beginning of the buffer :
+ * it means that the event read must get the first event. */
+ tf->event.tracefile = tf;
+ tf->event.block = block_num;
+ tf->event.offset = 0;
+
+ return 0;
+
+map_error:
+ return -errno;
+
+}
+
+/* It will update the fields offsets too */
+void ltt_update_event_size(LttTracefile *tf)
+{
+ off_t size = 0;
+ char *tscdata;
+ struct marker_info *info;
+
+ switch((enum marker_id)tf->event.event_id) {
+ case MARKER_ID_SET_MARKER_ID:
+ size = strlen((char*)tf->event.data) + 1;
+ //g_debug("marker %s id set", (char*)tf->event.data);
+ size += ltt_align(size, sizeof(guint16), tf->has_alignment);
+ size += sizeof(guint16);
+ size += sizeof(guint8);
+ size += sizeof(guint8);
+ size += sizeof(guint8);
+ size += sizeof(guint8);
+ size += sizeof(guint8);
+ break;
+ case MARKER_ID_SET_MARKER_FORMAT:
+ //g_debug("marker %s format set", (char*)tf->event.data);
+ size = strlen((char*)tf->event.data) + 1;
+ size += strlen((char*)tf->event.data) + 1;
+ break;
+ case MARKER_ID_HEARTBEAT_32:
+ //g_debug("Update Event heartbeat 32 bits");
+ size = ltt_align(size, sizeof(guint32), tf->has_alignment);
+ size += sizeof(guint32);
+ break;
+ case MARKER_ID_HEARTBEAT_64:
+ //g_debug("Update Event heartbeat 64 bits");
+ tscdata = (char*)(tf->event.data);
+ tf->event.tsc = ltt_get_uint64(LTT_GET_BO(tf), tscdata);
+ tf->buffer.tsc = tf->event.tsc;
+ tf->event.event_time = ltt_interpolate_time(tf, &tf->event);
+ size = ltt_align(size, sizeof(guint64), tf->has_alignment);
+ size += sizeof(guint64);
+ break;
+ default:
+ info = marker_get_info_from_id(tf->trace, tf->event.event_id);
+ g_assert(info != NULL);
+ if (info->size != -1) {
+ size = info->size;
+ } else {
+ size = marker_update_fields_offsets(marker_get_info_from_id(tf->trace,
+ tf->event.event_id), tf->event.data);
+ }
+ }
+
+ 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;
+ }
+ if (tf->event.data_size != tf->event.event_size) {
+ struct marker_info *info = marker_get_info_from_id(tf->trace,
+ tf->event.event_id);
+ g_error("Kernel/LTTV event size differs for event %s: kernel %u, LTTV %u",
+ g_quark_to_string(info->name),
+ tf->event.event_size, tf->event.data_size);
+ exit(-1);
+ }
+
+#if 0
+ LttEventType *event_type =
+ ltt_facility_eventtype_get(f, tf->event.event_id);
+
+ 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;
+ }
+ if (tf->event.data_size != tf->event.event_size) {
+ g_error("Kernel/LTTV event size differs for event %s.%s: kernel %u, LTTV %u",
+ g_quark_to_string(f->name), g_quark_to_string(event_type->name),
+ tf->event.event_size, tf->event.data_size);
+ exit(-1);
+ }
+ //g_assert(tf->event.data_size == tf->event.event_size);
+
+ return;
+
+event_type_error:
+event_id_error:
+ 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;
+#endif //0
+}
+
+
+/* Take the tf current event offset and use the event facility id and event id
+ * to figure out where is the next event offset.
+ *
+ * This is an internal function not aiming at being used elsewhere : it will
+ * not jump over the current block limits. Please consider using
+ * ltt_tracefile_read to do this.
+ *
+ * Returns 0 on success
+ * ERANGE if we are at the end of the buffer.
+ * ENOPROTOOPT if an error occured when getting the current event size.
+ */
+int ltt_seek_next_event(LttTracefile *tf)
+{
+ int ret = 0;
+ void *pos;
+
+ /* seek over the buffer header if we are at the buffer start */
+ if(tf->event.offset == 0) {
+ tf->event.offset += tf->buffer_header_size;
+
+ if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) {
+ ret = ERANGE;
+ }
+ goto found;
+ }
+
+
+ pos = tf->event.data;
+
+ if(tf->event.data_size < 0) goto error;
+
+ pos += (size_t)tf->event.data_size;
+
+ tf->event.offset = pos - tf->buffer.head;
+
+ if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) {
+ ret = ERANGE;
+ goto found;