X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=formats%2Fctf%2Fctf.c;h=32206166b2a2c43a637dbf7e0e36489d297bd0da;hp=fa19648155964faa6a8dbedc283a2fbb2d655ab2;hb=30c276af575248a4f83e594c987264f6caa238ba;hpb=badea1a2413e25f0b1961770148e28deba8a3a3f diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index fa196481..32206166 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -23,12 +23,14 @@ #include #include #include +#include +#include +#include +#include #include #include -#include #include #include -#include #include #include #include @@ -40,6 +42,8 @@ #include "metadata/ctf-scanner.h" #include "metadata/ctf-parser.h" #include "metadata/ctf-ast.h" +#include "events-private.h" +#include "memstream.h" /* * We currently simply map a page to read the packet header and packet @@ -47,7 +51,6 @@ */ #define MAX_PACKET_HEADER_LEN (getpagesize() * CHAR_BIT) #define WRITE_PACKET_LEN (getpagesize() * 8 * CHAR_BIT) -#define UUID_LEN 16 /* uuid by value len */ #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) @@ -75,9 +78,21 @@ struct trace_descriptor *ctf_open_mmap_trace( void (*packet_seek)(struct stream_pos *pos, size_t index, int whence), FILE *metadata_fp); +static +void ctf_set_context(struct trace_descriptor *descriptor, + struct bt_context *ctx); +static +void ctf_set_handle(struct trace_descriptor *descriptor, + struct bt_trace_handle *handle); static void ctf_close_trace(struct trace_descriptor *descriptor); +static +uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor, + struct bt_trace_handle *handle); +static +uint64_t ctf_timestamp_end(struct trace_descriptor *descriptor, + struct bt_trace_handle *handle); static rw_dispatch read_dispatch_table[] = { @@ -108,13 +123,104 @@ struct format ctf_format = { .open_trace = ctf_open_trace, .open_mmap_trace = ctf_open_mmap_trace, .close_trace = ctf_close_trace, + .set_context = ctf_set_context, + .set_handle = ctf_set_handle, + .timestamp_begin = ctf_timestamp_begin, + .timestamp_end = ctf_timestamp_end, }; +static +uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor, + struct bt_trace_handle *handle) +{ + struct ctf_trace *tin; + uint64_t begin = ULLONG_MAX; + int i, j; + + tin = container_of(descriptor, struct ctf_trace, parent); + + if (!tin) + goto error; + + /* for each stream_class */ + for (i = 0; i < tin->streams->len; i++) { + struct ctf_stream_declaration *stream_class; + + stream_class = g_ptr_array_index(tin->streams, i); + /* for each file_stream */ + for (j = 0; j < stream_class->streams->len; j++) { + struct ctf_stream_definition *stream; + struct ctf_file_stream *cfs; + struct ctf_stream_pos *stream_pos; + struct packet_index *index; + + stream = g_ptr_array_index(stream_class->streams, j); + cfs = container_of(stream, struct ctf_file_stream, + parent); + stream_pos = &cfs->pos; + + index = &g_array_index(stream_pos->packet_index, + struct packet_index, 0); + if (index->timestamp_begin < begin) + begin = index->timestamp_begin; + } + } + + return begin; + +error: + return -1ULL; +} + +static +uint64_t ctf_timestamp_end(struct trace_descriptor *descriptor, + struct bt_trace_handle *handle) +{ + struct ctf_trace *tin; + uint64_t end = 0; + int i, j; + + tin = container_of(descriptor, struct ctf_trace, parent); + + if (!tin) + goto error; + + /* for each stream_class */ + for (i = 0; i < tin->streams->len; i++) { + struct ctf_stream_declaration *stream_class; + + stream_class = g_ptr_array_index(tin->streams, i); + /* for each file_stream */ + for (j = 0; j < stream_class->streams->len; j++) { + struct ctf_stream_definition *stream; + struct ctf_file_stream *cfs; + struct ctf_stream_pos *stream_pos; + struct packet_index *index; + + stream = g_ptr_array_index(stream_class->streams, j); + cfs = container_of(stream, struct ctf_file_stream, + parent); + stream_pos = &cfs->pos; + + index = &g_array_index(stream_pos->packet_index, + struct packet_index, + stream_pos->packet_index->len - 1); + if (index->timestamp_end > end) + end = index->timestamp_end; + } + } + + return end; + +error: + return -1ULL; +} + /* * Update stream current timestamp, keep at clock frequency. */ static -void ctf_update_timestamp(struct ctf_stream *stream, +void ctf_update_timestamp(struct ctf_stream_definition *stream, struct definition_integer *integer_definition) { struct declaration_integer *integer_declaration = @@ -145,25 +251,18 @@ void ctf_update_timestamp(struct ctf_stream *stream, * applying offsets as needed (unix time). */ void ctf_print_timestamp(FILE *fp, - struct ctf_stream *stream, + struct ctf_stream_definition *stream, uint64_t timestamp) { uint64_t ts_sec = 0, ts_nsec; - struct ctf_trace *trace = stream->stream_class->trace; - struct trace_collection *tc = trace->collection; - uint64_t tc_offset = tc->single_clock_offset_avg; - if (stream->current_clock->freq == 1000000000ULL) { - ts_nsec = timestamp; + if (opt_clock_raw) { + ts_nsec = ctf_get_timestamp_raw(stream, timestamp); } else { - ts_nsec = (uint64_t) ((double) timestamp * 1000000000.0 - / (double) stream->current_clock->freq); + ts_nsec = ctf_get_timestamp(stream, timestamp); } - /* Add offsets */ - if (!opt_clock_raw) { - ts_nsec += tc_offset; - } + /* Add command-line offset */ ts_sec += opt_clock_offset; ts_sec += ts_nsec / NSEC_PER_SEC; @@ -217,12 +316,12 @@ end: } static -int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream) +int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream) { struct ctf_stream_pos *pos = container_of(ppos, struct ctf_stream_pos, parent); - struct ctf_stream_class *stream_class = stream->stream_class; - struct ctf_stream_event *event; + struct ctf_stream_declaration *stream_class = stream->stream_class; + struct ctf_event_definition *event; uint64_t id = 0; int ret; @@ -331,10 +430,10 @@ error: } static -int ctf_write_event(struct stream_pos *pos, struct ctf_stream *stream) +int ctf_write_event(struct stream_pos *pos, struct ctf_stream_definition *stream) { - struct ctf_stream_class *stream_class = stream->stream_class; - struct ctf_stream_event *event; + struct ctf_stream_declaration *stream_class = stream->stream_class; + struct ctf_event_definition *event; uint64_t id; int ret; @@ -695,7 +794,7 @@ int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in, memcpy(td->uuid, header.uuid, sizeof(header.uuid)); CTF_TRACE_SET_FIELD(td, uuid); } else { - if (uuid_compare(header.uuid, td->uuid)) + if (babeltrace_uuid_compare(header.uuid, td->uuid)) return -EINVAL; } @@ -754,7 +853,7 @@ int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, * because its size includes garbage at the end (after final * \0). This is the allocated size, not the actual string size. */ - out = open_memstream(buf, &size); + out = babeltrace_open_memstream(buf, &size); if (out == NULL) { perror("Metadata open_memstream"); return -errno; @@ -769,10 +868,16 @@ int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp, break; } } - fclose(out); /* flush the buffer */ + /* close to flush the buffer */ + ret = babeltrace_close_memstream(buf, &size, out); + if (ret < 0) { + perror("babeltrace_flush_memstream"); + fclose(in); + return -errno; + } fclose(in); /* open for reading */ - *fp = fmemopen(*buf, strlen(*buf), "rb"); + *fp = babeltrace_fmemopen(*buf, strlen(*buf), "rb"); if (!*fp) { perror("Metadata fmemopen"); return -errno; @@ -888,11 +993,11 @@ end_stream: } static -struct ctf_stream_event *create_event_definitions(struct ctf_trace *td, - struct ctf_stream *stream, - struct ctf_event *event) +struct ctf_event_definition *create_event_definitions(struct ctf_trace *td, + struct ctf_stream_definition *stream, + struct ctf_event_declaration *event) { - struct ctf_stream_event *stream_event = g_new0(struct ctf_stream_event, 1); + struct ctf_event_definition *stream_event = g_new0(struct ctf_event_definition, 1); if (event->context_decl) { struct definition *definition = @@ -916,6 +1021,7 @@ struct ctf_stream_event *create_event_definitions(struct ctf_trace *td, struct definition_struct, p); stream->parent_def_scope = stream_event->event_fields->p.scope; } + stream_event->stream = stream; return stream_event; error: @@ -927,9 +1033,9 @@ error: } static -int create_stream_definitions(struct ctf_trace *td, struct ctf_stream *stream) +int create_stream_definitions(struct ctf_trace *td, struct ctf_stream_definition *stream) { - struct ctf_stream_class *stream_class; + struct ctf_stream_declaration *stream_class; int ret; int i; @@ -977,8 +1083,8 @@ int create_stream_definitions(struct ctf_trace *td, struct ctf_stream *stream) stream->events_by_id = g_ptr_array_new(); g_ptr_array_set_size(stream->events_by_id, stream_class->events_by_id->len); for (i = 0; i < stream->events_by_id->len; i++) { - struct ctf_event *event = g_ptr_array_index(stream_class->events_by_id, i); - struct ctf_stream_event *stream_event; + struct ctf_event_declaration *event = g_ptr_array_index(stream_class->events_by_id, i); + struct ctf_event_definition *stream_event; if (!event) continue; @@ -991,7 +1097,7 @@ int create_stream_definitions(struct ctf_trace *td, struct ctf_stream *stream) error_event: for (i = 0; i < stream->events_by_id->len; i++) { - struct ctf_stream_event *stream_event = g_ptr_array_index(stream->events_by_id, i); + struct ctf_event_definition *stream_event = g_ptr_array_index(stream->events_by_id, i); if (stream_event) g_free(stream_event); } @@ -1011,7 +1117,7 @@ static int create_stream_packet_index(struct ctf_trace *td, struct ctf_file_stream *file_stream) { - struct ctf_stream_class *stream; + struct ctf_stream_declaration *stream; int len_index; struct ctf_stream_pos *pos; struct stat filestats; @@ -1083,20 +1189,20 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition_array *defarray; struct definition *field; uint64_t i; - uint8_t uuidval[UUID_LEN]; + uint8_t uuidval[BABELTRACE_UUID_LEN]; field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); assert(field->declaration->id == CTF_TYPE_ARRAY); defarray = container_of(field, struct definition_array, p); - assert(array_len(defarray) == UUID_LEN); + assert(array_len(defarray) == BABELTRACE_UUID_LEN); - for (i = 0; i < UUID_LEN; i++) { + for (i = 0; i < BABELTRACE_UUID_LEN; i++) { struct definition *elem; elem = array_index(defarray, i); uuidval[i] = get_unsigned_int(elem); } - ret = uuid_compare(td->uuid, uuidval); + ret = babeltrace_uuid_compare(td->uuid, uuidval); if (ret) { fprintf(stderr, "[error] Unique Universal Identifiers do not match.\n"); return -EINVAL; @@ -1226,7 +1332,7 @@ int create_stream_packet_index(struct ctf_trace *td, } static -int create_trace_definitions(struct ctf_trace *td, struct ctf_stream *stream) +int create_trace_definitions(struct ctf_trace *td, struct ctf_stream_definition *stream) { int ret; @@ -1452,7 +1558,7 @@ static int prepare_mmap_stream_definition(struct ctf_trace *td, struct ctf_file_stream *file_stream) { - struct ctf_stream_class *stream; + struct ctf_stream_declaration *stream; uint64_t stream_id = 0; int ret; @@ -1591,7 +1697,7 @@ void ctf_close_trace(struct trace_descriptor *tdp) if (td->streams) { for (i = 0; i < td->streams->len; i++) { - struct ctf_stream_class *stream; + struct ctf_stream_declaration *stream; int j; stream = g_ptr_array_index(td->streams, i); @@ -1606,10 +1712,40 @@ void ctf_close_trace(struct trace_descriptor *tdp) } g_ptr_array_free(td->streams, TRUE); } + + if (td->event_declarations) { + for (i = 0; i < td->event_declarations->len; i++) { + struct bt_ctf_event_decl *event; + + event = g_ptr_array_index(td->event_declarations, i); + g_free(event); + } + g_ptr_array_free(td->event_declarations, TRUE); + } closedir(td->dir); g_free(td); } +static +void ctf_set_context(struct trace_descriptor *descriptor, + struct bt_context *ctx) +{ + struct ctf_trace *td = container_of(descriptor, struct ctf_trace, + parent); + + td->ctx = ctx; +} + +static +void ctf_set_handle(struct trace_descriptor *descriptor, + struct bt_trace_handle *handle) +{ + struct ctf_trace *td = container_of(descriptor, struct ctf_trace, + parent); + + td->handle = handle; +} + void __attribute__((constructor)) ctf_init(void) { int ret;