From: Jérémie Galarneau Date: Sun, 11 Dec 2016 08:54:26 +0000 (-0500) Subject: Implement the trimmer plug-in X-Git-Tag: v2.0.0-pre1~629 X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;ds=sidebyside;h=44d3cbf0a1e9a9911cb1aa511ee2f49c270e2327;p=babeltrace.git Implement the trimmer plug-in Signed-off-by: Jérémie Galarneau --- diff --git a/plugins/trimmer/iterator.c b/plugins/trimmer/iterator.c index 492f3f1a..44a58e43 100644 --- a/plugins/trimmer/iterator.c +++ b/plugins/trimmer/iterator.c @@ -29,13 +29,62 @@ #include "trimmer.h" #include "iterator.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static +void trimmer_iterator_destroy(struct bt_notification_iterator *it) +{ + struct trimmer_iterator *it_data; + + it_data = bt_notification_iterator_get_private_data(it); + assert(it_data); + + if (it_data->input_iterator_group) { + g_ptr_array_free(it_data->input_iterator_group, TRUE); + } + bt_put(it_data->current_notification); + if (it_data->stream_to_packet_start_notification) { + g_hash_table_destroy(it_data->stream_to_packet_start_notification); + } + g_free(it_data); +} BT_HIDDEN enum bt_component_status trimmer_iterator_init(struct bt_component *component, struct bt_notification_iterator *iterator) { - enum bt_component_status ret; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; enum bt_notification_iterator_status it_ret; + struct trimmer_iterator *it_data = g_new0(struct trimmer_iterator, 1); + + if (!it_data) { + ret = BT_COMPONENT_STATUS_NOMEM; + goto end; + } + + /* FIXME init trimmer_iterator */ + it_ret = bt_notification_iterator_set_private_data(iterator, it_data); + if (it_ret) { + goto end; + } + + it_ret = bt_notification_iterator_set_destroy_cb(iterator, + trimmer_iterator_destroy); + if (it_ret) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } it_ret = bt_notification_iterator_set_next_cb(iterator, trimmer_iterator_next); @@ -65,17 +114,195 @@ BT_HIDDEN struct bt_notification *trimmer_iterator_get( struct bt_notification_iterator *iterator) { - return NULL; + struct trimmer_iterator *trim_it; + + trim_it = bt_notification_iterator_get_private_data(iterator); + assert(trim_it); + + if (!trim_it->current_notification) { + enum bt_notification_iterator_status it_ret; + + it_ret = trimmer_iterator_next(iterator); + if (it_ret) { + goto end; + } + } +end: + return bt_get(trim_it->current_notification); +} + +/* + * Remove me. This is a temporary work-around due to our inhability to use + * libbabeltrace-ctf from libbabeltrace-plugin. + */ +static +struct bt_ctf_stream *internal_bt_notification_get_stream( + struct bt_notification *notification) +{ + struct bt_ctf_stream *stream = NULL; + + assert(notification); + switch (bt_notification_get_type(notification)) { + case BT_NOTIFICATION_TYPE_EVENT: + { + struct bt_ctf_event *event; + + event = bt_notification_event_get_event(notification); + stream = bt_ctf_event_get_stream(event); + bt_put(event); + break; + } + case BT_NOTIFICATION_TYPE_PACKET_START: + { + struct bt_ctf_packet *packet; + + packet = bt_notification_packet_start_get_packet(notification); + stream = bt_ctf_packet_get_stream(packet); + bt_put(packet); + break; + } + case BT_NOTIFICATION_TYPE_PACKET_END: + { + struct bt_ctf_packet *packet; + + packet = bt_notification_packet_end_get_packet(notification); + stream = bt_ctf_packet_get_stream(packet); + bt_put(packet); + break; + } + case BT_NOTIFICATION_TYPE_STREAM_END: + stream = bt_notification_stream_end_get_stream(notification); + break; + default: + goto end; + } +end: + return stream; +} + +/* Return true if the notification should be forwarded. */ +static +bool evaluate_notification(struct bt_notification *notification, + struct trimmer *trimmer, struct trimmer_iterator *it) +{ + bool ret = true; + struct bt_ctf_clock *clock = NULL; + enum bt_notification_type type; + struct bt_ctf_trace *trace = NULL; + struct bt_ctf_stream *stream = NULL; + struct bt_ctf_stream_class *stream_class = NULL; + struct bt_ctf_clock_value *clock_value = NULL; + + stream = internal_bt_notification_get_stream(notification); + if (!stream) { + goto end; + } + + stream_class = bt_ctf_stream_get_class(stream); + assert(stream_class); + trace = bt_ctf_stream_class_get_trace(stream_class); + assert(trace); + + type = bt_notification_get_type(notification); + switch (type) { + case BT_NOTIFICATION_TYPE_EVENT: + { + int64_t ts; + int clock_ret; + struct bt_ctf_event *event; + + clock = bt_ctf_trace_get_clock(trace, 0); + if (!clock) { + goto end; + } + + event = bt_notification_event_get_event(notification); + assert(event); + clock_value = bt_ctf_event_get_clock_value(event, clock); + if (!clock_value) { + printf_error("Failed to retrieve clock value\n"); + bt_put(event); + goto end; + } + + clock_ret = bt_ctf_clock_value_get_value_ns_from_epoch( + clock_value, &ts); + if (clock_ret) { + printf_error("Failed to retrieve clock value timestamp\n"); + goto end; + } + + if (trimmer->begin.set && ts < trimmer->begin.value) { + ret = false; + } + if (trimmer->end.set && ts > trimmer->end.value) { + ret = false; + } + break; + } + default: + break; + } +end: + bt_put(clock); + bt_put(trace); + bt_put(stream); + bt_put(clock_value); + return ret; } BT_HIDDEN enum bt_notification_iterator_status trimmer_iterator_next( struct bt_notification_iterator *iterator) { - enum bt_notification_iterator_status ret; + struct trimmer_iterator *trim_it = NULL; + struct bt_component *component = NULL; + struct trimmer *trimmer = NULL; + struct bt_notification_iterator *source_it = NULL; + enum bt_notification_iterator_status ret = + BT_NOTIFICATION_ITERATOR_STATUS_OK;; + enum bt_component_status component_ret; + bool event_in_range = false; - ret = BT_NOTIFICATION_ITERATOR_STATUS_OK; + trim_it = bt_notification_iterator_get_private_data(iterator); + assert(trim_it); + + component = bt_notification_iterator_get_component(iterator); + assert(component); + trimmer = bt_component_get_private_data(component); + assert(trimmer); + + /* FIXME, should handle input iterator groups. */ + component_ret = bt_component_filter_get_input_iterator(component, 0, + &source_it); + assert((component_ret == BT_COMPONENT_STATUS_OK) && source_it); + + while (!event_in_range) { + struct bt_notification *notification; + + ret = bt_notification_iterator_next(source_it); + if (ret != BT_NOTIFICATION_ITERATOR_STATUS_OK) { + goto end; + } + + notification = bt_notification_iterator_get_notification( + source_it); + if (!notification) { + ret = BT_NOTIFICATION_ITERATOR_STATUS_ERROR; + goto end; + } + + event_in_range = evaluate_notification(notification, trimmer, + trim_it); + if (event_in_range) { + BT_MOVE(trim_it->current_notification, notification); + } else { + bt_put(notification); + } + } end: + bt_put(source_it); + bt_put(component); return ret; } diff --git a/plugins/trimmer/iterator.h b/plugins/trimmer/iterator.h index c32b498d..a517b1f0 100644 --- a/plugins/trimmer/iterator.h +++ b/plugins/trimmer/iterator.h @@ -28,6 +28,14 @@ */ #include "trimmer.h" +#include + +struct trimmer_iterator { + /* Input iterators associated with this output iterator. */ + GPtrArray *input_iterator_group; + struct bt_notification *current_notification; + GHashTable *stream_to_packet_start_notification; +}; BT_HIDDEN enum bt_component_status trimmer_iterator_init( diff --git a/plugins/trimmer/trimmer.c b/plugins/trimmer/trimmer.c index 7e6f024c..23fe7134 100644 --- a/plugins/trimmer/trimmer.c +++ b/plugins/trimmer/trimmer.c @@ -34,6 +34,7 @@ #include #include "trimmer.h" #include "iterator.h" +#include static void destroy_trimmer_data(struct trimmer *trimmer) @@ -62,6 +63,39 @@ void destroy_trimmer(struct bt_component *component) destroy_trimmer_data(data); } +static +void init_from_params(struct trimmer *trimmer, struct bt_value *params) +{ + struct bt_value *value = NULL; + + assert(params); + + value = bt_value_map_get(params, "begin_ns_epoch"); + if (value && bt_value_is_integer(value)) { + enum bt_value_status value_ret; + + value_ret = bt_value_integer_get(value, &trimmer->begin.value); + if (!value_ret) { + trimmer->begin.set = true; + } else { + printf_error("Failed to retrieve begin_ns_epoch value\n"); + } + } + bt_put(value); + value = bt_value_map_get(params, "end_ns_epoch"); + if (value && bt_value_is_integer(value)) { + enum bt_value_status value_ret; + + value_ret = bt_value_integer_get(value, &trimmer->end.value); + if (!value_ret) { + trimmer->end.set = true; + } else { + printf_error("Failed to retrieve end_ns_epoch value\n"); + } + } + bt_put(value); +} + enum bt_component_status trimmer_component_init( struct bt_component *component, struct bt_value *params) { @@ -89,6 +123,8 @@ enum bt_component_status trimmer_component_init( if (ret != BT_COMPONENT_STATUS_OK) { goto error; } + + init_from_params(trimmer, params); end: return ret; error: @@ -97,7 +133,7 @@ error: } /* Initialize plug-in entry points. */ -BT_PLUGIN_NAME("trimmer"); +BT_PLUGIN_NAME("utils"); BT_PLUGIN_DESCRIPTION("Babeltrace Trace Trimmer Plug-In."); BT_PLUGIN_AUTHOR("Jérémie Galarneau"); BT_PLUGIN_LICENSE("MIT"); diff --git a/plugins/trimmer/trimmer.h b/plugins/trimmer/trimmer.h index 9f4a34af..28bb1e2f 100644 --- a/plugins/trimmer/trimmer.h +++ b/plugins/trimmer/trimmer.h @@ -32,8 +32,13 @@ #include #include +struct trimmer_bound { + int64_t value; + bool set; +}; + struct trimmer { - int64_t range_start, range_end; + struct trimmer_bound begin, end; }; #endif /* BABELTRACE_PLUGIN_TRIMMER_H */