Commit | Line | Data |
---|---|---|
7a4bdb54 YB |
1 | /* This file is part of the Linux Trace Toolkit viewer |
2 | * Copyright (C) 2003-2004 Michel Dagenais | |
3 | * Copyright (C) 2012 Yannick Brosseau | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License Version 2 as | |
7 | * published by the Free Software Foundation; | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, write to the Free Software | |
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
17 | * MA 02111-1307, USA. | |
18 | */ | |
19 | #ifdef HAVE_CONFIG_H | |
20 | #include <config.h> | |
21 | #endif | |
22 | ||
23 | #include <lttv/traceset-process.h> | |
24 | #include <lttv/traceset.h> | |
25 | #include <lttv/event.h> | |
26 | #include <babeltrace/context.h> | |
27 | #include <babeltrace/iterator.h> | |
9a366873 | 28 | #include <babeltrace/trace-handle.h> |
7a4bdb54 YB |
29 | #include <babeltrace/ctf/events.h> |
30 | #include <babeltrace/ctf/iterator.h> | |
31 | ||
32 | void lttv_process_traceset_begin(LttvTraceset *traceset, | |
33 | LttvHooks *before_traceset, | |
34 | LttvHooks *before_trace, | |
35 | LttvHooks *event) | |
36 | { | |
f1e5df2a | 37 | struct bt_iter_pos begin_pos; |
7a4bdb54 YB |
38 | /* simply add hooks in context. _before hooks are called by add_hooks. */ |
39 | /* It calls all before_traceset, before_trace, and before_tracefile hooks. */ | |
40 | lttv_traceset_add_hooks(traceset, | |
41 | before_traceset, | |
42 | before_trace, | |
43 | event); | |
44 | ||
45 | ||
f1e5df2a YB |
46 | |
47 | begin_pos.type = BT_SEEK_BEGIN; | |
48 | ||
49 | if(!traceset->iter) { | |
50 | traceset->iter = bt_ctf_iter_create(lttv_traceset_get_context(traceset), | |
51 | &begin_pos, | |
52 | NULL); | |
53 | } | |
7a4bdb54 YB |
54 | } |
55 | ||
56 | guint lttv_process_traceset_middle(LttvTraceset *traceset, | |
9a366873 FD |
57 | LttTime end, |
58 | gulong nb_events, | |
59 | const LttvTracesetPosition *end_position) | |
7a4bdb54 | 60 | { |
7a4bdb54 | 61 | unsigned count = 0; |
9a366873 | 62 | gint last_ret = 0; |
9a366873 | 63 | |
7a4bdb54 YB |
64 | struct bt_ctf_event *bt_event; |
65 | ||
66 | LttvEvent event; | |
13d35254 YB |
67 | LttTime endPositionTime; |
68 | ||
d04fa838 | 69 | //TODO ybrosseau 2013-10-17: Compare with end_position directly when its possible |
13d35254 YB |
70 | if(end_position) { |
71 | endPositionTime = lttv_traceset_position_get_time(end_position); | |
72 | } | |
7a4bdb54 YB |
73 | while(TRUE) { |
74 | ||
9a366873 | 75 | if(last_ret == TRUE || ((count >= nb_events) && (nb_events != G_MAXULONG))) { |
7a4bdb54 YB |
76 | break; |
77 | } | |
78 | ||
79 | if((bt_event = bt_ctf_iter_read_event(traceset->iter)) != NULL) { | |
9a366873 | 80 | |
762e15b0 | 81 | LttTime time = ltt_time_from_uint64(bt_ctf_get_timestamp(bt_event)); |
9a366873 FD |
82 | if(ltt_time_compare(end, time) <= 0) { |
83 | break; | |
84 | } | |
d04fa838 | 85 | //TODO ybrosseau 2013-10-17: Compare with end_position directly when its possible |
13d35254 YB |
86 | if(end_position && (ltt_time_compare(endPositionTime, time) <= 0)) { |
87 | break; | |
88 | } | |
7a4bdb54 YB |
89 | count++; |
90 | ||
91 | event.bt_event = bt_event; | |
115c78c2 | 92 | |
0fa52e61 | 93 | /* Retrieve the associated state */ |
115c78c2 YB |
94 | event.state = g_ptr_array_index(traceset->state_trace_handle_index, |
95 | bt_ctf_event_get_handle_id(bt_event)); | |
7a4bdb54 | 96 | |
9a366873 | 97 | last_ret = lttv_hooks_call(traceset->event_hooks, &event); |
7a4bdb54 YB |
98 | |
99 | if(bt_iter_next(bt_ctf_get_iter(traceset->iter)) < 0) { | |
100 | printf("ERROR NEXT\n"); | |
101 | break; | |
102 | } | |
103 | } else { | |
104 | /* READ FAILED */ | |
105 | ||
106 | break; | |
107 | ||
108 | } | |
109 | } | |
7a4bdb54 YB |
110 | return count; |
111 | } | |
112 | ||
113 | void lttv_process_traceset_end(LttvTraceset *traceset, | |
114 | LttvHooks *after_traceset, | |
115 | LttvHooks *after_trace, | |
116 | LttvHooks *event) | |
117 | { | |
118 | /* Remove hooks from context. _after hooks are called by remove_hooks. */ | |
119 | /* It calls all after_traceset, after_trace, and after_tracefile hooks. */ | |
120 | lttv_traceset_remove_hooks(traceset, | |
121 | after_traceset, | |
122 | after_trace, | |
123 | event); | |
124 | ||
125 | } | |
126 | ||
127 | ||
128 | void lttv_traceset_add_hooks(LttvTraceset *traceset, | |
129 | LttvHooks *before_traceset, | |
130 | LttvHooks *before_trace, | |
131 | LttvHooks *event) | |
132 | { | |
7a4bdb54 YB |
133 | guint i, nb_trace; |
134 | ||
135 | LttvTrace *trace; | |
136 | ||
137 | lttv_hooks_call(before_traceset, traceset); | |
138 | ||
139 | lttv_hooks_add_list(traceset->event_hooks, event); | |
140 | ||
141 | nb_trace = lttv_traceset_number(traceset); | |
142 | ||
143 | for(i = 0 ; i < nb_trace ; i++) { | |
144 | trace = (LttvTrace *)g_ptr_array_index(traceset->traces,i); | |
145 | lttv_trace_add_hooks(trace, | |
146 | before_trace, | |
147 | event | |
148 | ); | |
149 | } | |
150 | } | |
151 | void lttv_traceset_remove_hooks(LttvTraceset *traceset, | |
152 | LttvHooks *after_traceset, | |
153 | LttvHooks *after_trace, | |
154 | LttvHooks *event) | |
155 | { | |
7a4bdb54 YB |
156 | guint i, nb_trace; |
157 | ||
158 | LttvTrace *trace; | |
159 | ||
160 | nb_trace = lttv_traceset_number(traceset); | |
161 | ||
162 | for(i = 0 ; i < nb_trace ; i++) { | |
163 | trace = (LttvTrace *)g_ptr_array_index(traceset->traces,i); | |
164 | lttv_trace_remove_hooks(trace, | |
165 | after_trace, | |
166 | event); | |
167 | ||
168 | } | |
169 | ||
9a366873 | 170 | lttv_hooks_remove_list(traceset->event_hooks, event); |
7a4bdb54 YB |
171 | lttv_hooks_call(after_traceset, traceset); |
172 | ||
173 | ||
174 | } | |
175 | ||
176 | ||
177 | void lttv_trace_add_hooks(LttvTrace *trace, | |
178 | LttvHooks *before_trace, | |
179 | LttvHooks *event) | |
180 | { | |
181 | lttv_hooks_call(before_trace, trace); | |
182 | } | |
183 | ||
184 | void lttv_trace_remove_hooks(LttvTrace *trace, | |
185 | LttvHooks *after_trace, | |
186 | LttvHooks *event) | |
187 | ||
188 | { | |
189 | lttv_hooks_call(after_trace, trace); | |
7a4bdb54 YB |
190 | } |
191 | ||
192 | void lttv_process_traceset_seek_time(LttvTraceset *traceset, LttTime start) | |
193 | { | |
7a4bdb54 YB |
194 | struct bt_iter_pos seekpos; |
195 | int ret; | |
f1e5df2a YB |
196 | if (traceset->iter == NULL) { |
197 | g_warning("Iterator not valid in seek_time"); | |
198 | return; | |
199 | } | |
7a4bdb54 YB |
200 | seekpos.type = BT_SEEK_TIME; |
201 | seekpos.u.seek_time = ltt_time_to_uint64(start); | |
f1e5df2a YB |
202 | |
203 | ret = bt_iter_set_pos(bt_ctf_get_iter(traceset->iter), &seekpos); | |
7a4bdb54 YB |
204 | if(ret < 0) { |
205 | printf("Seek by time error: %s,\n",strerror(-ret)); | |
206 | } | |
9a366873 FD |
207 | } |
208 | ||
209 | guint lttv_process_traceset_seek_n_forward(LttvTraceset *traceset, | |
210 | guint n, | |
211 | check_handler *check, | |
212 | gboolean *stop_flag, | |
213 | LttvFilter *filter1, | |
214 | LttvFilter *filter2, | |
215 | LttvFilter *filter3, | |
216 | gpointer data) | |
217 | { | |
9a366873 FD |
218 | unsigned count = 0; |
219 | while(count < n) { | |
220 | if(bt_iter_next(bt_ctf_get_iter(traceset->iter)) < 0) { | |
221 | printf("ERROR NEXT\n"); | |
222 | break; | |
223 | } | |
224 | count++; | |
225 | } | |
226 | return count; | |
227 | } | |
228 | ||
229 | guint lttv_process_traceset_seek_n_backward(LttvTraceset *ts, | |
230 | guint n, | |
231 | gdouble ratio, | |
232 | check_handler *check, | |
233 | gboolean *stop_flag, | |
234 | LttvFilter *filter1, | |
235 | LttvFilter *filter2, | |
236 | LttvFilter *filter3, | |
237 | gpointer data) | |
238 | { | |
239 | guint i, count, ret; | |
240 | gint extraEvent = 0; | |
241 | guint64 initialTimeStamp, previousTimeStamp; | |
88bf15f0 FD |
242 | LttvTracesetPosition *initialPos, *previousPos, *currentPos, beginPos; |
243 | struct bt_iter_pos pos; | |
244 | beginPos.bt_pos = &pos; | |
245 | beginPos.iter = ts->iter; | |
246 | beginPos.bt_pos->type = BT_SEEK_BEGIN; | |
c73ce169 FD |
247 | beginPos.timestamp = G_MAXUINT64; |
248 | beginPos.cpu_id = INT_MAX; | |
9a366873 | 249 | /*Save initial position of the traceset*/ |
68573dd0 | 250 | initialPos = lttv_traceset_create_current_position (ts); |
9a366873 FD |
251 | |
252 | /*Get the timespan of the initial position*/ | |
253 | initialTimeStamp = lttv_traceset_position_get_timestamp(initialPos); | |
254 | /* | |
255 | * Create a position before the initial timestamp according | |
68573dd0 | 256 | * to the ratio of nanosecond/event hopefully before the |
9a366873 FD |
257 | * the desired seek position |
258 | */ | |
259 | while(1){ | |
260 | previousTimeStamp = initialTimeStamp - n*(guint)ceil(ratio); | |
261 | ||
262 | previousPos = lttv_traceset_create_time_position(ts,ltt_time_from_uint64(previousTimeStamp)); | |
263 | if(initialTimeStamp == previousTimeStamp) | |
264 | break; | |
265 | ||
266 | currentPos = lttv_traceset_create_time_position(ts,ltt_time_from_uint64(previousTimeStamp)); | |
88bf15f0 FD |
267 | /*Corner case: When we are near the beginning of the trace and the previousTimeStamp is before |
268 | * the beginning of the trace. We have to seek to the first event. | |
269 | */ | |
270 | if((lttv_traceset_position_compare(currentPos,&beginPos ) == 0)){ | |
271 | lttv_traceset_seek_to_position(&beginPos); | |
272 | break; | |
273 | } | |
9a366873 | 274 | /*move traceset position */ |
58b4e4ae | 275 | lttv_state_traceset_seek_position(ts, previousPos); |
9a366873 FD |
276 | /* iterate to the initial position counting the number of event*/ |
277 | count = 0; | |
278 | do { | |
279 | if((ret = lttv_traceset_position_compare(currentPos,initialPos)) == 1){ | |
993046ef | 280 | if(bt_iter_next(bt_ctf_get_iter(ts->iter)) == 0) { |
13d35254 YB |
281 | if(bt_ctf_iter_read_event(ts->iter) > 0) { |
282 | lttv_traceset_destroy_position(currentPos); | |
283 | currentPos = lttv_traceset_create_current_position(ts); | |
284 | count++; | |
993046ef YB |
285 | } else { |
286 | break; | |
287 | } | |
288 | ||
289 | } else { | |
290 | ||
291 | //No more event available | |
292 | break; | |
293 | } | |
9a366873 FD |
294 | } |
295 | }while(ret != 0); | |
88bf15f0 | 296 | |
9a366873 FD |
297 | /*substract the desired number of event to the count*/ |
298 | extraEvent = count - n; | |
88bf15f0 | 299 | if (extraEvent >= 0) { |
9a366873 FD |
300 | //if the extraEvent is over 0 go back to previousPos and |
301 | //move forward the value of extraEvent times | |
58b4e4ae | 302 | lttv_state_traceset_seek_position(ts, previousPos); |
9a366873 FD |
303 | |
304 | for(i = 0 ; i < extraEvent ; i++){ | |
305 | if(bt_iter_next(bt_ctf_get_iter(ts->iter)) < 0){ | |
306 | printf("ERROR NEXT\n"); | |
307 | break; | |
308 | } | |
309 | ||
310 | } | |
311 | break; /* we successfully seeked backward */ | |
312 | } | |
88bf15f0 FD |
313 | else{ |
314 | /* if the extraEvent is below 0 create a position before and start over*/ | |
315 | ratio = ratio * 16; | |
9a366873 | 316 | } |
88bf15f0 | 317 | lttv_traceset_destroy_position(currentPos); |
9a366873 FD |
318 | } |
319 | return 0; | |
7a4bdb54 | 320 | } |