#define NSEC_PER_USEC 1000
-#define LTT_PACKED_STRUCT __attribute__ ((packed))
-
/* Byte ordering */
#define LTT_GET_BO(t) ((t)->reverse_bo)
-#define LTT_HAS_FLOAT(t) ((t)->float_word_order!=0)
+#define LTT_HAS_FLOAT(t) ((t)->float_word_order ! =0)
#define LTT_GET_FLOAT_BO(t) \
- (((t)->float_word_order==__BYTE_ORDER)?0:1)
+ (((t)->float_word_order == __BYTE_ORDER) ? 0 : 1)
#define SEQUENCE_AVG_ELEMENTS 1000
typedef guint32 uint32_t;
typedef guint64 uint64_t;
-/* Block and trace headers */
-
-struct ltt_trace_header_any {
- uint32_t magic_number;
- uint32_t arch_type;
- uint32_t arch_variant;
- uint32_t float_word_order;
- uint8_t arch_size;
- uint8_t major_version;
- uint8_t minor_version;
- uint8_t flight_recorder;
- uint8_t alignment; /* Architecture alignment */
-} LTT_PACKED_STRUCT;
-
-struct ltt_trace_header_2_0 {
- uint32_t magic_number;
- uint32_t arch_type;
- uint32_t arch_variant;
- uint32_t float_word_order;
- uint8_t arch_size;
- uint8_t major_version;
- uint8_t minor_version;
- uint8_t flight_recorder;
- uint8_t alignment; /* Architecture alignment */
- uint8_t tscbits;
- uint8_t eventbits;
- uint8_t unused1;
- uint32_t freq_scale;
- uint64_t start_freq;
- uint64_t start_tsc;
- uint64_t start_monotonic;
- uint64_t start_time_sec;
- uint64_t start_time_usec;
-} LTT_PACKED_STRUCT;
-
-struct ltt_block_start_header {
- struct {
- uint64_t cycle_count;
- uint64_t freq;
- } begin;
- struct {
- uint64_t cycle_count;
- uint64_t freq;
- } end;
- uint32_t lost_size; /* Size unused at the end of the buffer */
- uint32_t buf_size; /* The size of this sub-buffer */
- struct ltt_trace_header_any trace[0];
-} LTT_PACKED_STRUCT;
+/* Subbuffer header */
+struct ltt_subbuffer_header_2_0 {
+ uint64_t cycle_count_begin; /* Cycle count at subbuffer start */
+ uint64_t cycle_count_end; /* Cycle count at subbuffer end */
+ uint32_t magic_number; /* Trace magic number.
+ * contains endianness information.
+ */
+ uint8_t major_version;
+ uint8_t minor_version;
+ uint8_t arch_size; /* Architecture pointer size */
+ uint8_t alignment; /* LTT data alignment */
+ uint64_t start_time_sec; /* NTP-corrected start time */
+ uint64_t start_time_usec;
+ uint64_t start_freq; /*
+ * Frequency at trace start,
+ * used all along the trace.
+ */
+ uint32_t freq_scale; /* Frequency scaling */
+ uint32_t lost_size; /* Size unused at end of subbuffer */
+ uint32_t buf_size; /* Size of this subbuffer */
+};
+typedef struct ltt_subbuffer_header_2_0 ltt_subbuffer_header_t;
enum field_status { FIELD_UNKNOWN, FIELD_VARIABLE, FIELD_FIXED };
/* Timekeeping */
uint64_t tsc; /* Current timestamp counter */
uint64_t freq; /* Frequency in khz */
- //double nsecs_per_cycle; /* Precalculated from freq */
guint32 cyc2ns_scale;
} LttBuffer;
*
* Return value : 0 success, 1 bad tracefile
*/
-static int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
+static int parse_trace_header(ltt_subbuffer_header_t *header,
+ LttTracefile *tf, LttTrace *t)
{
- guint32 *magic_number = (guint32*)header;
- struct ltt_trace_header_any *any = (struct ltt_trace_header_any *)header;
-
- if(*magic_number == LTT_MAGIC_NUMBER)
+ if (header->magic_number == LTT_MAGIC_NUMBER)
tf->reverse_bo = 0;
- else if(*magic_number == LTT_REV_MAGIC_NUMBER)
+ else if(header->magic_number == LTT_REV_MAGIC_NUMBER)
tf->reverse_bo = 1;
else /* invalid magic number, bad tracefile ! */
return 1;
-
+
+ if(t) {
+ t->ltt_major_version = header->major_version;
+ t->ltt_minor_version = header->minor_version;
+ t->arch_size = header->arch_size;
+ }
+ tf->alignment = header->alignment;
+
/* Get float byte order : might be different from int byte order
* (or is set to 0 if the trace has no float (kernel trace)) */
- tf->float_word_order = any->float_word_order;
- tf->alignment = any->alignment;
+ tf->float_word_order = 0;
- if(t) {
- t->arch_type = ltt_get_uint32(LTT_GET_BO(tf),
- &any->arch_type);
- t->arch_variant = ltt_get_uint32(LTT_GET_BO(tf),
- &any->arch_variant);
- t->arch_size = any->arch_size;
- t->ltt_major_version = any->major_version;
- t->ltt_minor_version = any->minor_version;
- t->flight_recorder = any->flight_recorder;
- }
-
- switch(any->major_version) {
+ switch(header->major_version) {
case 0:
case 1:
g_warning("Unsupported trace version : %hhu.%hhu",
- any->major_version, any->minor_version);
+ header->major_version, header->minor_version);
return 1;
break;
case 2:
- switch(any->minor_version) {
+ switch(header->minor_version) {
case 0:
{
- struct ltt_trace_header_2_0 *vheader =
- (struct ltt_trace_header_2_0 *)header;
- tf->buffer_header_size =
- sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_2_0);
- tf->tscbits = vheader->tscbits;
- tf->eventbits = vheader->eventbits;
+ struct ltt_subbuffer_header_2_0 *vheader = header;
+ tf->buffer_header_size = sizeof(struct ltt_subbuffer_header_2_0) ;
+ tf->tscbits = 27;
+ tf->eventbits = 5;
tf->tsc_mask = ((1ULL << tf->tscbits) - 1);
tf->tsc_mask_next_bit = (1ULL << tf->tscbits);
if(father_trace) {
t->start_freq = father_trace->start_freq;
t->freq_scale = father_trace->freq_scale;
- }
- else {
+ } else {
father_trace = t;
}
t->start_tsc = ltt_get_uint64(LTT_GET_BO(tf),
- &vheader->start_tsc);
- t->start_monotonic = ltt_get_uint64(LTT_GET_BO(tf),
- &vheader->start_monotonic);
+ &vheader->cycle_count_begin);
+ t->start_monotonic = 0;
t->start_time.tv_sec = ltt_get_uint64(LTT_GET_BO(tf),
&vheader->start_time_sec);
t->start_time.tv_nsec = ltt_get_uint64(LTT_GET_BO(tf),
break;
default:
g_warning("Unsupported trace version : %hhu.%hhu",
- any->major_version, any->minor_version);
+ header->major_version, header->minor_version);
return 1;
}
break;
default:
g_warning("Unsupported trace version : %hhu.%hhu",
- any->major_version, any->minor_version);
+ header->major_version, header->minor_version);
return 1;
}
-
-
return 0;
}
static gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
{
struct stat lTDFStat; /* Trace data file status */
- struct ltt_block_start_header *header;
+ ltt_subbuffer_header_t *header;
int page_size = getpagesize();
//open the file
// Is the file large enough to contain a trace
if(lTDFStat.st_size <
- (off_t)(sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_any))){
+ (off_t)(sizeof(ltt_subbuffer_header_t))){
g_print("The input data file %s does not contain a trace\n", fileName);
goto close_file;
}
/* Temporarily map the buffer start header to get trace information */
/* Multiple of pages aligned head */
tf->buffer.head = mmap(0,
- PAGE_ALIGN(sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_any)), PROT_READ,
+ PAGE_ALIGN(sizeof(ltt_subbuffer_header_t)), PROT_READ,
MAP_PRIVATE, tf->fd, 0);
if(tf->buffer.head == MAP_FAILED) {
perror("Error in allocating memory for buffer of tracefile");
}
g_assert( ( (gulong)tf->buffer.head&(8-1) ) == 0); // make sure it's aligned.
- header = (struct ltt_block_start_header*)tf->buffer.head;
+ header = (ltt_subbuffer_header_t *)tf->buffer.head;
- if(parse_trace_header(header->trace, tf, NULL)) {
+ if(parse_trace_header(header, tf, NULL)) {
g_warning("parse_trace_header error");
goto unmap_file;
}
tf->num_blocks = tf->file_size / tf->buf_size;
if(munmap(tf->buffer.head,
- PAGE_ALIGN(sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_any)))) {
+ PAGE_ALIGN(sizeof(ltt_subbuffer_header_t)))) {
g_warning("unmap size : %u\n",
- PAGE_ALIGN(sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_any)));
+ PAGE_ALIGN(sizeof(ltt_subbuffer_header_t)));
perror("munmap error");
g_assert(0);
}
/* Error */
unmap_file:
if(munmap(tf->buffer.head,
- PAGE_ALIGN(sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_any)))) {
+ PAGE_ALIGN(sizeof(ltt_subbuffer_header_t)))) {
g_warning("unmap size : %u\n",
- PAGE_ALIGN(sizeof(struct ltt_block_start_header)
- + sizeof(struct ltt_trace_header_any)));
+ PAGE_ALIGN(sizeof(ltt_subbuffer_header_t)));
perror("munmap error");
g_assert(0);
}
LttTracefile *tf;
GArray *group;
int i, ret;
- struct ltt_block_start_header *header;
+ ltt_subbuffer_header_t *header;
DIR *dir;
struct dirent *entry;
guint control_found = 0;
/* Get the trace information for the control/metadata_0 tracefile */
g_assert(group->len > 0);
tf = &g_array_index (group, LttTracefile, 0);
- header = (struct ltt_block_start_header*)tf->buffer.head;
- g_assert(parse_trace_header(header->trace,
- tf, t) == 0);
+ header = (ltt_subbuffer_header_t *)tf->buffer.head;
+ g_assert(parse_trace_header(header, tf, t) == 0);
t->num_cpu = group->len;
static gint map_block(LttTracefile * tf, guint block_num)
{
int page_size = getpagesize();
- struct ltt_block_start_header *header;
+ ltt_subbuffer_header_t *header;
g_assert(block_num < tf->num_blocks);
tf->buffer.index = block_num;
- header = (struct ltt_block_start_header*)tf->buffer.head;
+ header = (ltt_subbuffer_header_t *)tf->buffer.head;
tf->buffer.begin.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
- &header->begin.cycle_count);
- tf->buffer.begin.freq = ltt_get_uint64(LTT_GET_BO(tf),
- &header->begin.freq);
- if(tf->buffer.begin.freq == 0)
- tf->buffer.begin.freq = tf->trace->start_freq;
+ &header->cycle_count_begin);
+ tf->buffer.begin.freq = tf->trace->start_freq;
tf->buffer.begin.timestamp = ltt_interpolate_time_from_tsc(tf,
tf->buffer.begin.cycle_count);
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;
+ &header->cycle_count_end);
+ tf->buffer.end.freq = tf->trace->start_freq;
tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf),
&header->lost_size);