* Julien Desfossez ([email protected]) wrote: > Add a new library to allow external tools to read traces. > Updated convert_trace to use this API.
Merged and pushed (with minor edit). Thanks! Mathieu > > Signed-off-by: Julien Desfossez <[email protected]> > --- > converter/babeltrace-api.h | 95 ++++++++++++++++++++++++++++++ > converter/babeltrace-lib.c | 137 > +++++++++++++++++++++++++++++++------------- > 2 files changed, 193 insertions(+), 39 deletions(-) > create mode 100644 converter/babeltrace-api.h > > diff --git a/converter/babeltrace-api.h b/converter/babeltrace-api.h > new file mode 100644 > index 0000000..d95f091 > --- /dev/null > +++ b/converter/babeltrace-api.h > @@ -0,0 +1,95 @@ > +#ifndef _BABELTRACE_LIB_H > +#define _BABELTRACE_LIB_H > + > +/* > + * BabelTrace API > + * > + * Copyright 2010-2011 - Mathieu Desnoyers <[email protected]> > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > copy > + * of this software and associated documentation files (the "Software"), to > deal > + * in the Software without restriction, including without limitation the > rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + */ > + > +#include <babeltrace/types.h> > +#include <babeltrace/format.h> > +#include <babeltrace/ctf/types.h> > +#include <babeltrace/ctf-ir/metadata.h> > + > +/* > + * struct babeltrace_iter: data structure representing an iterator on a trace > + * collection. > + */ > +struct babeltrace_iter { > + struct ptr_heap *stream_heap; > + struct trace_collection *tc; > +}; > + > +struct babeltrace_iter_pos { > + GPtrArray *pos; /* struct babeltrace_iter_stream_pos */ > +}; > + > +struct babeltrace_iter_stream_pos { > + struct stream_pos parent; > + ssize_t offset; > + size_t cur_index; > +}; > + > +/* > + * Initialization/teardown. > + */ > +struct babeltrace_iter *babeltrace_iter_create(struct trace_collection *tc); > +void babeltrace_iter_destroy(struct babeltrace_iter *iter); > + > +/* > + * Move within the trace. > + */ > +/* > + * babeltrace_iter_next: Move stream position to the next event. > + * > + * Does *not* read the event. > + * Returns 0 on success, a negative value on error > + * 0: success, event is ready. > + */ > +int babeltrace_iter_next(struct babeltrace_iter *iter); > + > +/* Get the current position for each stream of the trace */ > +struct babeltrace_iter_pos * > +babeltrace_iter_get_pos(struct babeltrace_iter *iter); > + > +/* The position needs to be freed after use */ > +void babeltrace_iter_free_pos(struct babeltrace_iter_pos *pos); > + > +/* Seek the trace to the position */ > +int babeltrace_iter_seek_pos(struct babeltrace_iter *iter, > + struct babeltrace_iter_pos *pos); > + > +/* > + * babeltrace_iter_seek_time: Seek the trace to the given timestamp. > + * > + * Return EOF if timestamp is after the last event of the trace. > + * Return other negative value for other errors. > + * Return 0 for success. > + */ > +int babeltrace_iter_seek_time(struct babeltrace_iter *iter, > + uint64_t timestamp); > + > +/* > + * babeltrace_iter_read_event: Read the current event data. > + * > + * @iter: trace iterator (input) > + * @stream: stream containing event at current position (output) > + * @event: current event (output) > + * Return 0 on success, negative error value on error. > + */ > +int babeltrace_iter_read_event(struct babeltrace_iter *iter, > + struct ctf_stream **stream, > + struct ctf_stream_event **event); > + > +#endif /* _BABELTRACE_LIB_H */ > diff --git a/converter/babeltrace-lib.c b/converter/babeltrace-lib.c > index 3f9369b..b07d1e3 100644 > --- a/converter/babeltrace-lib.c > +++ b/converter/babeltrace-lib.c > @@ -29,7 +29,9 @@ > #include <babeltrace/ctf-text/types.h> > #include <babeltrace/prio_heap.h> > > -static int read_event(struct ctf_file_stream *sin) > +#include "babeltrace-api.h" > + > +static int stream_read_event(struct ctf_file_stream *sin) > { > int ret; > > @@ -56,24 +58,23 @@ int stream_compare(void *a, void *b) > return 0; > } > > -int convert_trace(struct trace_descriptor *td_write, > - struct trace_collection *trace_collection_read) > +struct babeltrace_iter *babeltrace_iter_create(struct trace_collection *tc) > { > - struct ptr_heap *stream_heap; > - struct ctf_text_stream_pos *sout; > int i, stream_id; > int ret = 0; > + struct babeltrace_iter *iter; > > - stream_heap = g_new(struct ptr_heap, 1); > - heap_init(stream_heap, 0, stream_compare); > - sout = container_of(td_write, struct ctf_text_stream_pos, > - trace_descriptor); > + iter = malloc(sizeof(struct babeltrace_iter)); > + iter->stream_heap = g_new(struct ptr_heap, 1); > + iter->tc = tc; > + > + heap_init(iter->stream_heap, 0, stream_compare); > > - for (i = 0; i < trace_collection_read->array->len; i++) { > + for (i = 0; i < tc->array->len; i++) { > struct ctf_trace *tin; > struct trace_descriptor *td_read; > > - td_read = g_ptr_array_index(trace_collection_read->array, i); > + td_read = g_ptr_array_index(tc->array, i); > tin = container_of(td_read, struct ctf_trace, parent); > > /* Populate heap with each stream */ > @@ -92,54 +93,112 @@ int convert_trace(struct trace_descriptor *td_write, > file_stream = g_ptr_array_index(stream->streams, > filenr); > > - ret = read_event(file_stream); > + ret = stream_read_event(file_stream); > if (ret == EOF) { > ret = 0; > continue; > } else if (ret) { > - goto end; > + goto error; > } > /* Add to heap */ > - ret = heap_insert(stream_heap, file_stream); > + ret = heap_insert(iter->stream_heap, > file_stream); > if (ret) { > fprintf(stdout, > - "[error] Out of memory.\n"); > - goto end; > + "[error] Out of > memory.\n"); > + goto error; > } > } > } > } > > - /* Replace heap entries until EOF for each stream (heap empty) */ > - for (;;) { > - struct ctf_file_stream *file_stream, *removed; > + return iter; > > - file_stream = heap_maximum(stream_heap); > - if (!file_stream) { > - /* end of file for all streams */ > - ret = 0; > - break; > - } > - ret = sout->parent.event_cb(&sout->parent, > &file_stream->parent); > +error: > + heap_free(iter->stream_heap); > + g_free(iter->stream_heap); > + free(iter); > + return NULL; > +} > + > +void babeltrace_iter_destroy(struct babeltrace_iter *iter) > +{ > + heap_free(iter->stream_heap); > + g_free(iter->stream_heap); > + free(iter); > +} > + > +int babeltrace_iter_next(struct babeltrace_iter *iter) > +{ > + struct ctf_file_stream *file_stream, *removed; > + int ret; > + > + file_stream = heap_maximum(iter->stream_heap); > + if (!file_stream) { > + /* end of file for all streams */ > + ret = 0; > + goto end; > + } > + > + ret = stream_read_event(file_stream); > + if (ret == EOF) { > + removed = heap_remove(iter->stream_heap); > + assert(removed == file_stream); > + ret = 0; > + goto end; > + } else if (ret) { > + goto end; > + } > + /* Reinsert the file stream into the heap, and rebalance. */ > + removed = heap_replace_max(iter->stream_heap, file_stream); > + assert(removed == file_stream); > + > +end: > + return ret; > +} > + > +int babeltrace_iter_read_event(struct babeltrace_iter *iter, > + struct ctf_stream **stream, > + struct ctf_stream_event **event) > +{ > + struct ctf_file_stream *file_stream; > + int ret = 0; > + > + file_stream = heap_maximum(iter->stream_heap); > + if (!file_stream) { > + /* end of file for all streams */ > + ret = EOF; > + goto end; > + } > + *stream = &file_stream->parent; > + *event = g_ptr_array_index((*stream)->events_by_id, > (*stream)->event_id); > +end: > + return ret; > +} > + > +int convert_trace(struct trace_descriptor *td_write, > + struct trace_collection *trace_collection_read) > +{ > + struct babeltrace_iter *iter; > + struct ctf_stream *stream; > + struct ctf_stream_event *event; > + struct ctf_text_stream_pos *sout; > + int ret = 0; > + > + sout = container_of(td_write, struct ctf_text_stream_pos, > + trace_descriptor); > + > + iter = babeltrace_iter_create(trace_collection_read); > + while (babeltrace_iter_read_event(iter, &stream, &event) == 0) { > + ret = sout->parent.event_cb(&sout->parent, stream); > if (ret) { > fprintf(stdout, "[error] Writing event failed.\n"); > goto end; > } > - ret = read_event(file_stream); > - if (ret == EOF) { > - removed = heap_remove(stream_heap); > - assert(removed == file_stream); > - ret = 0; > - continue; > - } else if (ret) > + ret = babeltrace_iter_next(iter); > + if (ret < 0) > goto end; > - /* Reinsert the file stream into the heap, and rebalance. */ > - removed = heap_replace_max(stream_heap, file_stream); > - assert(removed == file_stream); > } > - > end: > - heap_free(stream_heap); > - g_free(stream_heap); > + babeltrace_iter_destroy(iter); > return ret; > } > -- > 1.7.4.1 > > > _______________________________________________ > ltt-dev mailing list > [email protected] > http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com _______________________________________________ ltt-dev mailing list [email protected] http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
