Fix end of the trace handling and end position
[lttv.git] / lttv / lttv / traceset-process.c
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>
28 #include <babeltrace/trace-handle.h>
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 {
37 struct bt_iter_pos begin_pos;
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
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 }
54 }
55
56 guint lttv_process_traceset_middle(LttvTraceset *traceset,
57 LttTime end,
58 gulong nb_events,
59 const LttvTracesetPosition *end_position)
60 {
61 unsigned count = 0;
62 gint last_ret = 0;
63 LttvTracesetPosition *currentPos;
64
65 struct bt_ctf_event *bt_event;
66
67 LttvEvent event;
68 LttTime endPositionTime;
69
70 if(end_position) {
71 endPositionTime = lttv_traceset_position_get_time(end_position);
72 }
73 while(TRUE) {
74
75 if(last_ret == TRUE || ((count >= nb_events) && (nb_events != G_MAXULONG))) {
76 break;
77 }
78
79 if((bt_event = bt_ctf_iter_read_event(traceset->iter)) != NULL) {
80
81 LttTime time = ltt_time_from_uint64(bt_ctf_get_timestamp(bt_event));
82 if(ltt_time_compare(end, time) <= 0) {
83 break;
84 }
85 /*
86 currentPos = lttv_traceset_create_current_position(traceset);
87 if(lttv_traceset_position_compare(currentPos,end_position ) == 0){
88 lttv_traceset_destroy_position(currentPos);
89 break;
90 }
91 lttv_traceset_destroy_position(currentPos);
92 */
93 if(end_position && (ltt_time_compare(endPositionTime, time) <= 0)) {
94 break;
95 }
96 count++;
97
98 event.bt_event = bt_event;
99
100 /* Retreive the associated state */
101 event.state = g_ptr_array_index(traceset->state_trace_handle_index,
102 bt_ctf_event_get_handle_id(bt_event));
103
104 last_ret = lttv_hooks_call(traceset->event_hooks, &event);
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 }
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 {
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 {
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
177 lttv_hooks_remove_list(traceset->event_hooks, event);
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);
197 }
198
199 void lttv_process_traceset_seek_time(LttvTraceset *traceset, LttTime start)
200 {
201 struct bt_iter_pos seekpos;
202 int ret;
203 if (traceset->iter == NULL) {
204 g_warning("Iterator not valid in seek_time");
205 return;
206 }
207 seekpos.type = BT_SEEK_TIME;
208 seekpos.u.seek_time = ltt_time_to_uint64(start);
209
210 ret = bt_iter_set_pos(bt_ctf_get_iter(traceset->iter), &seekpos);
211 if(ret < 0) {
212 printf("Seek by time error: %s,\n",strerror(-ret));
213 }
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 {
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;
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;
254 beginPos.timestamp = G_MAXUINT64;
255 beginPos.cpu_id = INT_MAX;
256 /*Save initial position of the traceset*/
257 initialPos = lttv_traceset_create_current_position (ts);
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
263 * to the ratio of nanosecond/event hopefully before the
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));
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 }
281 /*move traceset position */
282 lttv_state_traceset_seek_position(ts, previousPos);
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){
287 if(bt_iter_next(bt_ctf_get_iter(ts->iter)) == 0) {
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++;
292 } else {
293 break;
294 }
295
296 } else {
297
298 //No more event available
299 break;
300 }
301 }
302 }while(ret != 0);
303
304 /*substract the desired number of event to the count*/
305 extraEvent = count - n;
306 if (extraEvent >= 0) {
307 //if the extraEvent is over 0 go back to previousPos and
308 //move forward the value of extraEvent times
309 lttv_state_traceset_seek_position(ts, previousPos);
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 }
320 else{
321 /* if the extraEvent is below 0 create a position before and start over*/
322 ratio = ratio * 16;
323 }
324 lttv_traceset_destroy_position(currentPos);
325 }
326 return 0;
327 }
This page took 0.03515 seconds and 4 git commands to generate.