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