X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttv%2Flttv%2Ftraceset.c;h=f7cb9ca608b1479b1c3c82f42d9caa36c71bc96e;hb=d04fa8383cb80eb3c8397edc0134e301f8f7a882;hp=934d65f34c1c11b6e38fa98a2de8d88d2a2c212a;hpb=58b4e4ae6fe118dbf6b441692eae833df2229d3e;p=lttv.git diff --git a/lttv/lttv/traceset.c b/lttv/lttv/traceset.c index 934d65f3..f7cb9ca6 100644 --- a/lttv/lttv/traceset.c +++ b/lttv/lttv/traceset.c @@ -33,13 +33,13 @@ /* To traverse a tree recursively */ #include -#include /* For the use of realpath*/ #include #include /* For strcpy*/ #include - +#include +#include /* 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, @@ -54,12 +54,10 @@ LttvTraceset *lttv_traceset_new(void) ts = g_new(LttvTraceset, 1); ts->filename = NULL; + ts->common_path = NULL; ts->traces = g_ptr_array_new(); ts->context = bt_context_create(); ts->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - //TODO remove this when we have really mecanism - //s->tmpState = g_new(LttvTraceState *, 1); - //lttv_trace_state_init(s->tmpState,0); /*Initialize iterator to the beginning of the traces*/ begin_pos.type = BT_SEEK_BEGIN; @@ -70,6 +68,9 @@ LttvTraceset *lttv_traceset_new(void) ts->state_trace_handle_index = g_ptr_array_new(); ts->has_precomputed_states = FALSE; + ts->time_span.start_time = ltt_time_zero; + ts->time_span.end_time = ltt_time_zero; + lttv_traceset_get_time_span_real(ts); return ts; } @@ -145,6 +146,7 @@ static LttvTrace *lttv_trace_create(LttvTraceset *ts, const char *path) new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); new_trace->id = id; new_trace->ref_count = 0; + new_trace->short_name[0] = '\0'; new_trace->traceset = ts; new_trace->state = g_new(LttvTraceState,1); lttv_trace_state_init(new_trace->state,new_trace); @@ -153,6 +155,29 @@ static LttvTrace *lttv_trace_create(LttvTraceset *ts, const char *path) 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; + /* Find common path */ + if (ts->common_path == NULL) { + ts->common_path = strdup(path); + } else { + /* TODO ybrosseau 2013-05-24: consider put that in a function */ + int i,j; + for (i = 0; + ts->common_path != '\0'; + i++) { + if (path[i] != ts->common_path[i]) { + /* The common path has changed, redo the other traces */ + for(j = 0; j < ts->traces->len; j++) { + LttvTrace *t = g_ptr_array_index(ts->traces, j); + strncpy(t->short_name, t->full_path+i, TRACE_NAME_SIZE); + } + + break; + } + } + strncpy(new_trace->short_name, path+i, TRACE_NAME_SIZE); + } + new_trace->full_path = strdup(path); + return new_trace; } @@ -183,6 +208,7 @@ LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig) s = g_new(LttvTraceset, 1); s->filename = NULL; + s->common_path = strdup(s_orig->common_path); s->traces = g_ptr_array_new(); s->state_trace_handle_index = g_ptr_array_new(); for(i=0;itraces->len;i++) @@ -242,6 +268,7 @@ void lttv_traceset_destroy(LttvTraceset *s) if(lttv_trace_get_ref_number(trace) == 0) lttv_trace_destroy(trace); } + free(s->common_path); g_ptr_array_free(s->traces, TRUE); bt_context_put(s->context); g_object_unref(s->a); @@ -265,6 +292,7 @@ LttvHooks *lttv_traceset_get_hooks(LttvTraceset *s) void lttv_trace_destroy(LttvTrace *t) { + free(t->full_path); g_object_unref(t->a); g_free(t); } @@ -275,82 +303,96 @@ void lttv_traceset_add(LttvTraceset *s, LttvTrace *t) g_ptr_array_add(s->traces, t); } +int lttv_traceset_get_trace_index_from_event(LttvEvent *event) +{ + LttvTraceset *ts = event->state->trace->traceset; + + return lttv_traceset_get_trace_index_from_handle_id(ts, bt_ctf_event_get_handle_id(event->bt_event)); +} + +int lttv_traceset_get_trace_index_from_handle_id(LttvTraceset *ts, int handle_id) +{ + int i; + + /* TODO ybrosseau 2013-05-22: use a map to speedup the lookup */ + + for(i = 0; i < ts->traces->len; i++) { + LttvTrace *t = g_ptr_array_index(ts->traces, i); + if (t && t->id == handle_id) { + return i; + } + } + + /* Handle id not found */ + return -1; + +} + int lttv_traceset_add_path(LttvTraceset *ts, char *trace_path) { - FTS *tree; - FTSENT *node; - char * const paths[2] = { trace_path, NULL }; int ret = -1; - + DIR *curdir = NULL; 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); + + /* Open top level directory */ + curdir = opendir(trace_path); + if (curdir == NULL) { + g_warning("Cannot open directory %s (%s)", trace_path, strerror(errno)); 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; + // Check if a metadata file exists in the current directory + int metafd = openat(dirfd(curdir), "metadata", O_RDONLY); + if (metafd < 0) { + + } else { + ret = close(metafd); + if (ret < 0) { + g_warning("Unable to close metadata " + "file descriptor : %s.", trace_path); goto error; } + + ret = lttv_traceset_create_trace(ts, trace_path); + if (ret < 0) { + g_warning("Opening trace \"%s\" " + "for reading.", trace_path); + goto error; + } + metaFileFound = TRUE; + } - // 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; + struct dirent curentry; + struct dirent *resultentry; + while ((ret = readdir_r(curdir, &curentry, &resultentry)) == 0) { + if (resultentry == NULL) { + /* No more entry*/ + break; + } + if (curentry.d_name[0] != '.') { + if (curentry.d_type == DT_DIR) { + + char curpath[PATH_MAX]; + snprintf(curpath, PATH_MAX, "%s/%s", trace_path, curentry.d_name); + ret = lttv_traceset_add_path(ts, curpath); + if (ret >= 0) { + metaFileFound = TRUE; + } } - metaFileFound = TRUE; } } + if (ret != 0) { + g_warning("Invalid readdir"); + } + 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; @@ -422,7 +464,7 @@ guint lttv_trace_get_num_cpu(LttvTrace *t) return 24; } -LttvTracesetPosition *lttv_traceset_create_current_position(LttvTraceset *traceset) +LttvTracesetPosition *lttv_traceset_create_current_position(const LttvTraceset *traceset) { LttvTracesetPosition *traceset_pos; @@ -435,7 +477,9 @@ LttvTracesetPosition *lttv_traceset_create_current_position(LttvTraceset *traces traceset_pos->iter = traceset->iter; traceset_pos->bt_pos = bt_iter_get_pos(bt_ctf_get_iter(traceset->iter)); - + traceset_pos->timestamp = G_MAXUINT64; + traceset_pos->cpu_id = INT_MAX; + return traceset_pos; } @@ -452,10 +496,11 @@ LttvTracesetPosition *lttv_traceset_create_time_position(LttvTraceset *traceset, } traceset_pos->iter = traceset->iter; - traceset_pos->bt_pos = bt_iter_create_time_pos( + traceset_pos->bt_pos = bt_iter_create_time_pos( bt_ctf_get_iter(traceset_pos->iter), ltt_time_to_uint64(timestamp)); - + traceset_pos->timestamp = G_MAXUINT64; + traceset_pos->cpu_id = INT_MAX; return traceset_pos; } @@ -480,7 +525,7 @@ guint lttv_traceset_get_cpuid_from_event(LttvEvent *event) if (timestamp == -1ULL) { return 0; } - const struct definition *scope = bt_ctf_get_top_level_scope(ctf_event, BT_STREAM_PACKET_CONTEXT); + const struct bt_definition *scope = bt_ctf_get_top_level_scope(ctf_event, BT_STREAM_PACKET_CONTEXT); if (bt_ctf_field_get_error()) { return 0; } @@ -497,6 +542,8 @@ guint64 lttv_traceset_get_timestamp_first_event(LttvTraceset *ts) LttvTracesetPosition begin_position; struct bt_iter_pos pos; begin_position.bt_pos = &pos; + begin_position.timestamp = G_MAXUINT64; + begin_position.cpu_id = INT_MAX; /* Assign iterator to the beginning of the traces */ begin_position.bt_pos->type = BT_SEEK_BEGIN; @@ -505,6 +552,21 @@ guint64 lttv_traceset_get_timestamp_first_event(LttvTraceset *ts) return lttv_traceset_position_get_timestamp(&begin_position); } +guint64 lttv_traceset_get_timestamp_last_event(LttvTraceset *ts) +{ + LttvTracesetPosition last_position; + struct bt_iter_pos pos; + last_position.bt_pos = &pos; + last_position.timestamp = G_MAXUINT64; + last_position.cpu_id = INT_MAX; + + /* Assign iterator to the last event of the traces */ + last_position.bt_pos->type = BT_SEEK_LAST; + last_position.iter = ts->iter; + + return lttv_traceset_position_get_timestamp(&last_position); +} + /* * lttv_traceset_get_timestamp_begin : returns the minimum timestamp of * all the traces in the traceset. @@ -527,7 +589,8 @@ guint64 lttv_traceset_get_timestamp_begin(LttvTraceset *traceset) { currentTrace = g_ptr_array_index(traceset->traces,i); timestamp_cur = bt_trace_handle_get_timestamp_begin(bt_ctx, - currentTrace->id); + currentTrace->id, + BT_CLOCK_REAL); if(timestamp_cur < timestamp_min) timestamp_min = timestamp_cur; } @@ -559,7 +622,8 @@ guint64 lttv_traceset_get_timestamp_end(LttvTraceset *traceset) { currentTrace = g_ptr_array_index(traceset->traces,i); timestamp_cur = bt_trace_handle_get_timestamp_end(bt_ctx, - currentTrace->id); + currentTrace->id, + BT_CLOCK_REAL); if(timestamp_cur > timestamp_max){ timestamp_max = timestamp_cur; } @@ -569,28 +633,37 @@ guint64 lttv_traceset_get_timestamp_end(LttvTraceset *traceset) } /* * lttv_traceset_get_time_span_real : return a TimeInterval representing the - * minimum timestamp dans le maximum timestamp of the traceset. + * minimum timestamp and the maximum timestamp of the traceset. * */ TimeInterval lttv_traceset_get_time_span_real(LttvTraceset *ts) { - TimeInterval time_span; - time_span.start_time =ltt_time_from_uint64(lttv_traceset_get_timestamp_first_event(ts)); - time_span.end_time = ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts)); - return time_span; + + + if(ltt_time_compare(ts->time_span.start_time, + ltt_time_zero) == 0 && ts->traces->len > 0){ + ts->time_span.start_time = ltt_time_from_uint64( + lttv_traceset_get_timestamp_first_event(ts)); + ts->time_span.end_time = ltt_time_from_uint64( + lttv_traceset_get_timestamp_last_event(ts)); + } + return ts->time_span; } /* * lttv_traceset_get_time_span : return a TimeInterval representing the - * minimum timestamp dans le maximum timestamp of the traceset. + * minimum timestamp and the maximum timestamp of the traceset. * */ TimeInterval lttv_traceset_get_time_span(LttvTraceset *ts) { - TimeInterval time_span; - time_span.start_time =ltt_time_from_uint64(lttv_traceset_get_timestamp_begin(ts)); - time_span.end_time = ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts)); - return time_span; + if(ltt_time_compare(ts->time_span.start_time, ltt_time_zero) == 0){ + ts->time_span.start_time =ltt_time_from_uint64( + lttv_traceset_get_timestamp_begin(ts)); + ts->time_span.end_time = ltt_time_from_uint64( + lttv_traceset_get_timestamp_end(ts)); + } + return ts->time_span; } const char *lttv_traceset_get_name_from_event(LttvEvent *event) @@ -598,24 +671,56 @@ const char *lttv_traceset_get_name_from_event(LttvEvent *event) return bt_ctf_event_name(event->bt_event); } -guint64 lttv_traceset_position_get_timestamp(const LttvTracesetPosition *pos) -{ - guint64 timestamp = 0; - /*We save the current iterator,so we can reassign it after the seek*/ - LttvTracesetPosition previous_pos; - previous_pos.iter = pos->iter; - previous_pos.bt_pos = bt_iter_get_pos(bt_ctf_get_iter(pos->iter)); +int set_values_position(const LttvTracesetPosition *pos) +{ + LttvTracesetPosition previous_pos; + previous_pos.iter = pos->iter; + previous_pos.bt_pos = bt_iter_get_pos(bt_ctf_get_iter(pos->iter)); /* Seek to the new desired position */ - lttv_traceset_seek_to_position(pos); + lttv_traceset_seek_to_position(pos); /*Read the event*/ - struct bt_ctf_event *event = bt_ctf_iter_read_event(pos->iter); - + struct bt_ctf_event *event = bt_ctf_iter_read_event(pos->iter); + if(event != NULL){ - timestamp = bt_ctf_get_timestamp_raw(event); + ((LttvTracesetPosition *)pos)->timestamp = bt_ctf_get_timestamp(event); + + LttvEvent lttv_event; + lttv_event.bt_event = event; + ((LttvTracesetPosition *)pos)->cpu_id = lttv_traceset_get_cpuid_from_event(<tv_event); + } + else { + /* The event is null */ + return 0; } - /* Reassign the previously saved position */ - lttv_traceset_seek_to_position(&previous_pos); - return timestamp; + + /* Reassign the previously saved position */ + lttv_traceset_seek_to_position(&previous_pos); + /*We must desallocate because the function bt_iter_get_pos() does a g_new */ + bt_iter_free_pos(previous_pos.bt_pos); + if (pos->timestamp == G_MAXUINT64) { + return 0; + } + return 1; +} + +guint64 lttv_traceset_position_get_timestamp(const LttvTracesetPosition *pos) +{ + if(pos->timestamp == G_MAXUINT64){ + if(set_values_position(pos) == 0){ + return 0; + } + } + + return pos->timestamp; +} + +int lttv_traceset_position_get_cpuid(const LttvTracesetPosition *pos){ + if(pos->cpu_id == INT_MAX ){ + if(set_values_position(pos) == 0){ + return 0; + } + } + return pos->cpu_id; } LttTime lttv_traceset_position_get_time(const LttvTracesetPosition *pos) @@ -624,37 +729,41 @@ LttTime lttv_traceset_position_get_time(const LttvTracesetPosition *pos) } - +/* 0 if equals, other is different */ int lttv_traceset_position_compare(const LttvTracesetPosition *pos1, const LttvTracesetPosition *pos2) { #warning " TODO :Rename for lttv_traceset_position_equals && Must return COMPARAISON OF THE 2 POSITION && verify if it is the best way to compare position" if(pos1 == NULL || pos2 == NULL){ return -1; } - - guint64 timeStampPos1,timeStampPos2; - guint cpuId1, cpuId2; - LttvEvent event1, event2; - int ret; - - timeStampPos1 = lttv_traceset_position_get_timestamp(pos1); - timeStampPos2 = lttv_traceset_position_get_timestamp(pos2); - - event1.bt_event = bt_ctf_iter_read_event(pos1->iter); - event2.bt_event = bt_ctf_iter_read_event(pos2->iter); - - if(event1.bt_event == NULL || event2.bt_event == NULL){ - return -1; - } - cpuId1 = lttv_traceset_get_cpuid_from_event(&event1); - cpuId2 = lttv_traceset_get_cpuid_from_event(&event2); - - if(timeStampPos1 == timeStampPos2 && cpuId1 == cpuId2){ - return 0; + int res = -1; +#ifdef HAVE_BT_ITER_EQUALS_POS + if(pos1->timestamp == G_MAXUINT64 || pos2->timestamp == G_MAXUINT64) { + res = bt_iter_equals_pos(pos1->bt_pos, pos2->bt_pos); } - else{ - return 1; +#endif + if (res < 0) { + + guint64 timeStampPos1,timeStampPos2; + guint cpuId1, cpuId2; + + timeStampPos1 = lttv_traceset_position_get_timestamp(pos1); + timeStampPos2 = lttv_traceset_position_get_timestamp(pos2); + + if (timeStampPos1 == timeStampPos2) { + + cpuId1 = lttv_traceset_position_get_cpuid(pos1); + cpuId2 = lttv_traceset_position_get_cpuid(pos2); + + if(cpuId1 == cpuId2){ + return 0; + } + } + return 1; + } else { + + return !res; } }