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