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 FD |
62 | gint last_ret = 0; |
63 | LttvTracesetPosition *currentPos; | |
64 | ||
7a4bdb54 YB |
65 | struct bt_ctf_event *bt_event; |
66 | ||
67 | LttvEvent event; | |
13d35254 YB |
68 | LttTime endPositionTime; |
69 | ||
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 | } | |
13d35254 | 85 | /* |
68573dd0 | 86 | currentPos = lttv_traceset_create_current_position(traceset); |
9a366873 FD |
87 | if(lttv_traceset_position_compare(currentPos,end_position ) == 0){ |
88 | lttv_traceset_destroy_position(currentPos); | |
2dd99ee2 YB |
89 | break; |
90 | } | |
9a366873 | 91 | lttv_traceset_destroy_position(currentPos); |
13d35254 YB |
92 | */ |
93 | if(end_position && (ltt_time_compare(endPositionTime, time) <= 0)) { | |
94 | break; | |
95 | } | |
7a4bdb54 YB |
96 | count++; |
97 | ||
98 | event.bt_event = bt_event; | |
115c78c2 | 99 | |
0fa52e61 | 100 | /* Retrieve the associated state */ |
115c78c2 YB |
101 | event.state = g_ptr_array_index(traceset->state_trace_handle_index, |
102 | bt_ctf_event_get_handle_id(bt_event)); | |
7a4bdb54 | 103 | |
9a366873 | 104 | last_ret = lttv_hooks_call(traceset->event_hooks, &event); |
7a4bdb54 YB |
105 | |
106 | if(bt_iter_next(bt_ctf_get_iter(traceset->iter)) < 0) { | |
107 | printf("ERROR NEXT\n"); | |
108 | break; | |
109 | } | |
110 | } else { | |
111 | /* READ FAILED */ | |
112 | ||
113 | break; | |
114 | ||
115 | } | |
116 | } | |
7a4bdb54 YB |
117 | return count; |
118 | } | |
119 | ||
120 | void lttv_process_traceset_end(LttvTraceset *traceset, | |
121 | LttvHooks *after_traceset, | |
122 | LttvHooks *after_trace, | |
123 | LttvHooks *event) | |
124 | { | |
125 | /* Remove hooks from context. _after hooks are called by remove_hooks. */ | |
126 | /* It calls all after_traceset, after_trace, and after_tracefile hooks. */ | |
127 | lttv_traceset_remove_hooks(traceset, | |
128 | after_traceset, | |
129 | after_trace, | |
130 | event); | |
131 | ||
132 | } | |
133 | ||
134 | ||
135 | void lttv_traceset_add_hooks(LttvTraceset *traceset, | |
136 | LttvHooks *before_traceset, | |
137 | LttvHooks *before_trace, | |
138 | LttvHooks *event) | |
139 | { | |
7a4bdb54 YB |
140 | guint i, nb_trace; |
141 | ||
142 | LttvTrace *trace; | |
143 | ||
144 | lttv_hooks_call(before_traceset, traceset); | |
145 | ||
146 | lttv_hooks_add_list(traceset->event_hooks, event); | |
147 | ||
148 | nb_trace = lttv_traceset_number(traceset); | |
149 | ||
150 | for(i = 0 ; i < nb_trace ; i++) { | |
151 | trace = (LttvTrace *)g_ptr_array_index(traceset->traces,i); | |
152 | lttv_trace_add_hooks(trace, | |
153 | before_trace, | |
154 | event | |
155 | ); | |
156 | } | |
157 | } | |
158 | void lttv_traceset_remove_hooks(LttvTraceset *traceset, | |
159 | LttvHooks *after_traceset, | |
160 | LttvHooks *after_trace, | |
161 | LttvHooks *event) | |
162 | { | |
7a4bdb54 YB |
163 | guint i, nb_trace; |
164 | ||
165 | LttvTrace *trace; | |
166 | ||
167 | nb_trace = lttv_traceset_number(traceset); | |
168 | ||
169 | for(i = 0 ; i < nb_trace ; i++) { | |
170 | trace = (LttvTrace *)g_ptr_array_index(traceset->traces,i); | |
171 | lttv_trace_remove_hooks(trace, | |
172 | after_trace, | |
173 | event); | |
174 | ||
175 | } | |
176 | ||
9a366873 | 177 | lttv_hooks_remove_list(traceset->event_hooks, event); |
7a4bdb54 YB |
178 | lttv_hooks_call(after_traceset, traceset); |
179 | ||
180 | ||
181 | } | |
182 | ||
183 | ||
184 | void lttv_trace_add_hooks(LttvTrace *trace, | |
185 | LttvHooks *before_trace, | |
186 | LttvHooks *event) | |
187 | { | |
188 | lttv_hooks_call(before_trace, trace); | |
189 | } | |
190 | ||
191 | void lttv_trace_remove_hooks(LttvTrace *trace, | |
192 | LttvHooks *after_trace, | |
193 | LttvHooks *event) | |
194 | ||
195 | { | |
196 | lttv_hooks_call(after_trace, trace); | |
7a4bdb54 YB |
197 | } |
198 | ||
199 | void lttv_process_traceset_seek_time(LttvTraceset *traceset, LttTime start) | |
200 | { | |
7a4bdb54 YB |
201 | struct bt_iter_pos seekpos; |
202 | int ret; | |
f1e5df2a YB |
203 | if (traceset->iter == NULL) { |
204 | g_warning("Iterator not valid in seek_time"); | |
205 | return; | |
206 | } | |
7a4bdb54 YB |
207 | seekpos.type = BT_SEEK_TIME; |
208 | seekpos.u.seek_time = ltt_time_to_uint64(start); | |
f1e5df2a YB |
209 | |
210 | ret = bt_iter_set_pos(bt_ctf_get_iter(traceset->iter), &seekpos); | |
7a4bdb54 YB |
211 | if(ret < 0) { |
212 | printf("Seek by time error: %s,\n",strerror(-ret)); | |
213 | } | |
9a366873 FD |
214 | } |
215 | ||
216 | guint lttv_process_traceset_seek_n_forward(LttvTraceset *traceset, | |
217 | guint n, | |
218 | check_handler *check, | |
219 | gboolean *stop_flag, | |
220 | LttvFilter *filter1, | |
221 | LttvFilter *filter2, | |
222 | LttvFilter *filter3, | |
223 | gpointer data) | |
224 | { | |
9a366873 FD |
225 | unsigned count = 0; |
226 | while(count < n) { | |
227 | if(bt_iter_next(bt_ctf_get_iter(traceset->iter)) < 0) { | |
228 | printf("ERROR NEXT\n"); | |
229 | break; | |
230 | } | |
231 | count++; | |
232 | } | |
233 | return count; | |
234 | } | |
235 | ||
236 | guint lttv_process_traceset_seek_n_backward(LttvTraceset *ts, | |
237 | guint n, | |
238 | gdouble ratio, | |
239 | check_handler *check, | |
240 | gboolean *stop_flag, | |
241 | LttvFilter *filter1, | |
242 | LttvFilter *filter2, | |
243 | LttvFilter *filter3, | |
244 | gpointer data) | |
245 | { | |
246 | guint i, count, ret; | |
247 | gint extraEvent = 0; | |
248 | guint64 initialTimeStamp, previousTimeStamp; | |
88bf15f0 FD |
249 | LttvTracesetPosition *initialPos, *previousPos, *currentPos, beginPos; |
250 | struct bt_iter_pos pos; | |
251 | beginPos.bt_pos = &pos; | |
252 | beginPos.iter = ts->iter; | |
253 | beginPos.bt_pos->type = BT_SEEK_BEGIN; | |
c73ce169 FD |
254 | beginPos.timestamp = G_MAXUINT64; |
255 | beginPos.cpu_id = INT_MAX; | |
9a366873 | 256 | /*Save initial position of the traceset*/ |
68573dd0 | 257 | initialPos = lttv_traceset_create_current_position (ts); |
9a366873 FD |
258 | |
259 | /*Get the timespan of the initial position*/ | |
260 | initialTimeStamp = lttv_traceset_position_get_timestamp(initialPos); | |
261 | /* | |
262 | * Create a position before the initial timestamp according | |
68573dd0 | 263 | * to the ratio of nanosecond/event hopefully before the |
9a366873 FD |
264 | * the desired seek position |
265 | */ | |
266 | while(1){ | |
267 | previousTimeStamp = initialTimeStamp - n*(guint)ceil(ratio); | |
268 | ||
269 | previousPos = lttv_traceset_create_time_position(ts,ltt_time_from_uint64(previousTimeStamp)); | |
270 | if(initialTimeStamp == previousTimeStamp) | |
271 | break; | |
272 | ||
273 | currentPos = lttv_traceset_create_time_position(ts,ltt_time_from_uint64(previousTimeStamp)); | |
88bf15f0 FD |
274 | /*Corner case: When we are near the beginning of the trace and the previousTimeStamp is before |
275 | * the beginning of the trace. We have to seek to the first event. | |
276 | */ | |
277 | if((lttv_traceset_position_compare(currentPos,&beginPos ) == 0)){ | |
278 | lttv_traceset_seek_to_position(&beginPos); | |
279 | break; | |
280 | } | |
9a366873 | 281 | /*move traceset position */ |
58b4e4ae | 282 | lttv_state_traceset_seek_position(ts, previousPos); |
9a366873 FD |
283 | /* iterate to the initial position counting the number of event*/ |
284 | count = 0; | |
285 | do { | |
286 | if((ret = lttv_traceset_position_compare(currentPos,initialPos)) == 1){ | |
993046ef | 287 | if(bt_iter_next(bt_ctf_get_iter(ts->iter)) == 0) { |
13d35254 YB |
288 | if(bt_ctf_iter_read_event(ts->iter) > 0) { |
289 | lttv_traceset_destroy_position(currentPos); | |
290 | currentPos = lttv_traceset_create_current_position(ts); | |
291 | count++; | |
993046ef YB |
292 | } else { |
293 | break; | |
294 | } | |
295 | ||
296 | } else { | |
297 | ||
298 | //No more event available | |
299 | break; | |
300 | } | |
9a366873 FD |
301 | } |
302 | }while(ret != 0); | |
88bf15f0 | 303 | |
9a366873 FD |
304 | /*substract the desired number of event to the count*/ |
305 | extraEvent = count - n; | |
88bf15f0 | 306 | if (extraEvent >= 0) { |
9a366873 FD |
307 | //if the extraEvent is over 0 go back to previousPos and |
308 | //move forward the value of extraEvent times | |
58b4e4ae | 309 | lttv_state_traceset_seek_position(ts, previousPos); |
9a366873 FD |
310 | |
311 | for(i = 0 ; i < extraEvent ; i++){ | |
312 | if(bt_iter_next(bt_ctf_get_iter(ts->iter)) < 0){ | |
313 | printf("ERROR NEXT\n"); | |
314 | break; | |
315 | } | |
316 | ||
317 | } | |
318 | break; /* we successfully seeked backward */ | |
319 | } | |
88bf15f0 FD |
320 | else{ |
321 | /* if the extraEvent is below 0 create a position before and start over*/ | |
322 | ratio = ratio * 16; | |
9a366873 | 323 | } |
88bf15f0 | 324 | lttv_traceset_destroy_position(currentPos); |
9a366873 FD |
325 | } |
326 | return 0; | |
7a4bdb54 | 327 | } |