Fix seek n backward that did not check the end of a trace
[lttv.git] / lttv / lttv / traceset-process.c
CommitLineData
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
32void 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
56guint 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
112void 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
127void 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}
150void 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
176void lttv_trace_add_hooks(LttvTrace *trace,
177 LttvHooks *before_trace,
178 LttvHooks *event)
179{
180 lttv_hooks_call(before_trace, trace);
181}
182
183void 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
191void 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
208guint 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
228guint 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}
This page took 0.034754 seconds and 4 git commands to generate.