Implement LttvTracesetPosition
[lttv.git] / lttv / lttv / traceset.c
CommitLineData
9c312311 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
4e4d11b3 19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
dc877563 22
23#include <lttv/traceset.h>
3e67c985 24#include <lttv/iattribute.h>
7a4bdb54
YB
25#include <lttv/state.h>
26#include <lttv/hook.h>
f7afe191 27#include <stdio.h>
cbb811b3 28#include <babeltrace/context.h>
7a4bdb54
YB
29#include <babeltrace/iterator.h>
30#include <babeltrace/ctf/events.h>
3685e022 31
32/* To traverse a tree recursively */
33#include <fcntl.h>
34#include <fts.h>
35
dc877563 36/* A trace is a sequence of events gathered in the same tracing session. The
37 events may be stored in several tracefiles in the same directory.
38 A trace set is defined when several traces are to be analyzed together,
39 possibly to study the interactions between events in the different traces.
40*/
41
dc877563 42
7a4bdb54 43LttvTraceset *lttv_traceset_new(void)
dc877563 44{
90e19f82 45 LttvTraceset *s;
7a4bdb54 46 struct bt_iter_pos begin_pos;
dc877563 47
90e19f82
AM
48 s = g_new(LttvTraceset, 1);
49 s->filename = NULL;
50 s->traces = g_ptr_array_new();
cbb811b3 51 s->context = bt_context_create();
90e19f82 52 s->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
7a4bdb54
YB
53 //TODO remove this when we have really mecanism
54 //s->tmpState = g_new(LttvTraceState *, 1);
55 //lttv_trace_state_init(s->tmpState,0);
56 begin_pos.type = BT_SEEK_BEGIN;
57
58 //s->iter = bt_ctf_iter_create(lttv_traceset_get_context(s),
59 // &begin_pos,
60 // NULL);
61 s->iter = 0;
62 s->event_hooks = lttv_hooks_new();
115c78c2 63 s->state_trace_handle_index = g_ptr_array_new();
7a4bdb54
YB
64
65
66
90e19f82 67 return s;
dc877563 68}
69
49bf71b5 70char * lttv_traceset_name(LttvTraceset * s)
71{
90e19f82 72 return s->filename;
49bf71b5 73}
74
2bc1bcfb 75#ifdef BABEL_CLEANUP
76LttvTrace *lttv_trace_new(LttTrace *t)
308711e5 77{
90e19f82 78 LttvTrace *new_trace;
308711e5 79
90e19f82
AM
80 new_trace = g_new(LttvTrace, 1);
81 new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
2bc1bcfb 82 new_trace->id = t;
90e19f82
AM
83 new_trace->ref_count = 0;
84 return new_trace;
308711e5 85}
2bc1bcfb 86#endif
308711e5 87
2bc1bcfb 88/*
89 * lttv_trace_create : Create a trace from a path
90 *
91 * ts is the traceset in which will be contained the trace
92 *
93 * path is the path where to find a trace. It is not recursive.
94 *
95 * This function is static since a trace should always be contained in a
96 * traceset.
97 *
98 * return the created trace or NULL on failure
99 */
100static LttvTrace *lttv_trace_create(LttvTraceset *ts, const char *path)
101{
102 int id = bt_context_add_trace(lttv_traceset_get_context(ts),
103 path,
104 "ctf",
105 NULL,
106 NULL,
107 NULL);
108 if (id < 0) {
109 return NULL;
110 }
111 // Create the trace and save the trace handle id returned by babeltrace
112 LttvTrace *new_trace;
113
114 new_trace = g_new(LttvTrace, 1);
115 new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
116 new_trace->id = id;
117 new_trace->ref_count = 0;
7a4bdb54
YB
118 new_trace->traceset = ts;
119 new_trace->state = g_new(LttvTraceState,1);
120 lttv_trace_state_init(new_trace->state,new_trace);
115c78c2
YB
121
122 /* Add the state to the trace_handle to state index */
123 g_ptr_array_set_size(ts->state_trace_handle_index,id+1);
124 g_ptr_array_index(ts->state_trace_handle_index,id) = new_trace->state;
125
2bc1bcfb 126 return new_trace;
127}
128
129/*
130 * lttv_trace_create : Create and add a single trace to a traceset
131 *
132 * ts is the traceset in which will be contained the trace
133 *
134 * path is the path where to find a trace. It is not recursive.
135 *
136 * return a positive integer (>=0)on success or -1 on failure
137 */
138static int lttv_traceset_create_trace(LttvTraceset *ts, const char *path)
139{
140 LttvTrace *trace = lttv_trace_create(ts, path);
141 if (trace == NULL) {
142 return -1;
143 }
144 lttv_traceset_add(ts, trace);
145 return 0;
146}
308711e5 147
f7afe191 148LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig)
149{
90e19f82
AM
150 guint i;
151 LttvTraceset *s;
152 LttvTrace * trace;
f7afe191 153
90e19f82
AM
154 s = g_new(LttvTraceset, 1);
155 s->filename = NULL;
156 s->traces = g_ptr_array_new();
115c78c2 157 s->state_trace_handle_index = g_ptr_array_new();
90e19f82
AM
158 for(i=0;i<s_orig->traces->len;i++)
159 {
160 trace = g_ptr_array_index(s_orig->traces, i);
161 trace->ref_count++;
2176f952 162
7a4bdb54 163 /* WARNING: this is an alias, not a copy. */
90e19f82 164 g_ptr_array_add(s->traces, trace);
115c78c2
YB
165
166 g_ptr_array_set_size(s->state_trace_handle_index,trace->id+1);
167 g_ptr_array_index(s->state_trace_handle_index,trace->id) = trace->state;
168
90e19f82 169 }
cbb811b3
YB
170 s->context = s_orig->context;
171 bt_context_get(s->context);
90e19f82
AM
172 s->a = LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig->a)));
173 return s;
f7afe191 174}
dc877563 175
f7afe191 176
177LttvTraceset *lttv_traceset_load(const gchar *filename)
178{
90e19f82
AM
179 LttvTraceset *s = g_new(LttvTraceset,1);
180 FILE *tf;
f7afe191 181
90e19f82
AM
182 s->filename = g_strdup(filename);
183 tf = fopen(filename,"r");
184
185 g_critical("NOT IMPLEMENTED : load traceset data from a XML file");
186
187 fclose(tf);
188 return s;
f7afe191 189}
190
191gint lttv_traceset_save(LttvTraceset *s)
192{
90e19f82 193 FILE *tf;
f7afe191 194
90e19f82 195 tf = fopen(s->filename, "w");
f7afe191 196
90e19f82
AM
197 g_critical("NOT IMPLEMENTED : save traceset data in a XML file");
198
199 fclose(tf);
200 return 0;
f7afe191 201}
308711e5 202
ba576a78 203void lttv_traceset_destroy(LttvTraceset *s)
dc877563 204{
90e19f82 205 guint i;
5e2c04a2 206
90e19f82
AM
207 for(i=0;i<s->traces->len;i++) {
208 LttvTrace *trace = g_ptr_array_index(s->traces, i);
209 lttv_trace_unref(trace);
2bc1bcfb 210 // todo mdenis 2012-03-27: uncomment when babeltrace gets fixed
211 //bt_context_remove_trace(lttv_traceset_get_context(s), trace->id);
90e19f82
AM
212 if(lttv_trace_get_ref_number(trace) == 0)
213 lttv_trace_destroy(trace);
214 }
215 g_ptr_array_free(s->traces, TRUE);
cbb811b3 216 bt_context_put(s->context);
90e19f82
AM
217 g_object_unref(s->a);
218 g_free(s);
dc877563 219}
220
922581a4
YB
221struct bt_context *lttv_traceset_get_context(LttvTraceset *s)
222{
223 return s->context;
224}
225
7a4bdb54
YB
226LttvTraceset *lttv_trace_get_traceset(LttvTrace *trace)
227{
228 return trace->traceset;
229}
230
231LttvHooks *lttv_traceset_get_hooks(LttvTraceset *s)
232{
233 return s->event_hooks;
234}
235
308711e5 236void lttv_trace_destroy(LttvTrace *t)
237{
90e19f82
AM
238 g_object_unref(t->a);
239 g_free(t);
308711e5 240}
241
242
243void lttv_traceset_add(LttvTraceset *s, LttvTrace *t)
dc877563 244{
90e19f82
AM
245 t->ref_count++;
246 g_ptr_array_add(s->traces, t);
dc877563 247}
248
3685e022 249int lttv_traceset_add_path(LttvTraceset *ts, char *trace_path)
2bc1bcfb 250{
3685e022 251 FTS *tree;
252 FTSENT *node;
253 char * const paths[2] = { trace_path, NULL };
254 int ret = -1;
255
256 tree = fts_open(paths, FTS_NOCHDIR | FTS_LOGICAL, 0);
257 if (tree == NULL) {
258 g_warning("Cannot traverse \"%s\" for reading.\n",
259 trace_path);
260 return ret;
261 }
262
263 int dirfd, metafd;
264 while ((node = fts_read(tree))) {
265
266 if (!(node->fts_info & FTS_D))
267 continue;
268
269 dirfd = open(node->fts_accpath, 0);
270 if (dirfd < 0) {
271 g_warning("Unable to open trace "
272 "directory file descriptor : %s.", node->fts_accpath);
273 ret = dirfd;
274 goto error;
275 }
276
277 // Check if a metadata file exists in the current directory
278 metafd = openat(dirfd, "metadata", O_RDONLY);
279 if (metafd < 0) {
280 ret = close(dirfd);
281 if (ret < 0) {
282 g_warning("Unable to open metadata "
283 "file descriptor : %s.", node->fts_accpath);
284 goto error;
285 }
286 } else {
287 ret = close(metafd);
288 if (ret < 0) {
289 g_warning("Unable to close metadata "
290 "file descriptor : %s.", node->fts_accpath);
291 goto error;
292 }
293 ret = close(dirfd);
294 if (ret < 0) {
295 g_warning("Unable to close trace "
296 "directory file descriptor : %s.", node->fts_accpath);
297 goto error;
298 }
299
300 ret = lttv_traceset_create_trace(ts, node->fts_accpath);
301 if (ret < 0) {
302 g_warning("Opening trace \"%s\" from %s "
303 "for reading.", node->fts_accpath, trace_path);
304 goto error;
305 }
306 }
307 }
308
309error:
310 ret = fts_close(tree);
311 if (ret < 0) {
312 g_warning("Unable to close tree "
313 "file descriptor : %s.", trace_path);
314 }
315 return ret;
2bc1bcfb 316}
dc877563 317
318unsigned lttv_traceset_number(LttvTraceset *s)
319{
90e19f82 320 return s->traces->len;
dc877563 321}
322
323
308711e5 324LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i)
dc877563 325{
90e19f82
AM
326 g_assert(s->traces->len > i);
327 return ((LttvTrace *)s->traces->pdata[i]);
dc877563 328}
329
330
ba576a78 331void lttv_traceset_remove(LttvTraceset *s, unsigned i)
dc877563 332{
90e19f82
AM
333 LttvTrace * t;
334 g_assert(s->traces->len > i);
335 t = (LttvTrace *)s->traces->pdata[i];
336 t->ref_count--;
2bc1bcfb 337 bt_context_remove_trace(lttv_traceset_get_context(s), t->id);
90e19f82 338 g_ptr_array_remove_index(s->traces, i);
dc877563 339}
340
341
342/* A set of attributes is attached to each trace set, trace and tracefile
90e19f82 343 to store user defined data as needed. */
dc877563 344
345LttvAttribute *lttv_traceset_attribute(LttvTraceset *s)
346{
90e19f82 347 return s->a;
dc877563 348}
349
350
308711e5 351LttvAttribute *lttv_trace_attribute(LttvTrace *t)
352{
90e19f82 353 return t->a;
308711e5 354}
355
2bc1bcfb 356#ifdef BABEL_CLEANUP
308711e5 357LttTrace *lttv_trace(LttvTrace *t)
dc877563 358{
90e19f82 359 return t->t;
dc877563 360}
2bc1bcfb 361#endif
362
363gint lttv_trace_get_id(LttvTrace *t)
364{
365 return t->id;
366}
308711e5 367
2176f952 368guint lttv_trace_get_ref_number(LttvTrace * t)
369{
2bc1bcfb 370 // todo mdenis: adapt to babeltrace
90e19f82 371 return t->ref_count;
2176f952 372}
a43d67ba 373
374guint lttv_trace_ref(LttvTrace * t)
375{
90e19f82
AM
376 t->ref_count++;
377
378 return t->ref_count;
a43d67ba 379}
380
381guint lttv_trace_unref(LttvTrace * t)
382{
90e19f82
AM
383 if(likely(t->ref_count > 0))
384 t->ref_count--;
a43d67ba 385
90e19f82 386 return t->ref_count;
a43d67ba 387}
388
7a4bdb54
YB
389guint lttv_trace_get_num_cpu(LttvTrace *t)
390{
391#warning "TODO - Set the right number of CPU"
392 return 24;
393}
394
395LttvTracesetPosition *lttv_traceset_create_position(LttvTraceset *traceset)
396{
3d1e7ee5
YB
397 LttvTracesetPosition *traceset_pos;
398
399 traceset_pos = g_new(LttvTracesetPosition, 1);
400
401 /* Check in the new passed */
402 if(traceset_pos == NULL) {
403 return NULL;
404 }
405
406 traceset_pos->iter = traceset->iter;
407 traceset_pos->bt_pos = bt_iter_get_pos(bt_ctf_get_iter(traceset->iter));
408
409 return traceset_pos;
7a4bdb54
YB
410}
411
412void lttv_traceset_destroy_position(LttvTracesetPosition *traceset_pos)
413{
3d1e7ee5
YB
414 bt_iter_free_pos(traceset_pos->bt_pos);
415 g_free(traceset_pos);
7a4bdb54
YB
416}
417
418void lttv_traceset_seek_to_position(LttvTracesetPosition *traceset_pos)
419{
3d1e7ee5 420 bt_iter_set_pos(traceset_pos->iter, traceset_pos->bt_pos);
7a4bdb54
YB
421}
422
423guint lttv_traceset_get_cpuid_from_event(LttvEvent *event)
424{
425 struct definition *scope;
426 unsigned long timestamp;
427 unsigned int cpu_id;
428
429 struct bt_ctf_event *ctf_event = event->bt_event;
430 timestamp = bt_ctf_get_timestamp(ctf_event);
431 if (timestamp == -1ULL) {
432 return 0;
433 }
434 scope = bt_ctf_get_top_level_scope(ctf_event, BT_STREAM_PACKET_CONTEXT);
435 if (bt_ctf_field_get_error()) {
436 return 0;
437 }
438 cpu_id = bt_ctf_get_uint64(bt_ctf_get_field(ctf_event, scope, "cpu_id"));
439 if (bt_ctf_field_get_error()) {
440 return 0;
441 } else {
442 return cpu_id;
443 }
444}
445
446const char *lttv_traceset_get_name_from_event(LttvEvent *event)
447{
448 return bt_ctf_event_name(event->bt_event);
449}
This page took 0.087802 seconds and 4 git commands to generate.