4 * Babeltrace Trace Trimmer Iterator
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 #include <babeltrace/plugin/notification/iterator.h>
32 #include <babeltrace/plugin/notification/notification.h>
33 #include <babeltrace/plugin/notification/event.h>
34 #include <babeltrace/plugin/notification/stream.h>
35 #include <babeltrace/plugin/notification/packet.h>
36 #include <babeltrace/plugin/filter.h>
37 #include <babeltrace/ctf-ir/event.h>
38 #include <babeltrace/ctf-ir/stream.h>
39 #include <babeltrace/ctf-ir/stream-class.h>
40 #include <babeltrace/ctf-ir/clock.h>
41 #include <babeltrace/ctf-ir/packet.h>
42 #include <babeltrace/ctf-ir/trace.h>
46 void trimmer_iterator_destroy(struct bt_notification_iterator
*it
)
48 struct trimmer_iterator
*it_data
;
50 it_data
= bt_notification_iterator_get_private_data(it
);
53 if (it_data
->input_iterator_group
) {
54 g_ptr_array_free(it_data
->input_iterator_group
, TRUE
);
56 bt_put(it_data
->current_notification
);
57 if (it_data
->stream_to_packet_start_notification
) {
58 g_hash_table_destroy(it_data
->stream_to_packet_start_notification
);
64 enum bt_component_status
trimmer_iterator_init(struct bt_component
*component
,
65 struct bt_notification_iterator
*iterator
)
67 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
68 enum bt_notification_iterator_status it_ret
;
69 struct trimmer_iterator
*it_data
= g_new0(struct trimmer_iterator
, 1);
72 ret
= BT_COMPONENT_STATUS_NOMEM
;
76 /* FIXME init trimmer_iterator */
77 it_ret
= bt_notification_iterator_set_private_data(iterator
, it_data
);
82 it_ret
= bt_notification_iterator_set_destroy_cb(iterator
,
83 trimmer_iterator_destroy
);
85 ret
= BT_COMPONENT_STATUS_ERROR
;
89 it_ret
= bt_notification_iterator_set_next_cb(iterator
,
90 trimmer_iterator_next
);
92 ret
= BT_COMPONENT_STATUS_ERROR
;
96 it_ret
= bt_notification_iterator_set_get_cb(iterator
,
97 trimmer_iterator_get
);
99 ret
= BT_COMPONENT_STATUS_ERROR
;
103 it_ret
= bt_notification_iterator_set_seek_time_cb(iterator
,
104 trimmer_iterator_seek_time
);
106 ret
= BT_COMPONENT_STATUS_ERROR
;
114 struct bt_notification
*trimmer_iterator_get(
115 struct bt_notification_iterator
*iterator
)
117 struct trimmer_iterator
*trim_it
;
119 trim_it
= bt_notification_iterator_get_private_data(iterator
);
122 if (!trim_it
->current_notification
) {
123 enum bt_notification_iterator_status it_ret
;
125 it_ret
= trimmer_iterator_next(iterator
);
131 return bt_get(trim_it
->current_notification
);
135 * Remove me. This is a temporary work-around due to our inhability to use
136 * libbabeltrace-ctf from libbabeltrace-plugin.
139 struct bt_ctf_stream
*internal_bt_notification_get_stream(
140 struct bt_notification
*notification
)
142 struct bt_ctf_stream
*stream
= NULL
;
144 assert(notification
);
145 switch (bt_notification_get_type(notification
)) {
146 case BT_NOTIFICATION_TYPE_EVENT
:
148 struct bt_ctf_event
*event
;
150 event
= bt_notification_event_get_event(notification
);
151 stream
= bt_ctf_event_get_stream(event
);
155 case BT_NOTIFICATION_TYPE_PACKET_START
:
157 struct bt_ctf_packet
*packet
;
159 packet
= bt_notification_packet_start_get_packet(notification
);
160 stream
= bt_ctf_packet_get_stream(packet
);
164 case BT_NOTIFICATION_TYPE_PACKET_END
:
166 struct bt_ctf_packet
*packet
;
168 packet
= bt_notification_packet_end_get_packet(notification
);
169 stream
= bt_ctf_packet_get_stream(packet
);
173 case BT_NOTIFICATION_TYPE_STREAM_END
:
174 stream
= bt_notification_stream_end_get_stream(notification
);
183 /* Return true if the notification should be forwarded. */
185 bool evaluate_notification(struct bt_notification
*notification
,
186 struct trimmer
*trimmer
, struct trimmer_iterator
*it
)
189 struct bt_ctf_clock
*clock
= NULL
;
190 enum bt_notification_type type
;
191 struct bt_ctf_trace
*trace
= NULL
;
192 struct bt_ctf_stream
*stream
= NULL
;
193 struct bt_ctf_stream_class
*stream_class
= NULL
;
194 struct bt_ctf_clock_value
*clock_value
= NULL
;
196 stream
= internal_bt_notification_get_stream(notification
);
201 stream_class
= bt_ctf_stream_get_class(stream
);
202 assert(stream_class
);
203 trace
= bt_ctf_stream_class_get_trace(stream_class
);
206 type
= bt_notification_get_type(notification
);
208 case BT_NOTIFICATION_TYPE_EVENT
:
212 struct bt_ctf_event
*event
;
214 clock
= bt_ctf_trace_get_clock(trace
, 0);
219 event
= bt_notification_event_get_event(notification
);
221 clock_value
= bt_ctf_event_get_clock_value(event
, clock
);
223 printf_error("Failed to retrieve clock value\n");
228 clock_ret
= bt_ctf_clock_value_get_value_ns_from_epoch(
231 printf_error("Failed to retrieve clock value timestamp\n");
235 if (trimmer
->begin
.set
&& ts
< trimmer
->begin
.value
) {
238 if (trimmer
->end
.set
&& ts
> trimmer
->end
.value
) {
255 enum bt_notification_iterator_status
trimmer_iterator_next(
256 struct bt_notification_iterator
*iterator
)
258 struct trimmer_iterator
*trim_it
= NULL
;
259 struct bt_component
*component
= NULL
;
260 struct trimmer
*trimmer
= NULL
;
261 struct bt_notification_iterator
*source_it
= NULL
;
262 enum bt_notification_iterator_status ret
=
263 BT_NOTIFICATION_ITERATOR_STATUS_OK
;;
264 enum bt_component_status component_ret
;
265 bool event_in_range
= false;
267 trim_it
= bt_notification_iterator_get_private_data(iterator
);
270 component
= bt_notification_iterator_get_component(iterator
);
272 trimmer
= bt_component_get_private_data(component
);
275 /* FIXME, should handle input iterator groups. */
276 component_ret
= bt_component_filter_get_input_iterator(component
, 0,
278 assert((component_ret
== BT_COMPONENT_STATUS_OK
) && source_it
);
280 while (!event_in_range
) {
281 struct bt_notification
*notification
;
283 ret
= bt_notification_iterator_next(source_it
);
284 if (ret
!= BT_NOTIFICATION_ITERATOR_STATUS_OK
) {
288 notification
= bt_notification_iterator_get_notification(
291 ret
= BT_NOTIFICATION_ITERATOR_STATUS_ERROR
;
295 event_in_range
= evaluate_notification(notification
, trimmer
,
297 if (event_in_range
) {
298 BT_MOVE(trim_it
->current_notification
, notification
);
300 bt_put(notification
);
310 enum bt_notification_iterator_status
trimmer_iterator_seek_time(
311 struct bt_notification_iterator
*iterator
, int64_t time
)
313 enum bt_notification_iterator_status ret
;
315 ret
= BT_NOTIFICATION_ITERATOR_STATUS_OK
;