ae7c1a16cecf5e9319813d57a0fecbdf91dfb79e
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
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;
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.
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,
23 #include <lttv/traceset.h>
24 #include <lttv/iattribute.h>
25 #include <lttv/state.h>
26 #include <lttv/hook.h>
28 #include <babeltrace/babeltrace.h>
29 #include <babeltrace/context.h>
30 #include <babeltrace/ctf/iterator.h>
31 #include <babeltrace/ctf/events.h>
33 /* To traverse a tree recursively */
36 /* For the use of realpath*/
42 /* A trace is a sequence of events gathered in the same tracing session. The
43 events may be stored in several tracefiles in the same directory.
44 A trace set is defined when several traces are to be analyzed together,
45 possibly to study the interactions between events in the different traces.
49 LttvTraceset
*lttv_traceset_new(void)
52 struct bt_iter_pos begin_pos
;
54 s
= g_new(LttvTraceset
, 1);
56 s
->traces
= g_ptr_array_new();
57 s
->context
= bt_context_create();
58 s
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
59 //TODO remove this when we have really mecanism
60 //s->tmpState = g_new(LttvTraceState *, 1);
61 //lttv_trace_state_init(s->tmpState,0);
64 s
->event_hooks
= lttv_hooks_new();
66 s
->state_trace_handle_index
= g_ptr_array_new();
71 char * lttv_traceset_name(LttvTraceset
* s
)
77 LttvTrace
*lttv_trace_new(LttTrace
*t
)
81 new_trace
= g_new(LttvTrace
, 1);
82 new_trace
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
84 new_trace
->ref_count
= 0;
89 * get_absolute_pathname : Return the unique pathname in the system
91 * pathname is the relative path.
93 * abs_pathname is being set to the absolute path.
96 void get_absolute_pathname(const gchar
*pathname
, gchar
* abs_pathname
)
98 abs_pathname
[0] = '\0';
100 if (realpath(pathname
, abs_pathname
) != NULL
)
104 /* error, return the original path unmodified */
105 strcpy(abs_pathname
, pathname
);
114 * lttv_trace_create : Create a trace from a path
116 * ts is the traceset in which will be contained the trace
118 * path is the path where to find a trace. It is not recursive.
120 * This function is static since a trace should always be contained in a
123 * return the created trace or NULL on failure
125 static LttvTrace
*lttv_trace_create(LttvTraceset
*ts
, const char *path
)
127 int id
= bt_context_add_trace(lttv_traceset_get_context(ts
),
136 // Create the trace and save the trace handle id returned by babeltrace
137 LttvTrace
*new_trace
;
139 new_trace
= g_new(LttvTrace
, 1);
140 new_trace
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
142 new_trace
->ref_count
= 0;
143 new_trace
->traceset
= ts
;
144 new_trace
->state
= g_new(LttvTraceState
,1);
145 lttv_trace_state_init(new_trace
->state
,new_trace
);
147 /* Add the state to the trace_handle to state index */
148 g_ptr_array_set_size(ts
->state_trace_handle_index
,id
+1);
149 g_ptr_array_index(ts
->state_trace_handle_index
,id
) = new_trace
->state
;
155 * lttv_trace_create : Create and add a single trace to a traceset
157 * ts is the traceset in which will be contained the trace
159 * path is the path where to find a trace. It is not recursive.
161 * return a positive integer (>=0)on success or -1 on failure
163 static int lttv_traceset_create_trace(LttvTraceset
*ts
, const char *path
)
165 LttvTrace
*trace
= lttv_trace_create(ts
, path
);
169 lttv_traceset_add(ts
, trace
);
173 LttvTraceset
*lttv_traceset_copy(LttvTraceset
*s_orig
)
179 s
= g_new(LttvTraceset
, 1);
181 s
->traces
= g_ptr_array_new();
182 s
->state_trace_handle_index
= g_ptr_array_new();
183 for(i
=0;i
<s_orig
->traces
->len
;i
++)
185 trace
= g_ptr_array_index(s_orig
->traces
, i
);
188 /* WARNING: this is an alias, not a copy. */
189 g_ptr_array_add(s
->traces
, trace
);
191 g_ptr_array_set_size(s
->state_trace_handle_index
,trace
->id
+1);
192 g_ptr_array_index(s
->state_trace_handle_index
,trace
->id
) = trace
->state
;
195 s
->context
= s_orig
->context
;
196 bt_context_get(s
->context
);
197 s
->a
= LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig
->a
)));
202 LttvTraceset
*lttv_traceset_load(const gchar
*filename
)
204 LttvTraceset
*s
= g_new(LttvTraceset
,1);
207 s
->filename
= g_strdup(filename
);
208 tf
= fopen(filename
,"r");
210 g_critical("NOT IMPLEMENTED : load traceset data from a XML file");
216 gint
lttv_traceset_save(LttvTraceset
*s
)
220 tf
= fopen(s
->filename
, "w");
222 g_critical("NOT IMPLEMENTED : save traceset data in a XML file");
228 void lttv_traceset_destroy(LttvTraceset
*s
)
232 for(i
=0;i
<s
->traces
->len
;i
++) {
233 LttvTrace
*trace
= g_ptr_array_index(s
->traces
, i
);
234 lttv_trace_unref(trace
);
235 // todo mdenis 2012-03-27: uncomment when babeltrace gets fixed
236 //bt_context_remove_trace(lttv_traceset_get_context(s), trace->id);
237 if(lttv_trace_get_ref_number(trace
) == 0)
238 lttv_trace_destroy(trace
);
240 g_ptr_array_free(s
->traces
, TRUE
);
241 bt_context_put(s
->context
);
242 g_object_unref(s
->a
);
246 struct bt_context
*lttv_traceset_get_context(LttvTraceset
*s
)
251 LttvTraceset
*lttv_trace_get_traceset(LttvTrace
*trace
)
253 return trace
->traceset
;
256 LttvHooks
*lttv_traceset_get_hooks(LttvTraceset
*s
)
258 return s
->event_hooks
;
261 void lttv_trace_destroy(LttvTrace
*t
)
263 g_object_unref(t
->a
);
267 void lttv_traceset_add(LttvTraceset
*s
, LttvTrace
*t
)
270 g_ptr_array_add(s
->traces
, t
);
273 int lttv_traceset_add_path(LttvTraceset
*ts
, char *trace_path
)
278 char * const paths
[2] = { trace_path
, NULL
};
281 gboolean metaFileFound
= FALSE
;
283 tree
= fts_open(paths
, FTS_NOCHDIR
| FTS_LOGICAL
, 0);
285 g_warning("Cannot traverse \"%s\" for reading.\n",
291 while ((node
= fts_read(tree
))) {
293 if (!(node
->fts_info
& FTS_D
))
296 dirfd
= open(node
->fts_accpath
, 0);
298 g_warning("Unable to open trace "
299 "directory file descriptor : %s.", node
->fts_accpath
);
304 // Check if a metadata file exists in the current directory
305 metafd
= openat(dirfd
, "metadata", O_RDONLY
);
309 g_warning("Unable to open metadata "
310 "file descriptor : %s.", node
->fts_accpath
);
316 g_warning("Unable to close metadata "
317 "file descriptor : %s.", node
->fts_accpath
);
322 g_warning("Unable to close trace "
323 "directory file descriptor : %s.", node
->fts_accpath
);
327 ret
= lttv_traceset_create_trace(ts
, node
->fts_accpath
);
329 g_warning("Opening trace \"%s\" from %s "
330 "for reading.", node
->fts_accpath
, trace_path
);
333 metaFileFound
= TRUE
;
338 ret
= fts_close(tree
);
340 g_warning("Unable to close tree "
341 "file descriptor : %s.", trace_path
);
350 unsigned lttv_traceset_number(LttvTraceset
*s
)
352 return s
->traces
->len
;
356 LttvTrace
*lttv_traceset_get(LttvTraceset
*s
, unsigned i
)
358 g_assert(s
->traces
->len
> i
);
359 return ((LttvTrace
*)s
->traces
->pdata
[i
]);
363 void lttv_traceset_remove(LttvTraceset
*s
, unsigned i
)
366 g_assert(s
->traces
->len
> i
);
367 t
= (LttvTrace
*)s
->traces
->pdata
[i
];
369 bt_context_remove_trace(lttv_traceset_get_context(s
), t
->id
);
370 g_ptr_array_remove_index(s
->traces
, i
);
374 /* A set of attributes is attached to each trace set, trace and tracefile
375 to store user defined data as needed. */
377 LttvAttribute
*lttv_traceset_attribute(LttvTraceset
*s
)
383 LttvAttribute
*lttv_trace_attribute(LttvTrace
*t
)
389 gint
lttv_trace_get_id(LttvTrace
*t
)
394 guint
lttv_trace_get_ref_number(LttvTrace
* t
)
396 // todo mdenis: adapt to babeltrace
400 guint
lttv_trace_ref(LttvTrace
* t
)
407 guint
lttv_trace_unref(LttvTrace
* t
)
409 if(likely(t
->ref_count
> 0))
415 guint
lttv_trace_get_num_cpu(LttvTrace
*t
)
417 #warning "TODO - Set the right number of CPU"
421 LttvTracesetPosition
*lttv_traceset_create_position(LttvTraceset
*traceset
)
423 LttvTracesetPosition
*traceset_pos
;
425 traceset_pos
= g_new(LttvTracesetPosition
, 1);
427 /* Check in the new passed */
428 if(traceset_pos
== NULL
) {
432 traceset_pos
->iter
= traceset
->iter
;
433 traceset_pos
->bt_pos
= bt_iter_get_pos(bt_ctf_get_iter(traceset
->iter
));
438 void lttv_traceset_destroy_position(LttvTracesetPosition
*traceset_pos
)
440 bt_iter_free_pos(traceset_pos
->bt_pos
);
441 g_free(traceset_pos
);
444 void lttv_traceset_seek_to_position(LttvTracesetPosition
*traceset_pos
)
446 bt_iter_set_pos(traceset_pos
->iter
, traceset_pos
->bt_pos
);
449 guint
lttv_traceset_get_cpuid_from_event(LttvEvent
*event
)
451 struct definition
*scope
;
452 unsigned long timestamp
;
455 struct bt_ctf_event
*ctf_event
= event
->bt_event
;
456 timestamp
= bt_ctf_get_timestamp(ctf_event
);
457 if (timestamp
== -1ULL) {
460 scope
= bt_ctf_get_top_level_scope(ctf_event
, BT_STREAM_PACKET_CONTEXT
);
461 if (bt_ctf_field_get_error()) {
464 cpu_id
= bt_ctf_get_uint64(bt_ctf_get_field(ctf_event
, scope
, "cpu_id"));
465 if (bt_ctf_field_get_error()) {
472 * lttv_traceset_get_timestamp_begin : returns the minimum timestamp of
473 * all the traces in the traceset.
477 guint64
lttv_traceset_get_timestamp_begin(LttvTraceset
*traceset
)
479 struct bt_context
*bt_ctx
;
480 bt_ctx
= lttv_traceset_get_context(traceset
);
481 guint64 timestamp_min
= G_MAXUINT64
, timestamp_cur
= 0;
484 LttvTrace
*currentTrace
;
485 trace_count
= traceset
->traces
->len
;
489 timestamp_min
= G_MAXUINT64
;
491 for(i
= 0; i
< trace_count
;i
++)
493 currentTrace
= g_ptr_array_index(traceset
->traces
,i
);
494 timestamp_cur
= bt_trace_handle_get_timestamp_begin(bt_ctx
, currentTrace
->id
);
495 if(timestamp_cur
< timestamp_min
)
496 timestamp_min
= timestamp_cur
;
499 return timestamp_min
;
503 * lttv_traceset_get_timestamp_end: returns the maximum timestamp of
504 * all the traces in the traceset.
507 guint64
lttv_traceset_get_timestamp_end(LttvTraceset
*traceset
)
509 struct bt_context
*bt_ctx
;
510 bt_ctx
= lttv_traceset_get_context(traceset
);
511 guint64 timestamp_max
, timestamp_cur
= 0;
514 LttvTrace
*currentTrace
;
515 trace_count
= traceset
->traces
->len
;
522 for(i
=0; i
< trace_count
;i
++)
524 currentTrace
= g_ptr_array_index(traceset
->traces
,i
);
525 timestamp_cur
= bt_trace_handle_get_timestamp_end(bt_ctx
, currentTrace
->id
);
526 if(timestamp_cur
> timestamp_max
)
527 timestamp_max
= timestamp_cur
;
530 return timestamp_max
;
534 * lttv_traceset_get_time_span : return a TimeInterval representing the
535 * minimum timestamp dans le maximum timestamp of the traceset.
538 TimeInterval
lttv_traceset_get_time_span(LttvTraceset
*ts
)
540 TimeInterval time_span
;
541 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts
));
542 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts
));
546 const char *lttv_traceset_get_name_from_event(LttvEvent
*event
)
548 return bt_ctf_event_name(event
->bt_event
);
This page took 0.041314 seconds and 4 git commands to generate.