Fix end of the trace handling and end position
[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;
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
YB
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));
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
120void 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
135void 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}
158void 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
184void lttv_trace_add_hooks(LttvTrace *trace,
185 LttvHooks *before_trace,
186 LttvHooks *event)
187{
188 lttv_hooks_call(before_trace, trace);
189}
190
191void 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
199void 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
216guint 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
236guint 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}
This page took 0.035822 seconds and 4 git commands to generate.