#include <lttv/state.h>
#include <lttv/hook.h>
#include <stdio.h>
+#include <babeltrace/babeltrace.h>
#include <babeltrace/context.h>
-#include <babeltrace/iterator.h>
+#include <babeltrace/ctf/iterator.h>
#include <babeltrace/ctf/events.h>
+
+/* To traverse a tree recursively */
+#include <fcntl.h>
+#include <fts.h>
+/* For the use of realpath*/
+#include <limits.h>
+#include <stdlib.h>
+/* For strcpy*/
+#include <string.h>
+
/* A trace is a sequence of events gathered in the same tracing session. The
events may be stored in several tracefiles in the same directory.
A trace set is defined when several traces are to be analyzed together,
//TODO remove this when we have really mecanism
//s->tmpState = g_new(LttvTraceState *, 1);
//lttv_trace_state_init(s->tmpState,0);
- begin_pos.type = BT_SEEK_BEGIN;
- //s->iter = bt_ctf_iter_create(lttv_traceset_get_context(s),
- // &begin_pos,
- // NULL);
s->iter = 0;
s->event_hooks = lttv_hooks_new();
-
-
-
+
+ s->state_trace_handle_index = g_ptr_array_new();
return s;
}
return new_trace;
}
#endif
+/*
+ * get_absolute_pathname : Return the unique pathname in the system
+ *
+ * pathname is the relative path.
+ *
+ * abs_pathname is being set to the absolute path.
+ *
+ */
+void get_absolute_pathname(const gchar *pathname, gchar * abs_pathname)
+{
+ abs_pathname[0] = '\0';
+
+ if (realpath(pathname, abs_pathname) != NULL)
+ return;
+ else
+ {
+ /* error, return the original path unmodified */
+ strcpy(abs_pathname, pathname);
+ return;
+ }
+ return;
+}
+
+
/*
* lttv_trace_create : Create a trace from a path
new_trace->traceset = ts;
new_trace->state = g_new(LttvTraceState,1);
lttv_trace_state_init(new_trace->state,new_trace);
- ts->tmpState = new_trace->state;
+
+ /* Add the state to the trace_handle to state index */
+ g_ptr_array_set_size(ts->state_trace_handle_index,id+1);
+ g_ptr_array_index(ts->state_trace_handle_index,id) = new_trace->state;
+
return new_trace;
}
s = g_new(LttvTraceset, 1);
s->filename = NULL;
s->traces = g_ptr_array_new();
+ s->state_trace_handle_index = g_ptr_array_new();
for(i=0;i<s_orig->traces->len;i++)
{
trace = g_ptr_array_index(s_orig->traces, i);
/* WARNING: this is an alias, not a copy. */
g_ptr_array_add(s->traces, trace);
+
+ g_ptr_array_set_size(s->state_trace_handle_index,trace->id+1);
+ g_ptr_array_index(s->state_trace_handle_index,trace->id) = trace->state;
+
}
s->context = s_orig->context;
bt_context_get(s->context);
g_free(t);
}
-
void lttv_traceset_add(LttvTraceset *s, LttvTrace *t)
{
t->ref_count++;
g_ptr_array_add(s->traces, t);
}
-int lttv_traceset_add_path(LttvTraceset *ts, const char *trace_path)
+int lttv_traceset_add_path(LttvTraceset *ts, char *trace_path)
{
- // todo mdenis 2012-03-27: add trace recursively and update comment
- int ret = lttv_traceset_create_trace(ts, trace_path);
- return ret;
+
+ FTS *tree;
+ FTSENT *node;
+ char * const paths[2] = { trace_path, NULL };
+ int ret = -1;
+
+ gboolean metaFileFound = FALSE;
+
+ tree = fts_open(paths, FTS_NOCHDIR | FTS_LOGICAL, 0);
+ if (tree == NULL) {
+ g_warning("Cannot traverse \"%s\" for reading.\n",
+ trace_path);
+ return ret;
+ }
+
+ int dirfd, metafd;
+ while ((node = fts_read(tree))) {
+
+ if (!(node->fts_info & FTS_D))
+ continue;
+
+ dirfd = open(node->fts_accpath, 0);
+ if (dirfd < 0) {
+ g_warning("Unable to open trace "
+ "directory file descriptor : %s.", node->fts_accpath);
+ ret = dirfd;
+ goto error;
+ }
+
+ // Check if a metadata file exists in the current directory
+ metafd = openat(dirfd, "metadata", O_RDONLY);
+ if (metafd < 0) {
+ ret = close(dirfd);
+ if (ret < 0) {
+ g_warning("Unable to open metadata "
+ "file descriptor : %s.", node->fts_accpath);
+ goto error;
+ }
+ } else {
+ ret = close(metafd);
+ if (ret < 0) {
+ g_warning("Unable to close metadata "
+ "file descriptor : %s.", node->fts_accpath);
+ goto error;
+ }
+ ret = close(dirfd);
+ if (ret < 0) {
+ g_warning("Unable to close trace "
+ "directory file descriptor : %s.", node->fts_accpath);
+ goto error;
+ }
+
+ ret = lttv_traceset_create_trace(ts, node->fts_accpath);
+ if (ret < 0) {
+ g_warning("Opening trace \"%s\" from %s "
+ "for reading.", node->fts_accpath, trace_path);
+ goto error;
+ }
+ metaFileFound = TRUE;
+ }
+ }
+
+error:
+ ret = fts_close(tree);
+ if (ret < 0) {
+ g_warning("Unable to close tree "
+ "file descriptor : %s.", trace_path);
+ }
+ if(metaFileFound)
+ return ret;
+ else
+ return -1;
}
+
unsigned lttv_traceset_number(LttvTraceset *s)
{
return s->traces->len;
return t->a;
}
-#ifdef BABEL_CLEANUP
-LttTrace *lttv_trace(LttvTrace *t)
-{
- return t->t;
-}
-#endif
gint lttv_trace_get_id(LttvTrace *t)
{
LttvTracesetPosition *lttv_traceset_create_position(LttvTraceset *traceset)
{
-#warning "TODO"
- return NULL;
+ LttvTracesetPosition *traceset_pos;
+
+ traceset_pos = g_new(LttvTracesetPosition, 1);
+
+ /* Check in the new passed */
+ if(traceset_pos == NULL) {
+ return NULL;
+ }
+
+ traceset_pos->iter = traceset->iter;
+ traceset_pos->bt_pos = bt_iter_get_pos(bt_ctf_get_iter(traceset->iter));
+
+ return traceset_pos;
}
void lttv_traceset_destroy_position(LttvTracesetPosition *traceset_pos)
{
-#warning "TODO"
- return NULL;
+ bt_iter_free_pos(traceset_pos->bt_pos);
+ g_free(traceset_pos);
}
void lttv_traceset_seek_to_position(LttvTracesetPosition *traceset_pos)
{
-#warning "TODO"
+ bt_iter_set_pos(traceset_pos->iter, traceset_pos->bt_pos);
}
guint lttv_traceset_get_cpuid_from_event(LttvEvent *event)
return cpu_id;
}
}
+/*
+ * lttv_traceset_get_timestamp_begin : returns the minimum timestamp of
+ * all the traces in the traceset.
+ *
+ */
+
+guint64 lttv_traceset_get_timestamp_begin(LttvTraceset *traceset)
+{
+ struct bt_context *bt_ctx;
+ bt_ctx = lttv_traceset_get_context(traceset);
+ guint64 timestamp_min = G_MAXUINT64, timestamp_cur = 0;
+ int i;
+ int trace_count;
+ LttvTrace *currentTrace;
+ trace_count = traceset->traces->len;
+ if(trace_count == 0)
+ timestamp_min = 0;
+ else{
+ timestamp_min = G_MAXUINT64;
+
+ for(i = 0; i < trace_count;i++)
+ {
+ currentTrace = g_ptr_array_index(traceset->traces,i);
+ timestamp_cur = bt_trace_handle_get_timestamp_begin(bt_ctx, currentTrace->id);
+ if(timestamp_cur < timestamp_min)
+ timestamp_min = timestamp_cur;
+ }
+ }
+ return timestamp_min;
+}
+
+/*
+ * lttv_traceset_get_timestamp_end: returns the maximum timestamp of
+ * all the traces in the traceset.
+ *
+ */
+guint64 lttv_traceset_get_timestamp_end(LttvTraceset *traceset)
+{
+ struct bt_context *bt_ctx;
+ bt_ctx = lttv_traceset_get_context(traceset);
+ guint64 timestamp_max, timestamp_cur = 0;
+ int i;
+ int trace_count;
+ LttvTrace *currentTrace;
+ trace_count = traceset->traces->len;
+
+ if(trace_count == 0)
+ timestamp_max = 1;
+ else
+ {
+ timestamp_max = 0;
+ for(i =0; i < trace_count;i++)
+ {
+ currentTrace = g_ptr_array_index(traceset->traces,i);
+ timestamp_cur = bt_trace_handle_get_timestamp_end(bt_ctx, currentTrace->id);
+ if(timestamp_cur > timestamp_max)
+ timestamp_max = timestamp_cur;
+ }
+ }
+ return timestamp_max;
+
+}
const char *lttv_traceset_get_name_from_event(LttvEvent *event)
{