Handle cases where a trace have a negative offset from Epoch.
If Epoch is arbitrary (e.g. embedded system starting at 0, without any
network access), the "0" can be used as correlation point between
various components, and some components could start before the
correlation point. Therefore, especially in traces where the time is
meant to be shown in nanoseconds or cycles from the correlation point,
it also makes sense to have a negative time value.
It introduces API-breaking changes in the C and Python APIs, since we
need to be able to return negative time values, which were previously
used as errors (-1ULL).
The --offset and --offset-ns command line parameters can now take
negative offset (seconds and nanoseconds) values too.
The [sec.ns] format is used as fallback so we don't attempt to pass
a negative time value to POSIX time-formatting APIs.
This also fixes an inaccurate return value in an error path of
bt_ctf_event_populate_event_header().
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
%rename("_bt_trace_handle_get_path") bt_trace_handle_get_path(struct bt_context *ctx,
int handle_id);
%rename("_bt_trace_handle_get_timestamp_begin") bt_trace_handle_get_timestamp_begin(
- struct bt_context *ctx, int handle_id, enum bt_clock_type type);
+ struct bt_context *ctx, int handle_id, enum bt_clock_type type,
+ int64_t *timestamp);
%rename("_bt_trace_handle_get_timestamp_end") bt_trace_handle_get_timestamp_end(
- struct bt_context *ctx, int handle_id, enum bt_clock_type type);
+ struct bt_context *ctx, int handle_id, enum bt_clock_type type,
+ int64_t *timestamp);
const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id);
-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, int handle_id,
- enum bt_clock_type type);
-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, int handle_id,
- enum bt_clock_type type);
+int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, int handle_id,
+ enum bt_clock_type type, int64_t *timestamp);
+int bt_trace_handle_get_timestamp_end(struct bt_context *ctx, int handle_id,
+ enum bt_clock_type type, int64_t *timestamp);
%rename("_bt_ctf_event_get_handle_id") bt_ctf_event_get_handle_id(
const struct bt_ctf_event *event);
bt_ctf_event *event, enum bt_ctf_scope scope);
%rename("_bt_ctf_event_name") bt_ctf_event_name(const struct bt_ctf_event *ctf_event);
%rename("_bt_ctf_get_timestamp") bt_ctf_get_timestamp(
- const struct bt_ctf_event *ctf_event);
+ const struct bt_ctf_event *ctf_event, int64_t *timestamp);
%rename("_bt_ctf_get_cycles") bt_ctf_get_cycles(
const struct bt_ctf_event *ctf_event);
const struct bt_definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event,
enum bt_ctf_scope scope);
const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event);
-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event);
+int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, int64_t *timestamp);
uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event);
const struct bt_definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
const struct bt_definition *scope,
%rename("_bt_ctf_clock_set_frequency") bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq);
%rename("_bt_ctf_clock_get_precision") bt_ctf_clock_get_precision(struct bt_ctf_clock *clock);
%rename("_bt_ctf_clock_set_precision") bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision);
-%rename("_bt_ctf_clock_get_offset_s") bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock);
-%rename("_bt_ctf_clock_set_offset_s") bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, uint64_t offset_s);
-%rename("_bt_ctf_clock_get_offset") bt_ctf_clock_get_offset(struct bt_ctf_clock *clock);
-%rename("_bt_ctf_clock_set_offset") bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, uint64_t offset);
+%rename("_bt_ctf_clock_get_offset_s") bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s);
+%rename("_bt_ctf_clock_set_offset_s") bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s);
+%rename("_bt_ctf_clock_get_offset") bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset);
+%rename("_bt_ctf_clock_set_offset") bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset);
%rename("_bt_ctf_clock_get_is_absolute") bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock);
%rename("_bt_ctf_clock_set_is_absolute") bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute);
-%rename("_bt_ctf_clock_get_time") bt_ctf_clock_get_time(struct bt_ctf_clock *clock);
-%rename("_bt_ctf_clock_set_time") bt_ctf_clock_set_time(struct bt_ctf_clock *clock, uint64_t time);
+%rename("_bt_ctf_clock_get_time") bt_ctf_clock_get_time(struct bt_ctf_clock *clock, int64_t *time);
+%rename("_bt_ctf_clock_set_time") bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time);
%rename("_bt_ctf_clock_get") bt_ctf_clock_get(struct bt_ctf_clock *clock);
%rename("_bt_ctf_clock_put") bt_ctf_clock_put(struct bt_ctf_clock *clock);
int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq);
uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock);
int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision);
-uint64_t bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, uint64_t offset_s);
-uint64_t bt_ctf_clock_get_offset(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, uint64_t offset);
+int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s);
+int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s);
+int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset);
+int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset);
int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock);
int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute);
-uint64_t bt_ctf_clock_get_time(struct bt_ctf_clock *clock);
-int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, uint64_t time);
+int bt_ctf_clock_get_time(struct bt_ctf_clock *clock, int64_t *time);
+int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time);
void bt_ctf_clock_get(struct bt_ctf_clock *clock);
void bt_ctf_clock_put(struct bt_ctf_clock *clock);
goto end;
}
errno = 0;
- opt_clock_offset = strtoull(str, &endptr, 0);
+ opt_clock_offset = strtoll(str, &endptr, 0);
if (*endptr != '\0' || str == endptr || errno != 0) {
fprintf(stderr, "[error] Incorrect --clock-offset argument: %s\n", str);
ret = -EINVAL;
goto end;
}
errno = 0;
- opt_clock_offset_ns = strtoull(str, &endptr, 0);
+ opt_clock_offset_ns = strtoll(str, &endptr, 0);
if (*endptr != '\0' || str == endptr || errno != 0) {
fprintf(stderr, "[error] Incorrect --clock-offset-ns argument: %s\n", str);
ret = -EINVAL;
#include <unistd.h>
#include <stdlib.h>
-#define NSEC_PER_SEC 1000000000ULL
+#define NSEC_PER_SEC 1000000000LL
int opt_all_field_names,
opt_scope_field_names,
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
-#define NSEC_PER_SEC 1000000000ULL
+#define NSEC_PER_SEC 1000000000LL
#define INDEX_PATH "./index/%s.idx"
opt_clock_date,
opt_clock_gmt;
-uint64_t opt_clock_offset;
-uint64_t opt_clock_offset_ns;
+int64_t opt_clock_offset;
+int64_t opt_clock_offset_ns;
extern int yydebug;
static
int ctf_close_trace(struct bt_trace_descriptor *descriptor);
static
-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor *descriptor,
- struct bt_trace_handle *handle, enum bt_clock_type type);
+int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor,
+ struct bt_trace_handle *handle, enum bt_clock_type type,
+ int64_t *timestamp);
static
-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor,
- struct bt_trace_handle *handle, enum bt_clock_type type);
+int ctf_timestamp_end(struct bt_trace_descriptor *descriptor,
+ struct bt_trace_handle *handle, enum bt_clock_type type,
+ int64_t *timestamp);
static
int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp);
};
static
-uint64_t ctf_timestamp_begin(struct bt_trace_descriptor *descriptor,
- struct bt_trace_handle *handle, enum bt_clock_type type)
+int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor,
+ struct bt_trace_handle *handle, enum bt_clock_type type,
+ int64_t *timestamp)
{
struct ctf_trace *tin;
- uint64_t begin = ULLONG_MAX;
- int i, j;
+ int64_t begin = LLONG_MAX;
+ int i, j, ret;
tin = container_of(descriptor, struct ctf_trace, parent);
- if (!tin)
+ if (!tin || !timestamp) {
+ ret = -EINVAL;
goto error;
+ }
/* for each stream_class */
for (i = 0; i < tin->streams->len; i++) {
parent);
stream_pos = &cfs->pos;
- if (!stream_pos->packet_index)
+ if (!stream_pos->packet_index) {
+ ret = -EINVAL;
goto error;
+ }
if (stream_pos->packet_index->len <= 0)
continue;
if (index->ts_cycles.timestamp_begin < begin)
begin = index->ts_cycles.timestamp_begin;
} else {
+ ret = -EINVAL;
goto error;
}
}
}
-
- return begin;
+ if (begin == LLONG_MAX) {
+ ret = -ENOENT;
+ goto error;
+ }
+ *timestamp = begin;
+ return 0;
error:
- return -1ULL;
+ return ret;
}
static
-uint64_t ctf_timestamp_end(struct bt_trace_descriptor *descriptor,
- struct bt_trace_handle *handle, enum bt_clock_type type)
+int ctf_timestamp_end(struct bt_trace_descriptor *descriptor,
+ struct bt_trace_handle *handle, enum bt_clock_type type,
+ int64_t *timestamp)
{
struct ctf_trace *tin;
- uint64_t end = 0;
- int i, j;
+ int64_t end = LLONG_MIN;
+ int i, j, ret;
tin = container_of(descriptor, struct ctf_trace, parent);
- if (!tin)
+ if (!tin || !timestamp) {
+ ret = -EINVAL;
goto error;
+ }
/* for each stream_class */
for (i = 0; i < tin->streams->len; i++) {
parent);
stream_pos = &cfs->pos;
- if (!stream_pos->packet_index)
+ if (!stream_pos->packet_index) {
+ ret = -EINVAL;
goto error;
+ }
if (stream_pos->packet_index->len <= 0)
continue;
if (index->ts_cycles.timestamp_end > end)
end = index->ts_cycles.timestamp_end;
} else {
+ ret = -EINVAL;
goto error;
}
}
}
-
- return end;
+ if (end == LLONG_MIN) {
+ ret = -ENOENT;
+ goto error;
+ }
+ *timestamp = end;
+ return 0;
error:
- return -1ULL;
+ return ret;
}
/*
static
void ctf_print_timestamp_real(FILE *fp,
struct ctf_stream_definition *stream,
- uint64_t timestamp)
+ int64_t timestamp)
{
- uint64_t ts_sec = 0, ts_nsec;
+ int64_t ts_sec = 0, ts_nsec;
+ uint64_t ts_sec_abs, ts_nsec_abs;
+ bool is_negative;
ts_nsec = timestamp;
- /* Add command-line offset in ns*/
+ /* Add command-line offset in ns */
ts_nsec += opt_clock_offset_ns;
/* Add command-line offset */
ts_sec += ts_nsec / NSEC_PER_SEC;
ts_nsec = ts_nsec % NSEC_PER_SEC;
+ if (ts_sec >= 0 && ts_nsec >= 0) {
+ is_negative = false;
+ ts_sec_abs = ts_sec;
+ ts_nsec_abs = ts_nsec;
+ } else if (ts_sec > 0 && ts_nsec < 0) {
+ is_negative = false;
+ ts_sec_abs = ts_sec - 1;
+ ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
+ } else if (ts_sec == 0 && ts_nsec < 0) {
+ is_negative = true;
+ ts_sec_abs = ts_sec;
+ ts_nsec_abs = -ts_nsec;
+ } else if (ts_sec < 0 && ts_nsec > 0) {
+ is_negative = true;
+ ts_sec_abs = -(ts_sec + 1);
+ ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
+ } else if (ts_sec < 0 && ts_nsec == 0) {
+ is_negative = true;
+ ts_sec_abs = -ts_sec;
+ ts_nsec_abs = ts_nsec;
+ } else { /* (ts_sec < 0 && ts_nsec < 0) */
+ is_negative = true;
+ ts_sec_abs = -ts_sec;
+ ts_nsec_abs = -ts_nsec;
+ }
if (!opt_clock_seconds) {
struct tm tm;
- time_t time_s = (time_t) ts_sec;
+ time_t time_s = (time_t) ts_sec_abs;
+
+ if (is_negative) {
+ fprintf(stderr, "[warning] Fallback to [sec.ns] for printing negative time value. Use --clock-seconds.\n");
+ goto seconds;
+ }
if (!opt_clock_gmt) {
struct tm *res;
}
/* Print time in HH:MM:SS.ns */
fprintf(fp, "%02d:%02d:%02d.%09" PRIu64,
- tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec);
+ tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec_abs);
goto end;
}
seconds:
- fprintf(fp, "%3" PRIu64 ".%09" PRIu64,
- ts_sec, ts_nsec);
+ fprintf(fp, "%s%" PRId64 ".%09" PRIu64,
+ is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
end:
return;
void ctf_print_timestamp(FILE *fp,
struct ctf_stream_definition *stream,
- uint64_t timestamp)
+ int64_t timestamp)
{
if (opt_clock_cycles) {
ctf_print_timestamp_cycles(fp, stream, timestamp);
#include <babeltrace/clock-internal.h>
static inline
-uint64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream,
- uint64_t timestamp)
+int64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream,
+ uint64_t ts_cycles)
{
- uint64_t ts_nsec;
+ int64_t ts_nsec;
struct ctf_trace *trace = stream->stream_class->trace;
struct trace_collection *tc = trace->parent.collection;
- uint64_t tc_offset;
+ int64_t tc_offset;
if (tc->clock_use_offset_avg)
tc_offset = tc->single_clock_offset_avg;
else
tc_offset = clock_offset_ns(trace->parent.single_clock);
- ts_nsec = clock_cycles_to_ns(stream->current_clock, timestamp);
+ ts_nsec = clock_cycles_to_ns(stream->current_clock, ts_cycles);
ts_nsec += tc_offset; /* Add offset */
return ts_nsec;
}
return ret;
}
-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event)
+int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, int64_t *timestamp)
{
const struct ctf_event_definition *event;
- if (!ctf_event)
- return -1ULL;
+ if (!ctf_event || !timestamp)
+ return -1;
event = ctf_event->parent;
if (event && event->stream->has_timestamp)
- return event->stream->real_timestamp;
+ *timestamp = event->stream->real_timestamp;
else
- return -1ULL;
+ return -1;
+ return 0;
}
uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event)
return ret;
}
-uint64_t bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock)
+int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s)
{
- uint64_t ret = -1ULL;
+ int ret = 0;
- if (!clock) {
+ if (!clock || !offset_s) {
+ ret = -1;
goto end;
}
- ret = clock->offset_s;
+ *offset_s = clock->offset_s;
end:
return ret;
}
-int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, uint64_t offset_s)
+int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s)
{
int ret = 0;
return ret;
}
-uint64_t bt_ctf_clock_get_offset(struct bt_ctf_clock *clock)
+int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset)
{
- uint64_t ret = -1ULL;
+ int ret = 0;
- if (!clock) {
+ if (!clock || !offset) {
+ ret = -1;
goto end;
}
- ret = clock->offset;
+ *offset = clock->offset;
end:
return ret;
}
-int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, uint64_t offset)
+int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset)
{
int ret = 0;
return ret;
}
-uint64_t bt_ctf_clock_get_time(struct bt_ctf_clock *clock)
+int bt_ctf_clock_get_time(struct bt_ctf_clock *clock, int64_t *time)
{
- uint64_t ret = -1ULL;
+ int ret = 0;
- if (!clock) {
+ if (!clock || !time) {
+ ret = -1;
goto end;
}
- ret = clock->time;
+ *time = clock->time;
end:
return ret;
}
-int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, uint64_t time)
+int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time)
{
int ret = 0;
timestamp_field_type);
bt_put(timestamp_field_type);
if (mapped_clock) {
- uint64_t timestamp = bt_ctf_clock_get_time(
- mapped_clock);
+ int64_t timestamp;
+ ret = bt_ctf_clock_get_time(mapped_clock, ×tamp);
bt_put(mapped_clock);
- if (timestamp == (uint64_t) -1ULL) {
+ if (ret) {
goto end;
}
ret = -EPERM;
goto error;
}
- ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset_s);
+ ret = get_unary_signed(&node->u.ctf_expression.right, &clock->offset_s);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
ret = -EINVAL;
ret = -EPERM;
goto error;
}
- ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset);
+ ret = get_unary_signed(&node->u.ctf_expression.right, &clock->offset);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
ret = -EINVAL;
GPtrArray *array; /* struct bt_trace_descriptor */
GHashTable *clocks; /* struct ctf_clock */
- uint64_t single_clock_offset_avg;
- uint64_t offset_first;
+ int64_t single_clock_offset_avg;
+ int64_t offset_first;
int64_t delta_offset_first_sum;
int offset_nr;
int clock_use_offset_avg;
opt_clock_gmt,
opt_clock_force_correlate;
-extern uint64_t opt_clock_offset;
-extern uint64_t opt_clock_offset_ns;
+extern int64_t opt_clock_offset;
+extern int64_t opt_clock_offset_ns;
extern int babeltrace_ctf_console_output;
#endif
* is recommended to express the seconds in offset_s, otherwise there
* will be a loss of precision caused by the limited size of the double
* mantissa.
+ * This offset can be negative.
*/
static inline
-uint64_t clock_offset_ns(struct ctf_clock *clock)
+int64_t clock_offset_ns(struct ctf_clock *clock)
{
return clock->offset_s * 1000000000ULL
+ clock_cycles_to_ns(clock, clock->offset);
GString *description;
uint64_t frequency;
uint64_t precision;
- uint64_t offset_s; /* Offset in seconds */
- uint64_t offset; /* Offset in ticks */
- uint64_t time; /* Current clock value */
+ int64_t offset_s; /* Offset in seconds */
+ int64_t offset; /* Offset in ticks */
+ int64_t time; /* Current clock value */
uuid_t uuid;
int uuid_set;
int absolute;
* Get the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01.
*
* @param clock Clock instance.
+ * @param offset_s Pointer to clock offset in seconds (output).
*
- * Returns the clock's offset in seconds, -1ULL on error.
+ * Returns 0 on success, a negative value on error.
*/
-extern uint64_t bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock);
+extern int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock,
+ int64_t *offset_s);
/*
* bt_ctf_clock_set_offset_s: set a clock's offset in seconds.
* Returns 0 on success, a negative value on error.
*/
extern int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock,
- uint64_t offset_s);
+ int64_t offset_s);
/*
* bt_ctf_clock_get_offset: get a clock's offset in ticks.
* Get the clock's offset in ticks from Epoch + offset_t.
*
* @param clock Clock instance.
+ * @param offset Clock offset in ticks from Epoch + offset_s (output).
*
- * Returns the clock's offset in ticks from Epoch + offset_s, -1ULL on error.
+ * Returns 0 on success, a negative value on error.
*/
-extern uint64_t bt_ctf_clock_get_offset(struct bt_ctf_clock *clock);
+extern int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock,
+ int64_t *offset);
/*
* bt_ctf_clock_set_offset: set a clock's offset in ticks.
* Returns 0 on success, a negative value on error.
*/
extern int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock,
- uint64_t offset);
+ int64_t offset);
/*
* bt_ctf_clock_get_is_absolute: get a clock's absolute attribute.
* Get the current time in nanoseconds since the clock's origin (offset and
* offset_s attributes).
*
- * Returns the clock's current time value, -1ULL on error.
+ * @param clock Clock instance.
+ * @param time Clock current time value (output).
+ *
+ * Returns 0 on success, a negative value on error.
*/
-extern uint64_t bt_ctf_clock_get_time(struct bt_ctf_clock *clock);
+extern int bt_ctf_clock_get_time(struct bt_ctf_clock *clock,
+ int64_t *time);
/*
* bt_ctf_clock_set_time: set a clock's current time value.
* Returns 0 on success, a negative value on error.
*/
extern int bt_ctf_clock_set_time(struct bt_ctf_clock *clock,
- uint64_t time);
+ int64_t time);
/*
* bt_ctf_clock_get and bt_ctf_clock_put: increment and decrement the
/*
* The offset from Epoch is: offset_s + (offset * (1/freq))
* Coarse clock offset from Epoch (in seconds).
+ * It can be negative.
*/
- uint64_t offset_s;
- /* Fine clock offset from Epoch, in (1/freq) units. */
- uint64_t offset;
+ int64_t offset_s;
+ /*
+ * Fine clock offset from Epoch, in (1/freq) units.
+ * It can be negative.
+ */
+ int64_t offset;
int absolute;
enum { /* Fields populated mask */
uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *event);
/*
- * bt_ctf_get_timestamp: returns the timestamp of the event offsetted
- * with the system clock source (in ns) or -1ULL on error
+ * bt_ctf_get_timestamp: get the timestamp of the event offsetted
+ * with the system clock source (in ns) in *timestamp.
+ *
+ * Return 0 on success, or -1ULL on error.
*/
-uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event);
+int bt_ctf_get_timestamp(const struct bt_ctf_event *event, int64_t *timestamp);
/*
* bt_ctf_get_field_list: obtain the list of fields for compound type
struct bt_stream_callbacks;
struct packet_index_time {
- uint64_t timestamp_begin;
- uint64_t timestamp_end;
+ int64_t timestamp_begin;
+ int64_t timestamp_end;
};
struct packet_index {
}
void ctf_print_timestamp(FILE *fp, struct ctf_stream_definition *stream,
- uint64_t timestamp);
+ int64_t timestamp);
int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp,
FILE *metadata_fp);
struct bt_context *ctx);
void (*set_handle)(struct bt_trace_descriptor *descriptor,
struct bt_trace_handle *handle);
- uint64_t (*timestamp_begin)(struct bt_trace_descriptor *descriptor,
- struct bt_trace_handle *handle, enum bt_clock_type type);
- uint64_t (*timestamp_end)(struct bt_trace_descriptor *descriptor,
- struct bt_trace_handle *handle, enum bt_clock_type type);
+ int (*timestamp_begin)(struct bt_trace_descriptor *descriptor,
+ struct bt_trace_handle *handle, enum bt_clock_type type,
+ int64_t *timestamp);
+ int (*timestamp_end)(struct bt_trace_descriptor *descriptor,
+ struct bt_trace_handle *handle, enum bt_clock_type type,
+ int64_t *timestamp);
int (*convert_index_timestamp)(struct bt_trace_descriptor *descriptor);
};
struct bt_trace_descriptor *td;
struct bt_format *format;
char path[PATH_MAX];
- uint64_t real_timestamp_begin;
- uint64_t real_timestamp_end;
- uint64_t cycles_timestamp_begin;
- uint64_t cycles_timestamp_end;
+ int64_t real_timestamp_begin;
+ int64_t real_timestamp_end;
+ int64_t cycles_timestamp_begin;
+ int64_t cycles_timestamp_end;
};
/*
const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id);
/*
- * bt_trace_handle_get_timestamp_begin : returns the creation time (in
- * nanoseconds or cycles depending on type) of the buffers of a trace
- * or -1ULL on error.
+ * bt_trace_handle_get_timestamp_begin : get the creation time (in
+ * nanoseconds or cycles depending on type) of the buffers of a trace.
+ *
+ * Returns 0 on success, -1 on error.
*/
-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
- int handle_id, enum bt_clock_type type);
+int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
+ int handle_id, enum bt_clock_type type,
+ int64_t *timestamp);
/*
- * bt_trace_handle_get_timestamp_end : returns the destruction timestamp
- * (in nanoseconds or cycles depending on type) of the buffers of a trace
- * or -1ULL on error.
+ * bt_trace_handle_get_timestamp_end : get the destruction time
+ * (in nanoseconds or cycles depending on type) of the buffers of a
+ * trace.
+ *
+ * Returns 0 on success, -1 on error.
*/
-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
- int handle_id, enum bt_clock_type type);
+int bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
+ int handle_id, enum bt_clock_type type,
+ int64_t *timestamp);
/*
* bt_ctf_event_get_handle_id : get the handle id associated with an event
fprintf(stderr, "[error] [Context] Creating trace handle %s .\n\n",
path);
ret = -1;
- goto error;
+ goto error_close;
}
handle->format = fmt;
handle->td = td;
handle->path[PATH_MAX - 1] = '\0';
}
+ ret = bt_trace_collection_add(ctx->tc, td);
+ if (ret != 0)
+ goto error_destroy_handle;
+
if (fmt->set_handle)
fmt->set_handle(td, handle);
if (fmt->set_context)
fmt->set_context(td, ctx);
- /* Add new handle to container */
- g_hash_table_insert(ctx->trace_handles,
- (gpointer) (unsigned long) handle->id,
- handle);
- ret = bt_trace_collection_add(ctx->tc, td);
- if (ret != 0)
- goto error;
-
if (fmt->convert_index_timestamp) {
ret = fmt->convert_index_timestamp(td);
if (ret < 0)
- goto error;
+ goto error_collection_del;
+ }
+
+ if (fmt->timestamp_begin) {
+ ret = fmt->timestamp_begin(td, handle, BT_CLOCK_REAL,
+ &handle->real_timestamp_begin);
+ if (ret < 0 && ret != -ENOENT) {
+ ret = -1;
+ goto error_collection_del;
+ }
+ }
+ if (fmt->timestamp_end) {
+ ret = fmt->timestamp_end(td, handle, BT_CLOCK_REAL,
+ &handle->real_timestamp_end);
+ if (ret < 0 && ret != -ENOENT) {
+ ret = -1;
+ goto error_collection_del;
+ }
+ }
+ if (fmt->timestamp_begin) {
+ ret = fmt->timestamp_begin(td, handle, BT_CLOCK_CYCLES,
+ &handle->cycles_timestamp_begin);
+ if (ret < 0 && ret != -ENOENT) {
+ ret = -1;
+ goto error_collection_del;
+ }
+ }
+ if (fmt->timestamp_end) {
+ ret = fmt->timestamp_end(td, handle, BT_CLOCK_CYCLES,
+ &handle->cycles_timestamp_end);
+ if (ret < 0 && ret != -ENOENT) {
+ ret = -1;
+ goto error_collection_del;
+ }
}
- if (fmt->timestamp_begin)
- handle->real_timestamp_begin = fmt->timestamp_begin(td,
- handle, BT_CLOCK_REAL);
- if (fmt->timestamp_end)
- handle->real_timestamp_end = fmt->timestamp_end(td, handle,
- BT_CLOCK_REAL);
- if (fmt->timestamp_begin)
- handle->cycles_timestamp_begin = fmt->timestamp_begin(td,
- handle, BT_CLOCK_CYCLES);
- if (fmt->timestamp_end)
- handle->cycles_timestamp_end = fmt->timestamp_end(td, handle,
- BT_CLOCK_CYCLES);
+ /* Add new handle to container */
+ g_hash_table_insert(ctx->trace_handles,
+ (gpointer) (unsigned long) handle->id,
+ handle);
return handle->id;
-error:
+error_collection_del:
+ /* Remove from containers */
+ bt_trace_collection_remove(handle->td->ctx->tc, handle->td);
+error_destroy_handle:
+ bt_trace_handle_destroy(handle);
+error_close:
closeret = fmt->close_trace(td);
if (closeret) {
fprintf(stderr, "Error in close_trace callback\n");
return handle->path;
}
-uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
- int handle_id, enum bt_clock_type type)
+int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
+ int handle_id, enum bt_clock_type type,
+ int64_t *timestamp)
{
struct bt_trace_handle *handle;
- uint64_t ret;
+ int ret = 0;
- if (!ctx)
- return -1ULL;
+ if (!ctx || !timestamp)
+ return -1;
handle = g_hash_table_lookup(ctx->trace_handles,
(gpointer) (unsigned long) handle_id);
if (!handle) {
- ret = -1ULL;
+ ret = -1;
goto end;
}
if (type == BT_CLOCK_REAL) {
- ret = handle->real_timestamp_begin;
+ *timestamp = handle->real_timestamp_begin;
} else if (type == BT_CLOCK_CYCLES) {
- ret = handle->cycles_timestamp_begin;
+ *timestamp = handle->cycles_timestamp_begin;
} else {
- ret = -1ULL;
+ ret = -1;
}
end:
return ret;
}
-uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
- int handle_id, enum bt_clock_type type)
+int bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
+ int handle_id, enum bt_clock_type type,
+ int64_t *timestamp)
{
struct bt_trace_handle *handle;
- uint64_t ret;
+ int ret = 0;
- if (!ctx)
- return -1ULL;
+ if (!ctx || !timestamp)
+ return -1;
handle = g_hash_table_lookup(ctx->trace_handles,
(gpointer) (unsigned long) handle_id);
if (!handle) {
- ret = -1ULL;
+ ret = -1;
goto end;
}
if (type == BT_CLOCK_REAL) {
- ret = handle->real_timestamp_end;
+ *timestamp = handle->real_timestamp_end;
} else if (type == BT_CLOCK_CYCLES) {
- ret = handle->cycles_timestamp_end;
+ *timestamp = handle->cycles_timestamp_end;
} else {
- ret = -1ULL;
+ ret = -1;
}
end:
#define DEFAULT_CLOCK_IS_ABSOLUTE 0
#define DEFAULT_CLOCK_TIME 0
-#define NR_TESTS 588
+#define NR_TESTS 597
-static uint64_t current_time = 42;
+static int64_t current_time = 42;
/* Return 1 if uuids match, zero if different. */
int uuid_match(const unsigned char *uuid_a, const unsigned char *uuid_b)
const char *returned_clock_name;
const char *returned_clock_description;
const uint64_t frequency = 1123456789;
- const uint64_t offset_s = 1351530929945824323;
- const uint64_t offset = 1234567;
+ const int64_t offset_s = 1351530929945824323;
+ const int64_t offset = 1234567;
+ int64_t get_offset_s,
+ get_offset,
+ get_time;
const uint64_t precision = 10;
const int is_absolute = 0xFF;
char *metadata_string;
ok(bt_ctf_clock_get_frequency(clock) == frequency,
"bt_ctf_clock_get_frequency returns the correct frequency once it is set");
- ok(bt_ctf_clock_get_offset_s(clock) == DEFAULT_CLOCK_OFFSET_S,
+ ok(bt_ctf_clock_get_offset_s(clock, &get_offset_s) == 0,
+ "bt_ctf_clock_get_offset_s succeeds");
+ ok(get_offset_s == DEFAULT_CLOCK_OFFSET_S,
"bt_ctf_clock_get_offset_s returns the correct default offset (in seconds)");
ok(bt_ctf_clock_set_offset_s(clock, offset_s) == 0,
"Set clock offset (seconds)");
- ok(bt_ctf_clock_get_offset_s(clock) == offset_s,
+ ok(bt_ctf_clock_get_offset_s(clock, &get_offset_s) == 0,
+ "bt_ctf_clock_get_offset_s succeeds");
+ ok(get_offset_s == offset_s,
"bt_ctf_clock_get_offset_s returns the correct default offset (in seconds) once it is set");
- ok(bt_ctf_clock_get_offset(clock) == DEFAULT_CLOCK_OFFSET,
- "bt_ctf_clock_get_frequency returns the correct default offset (in ticks)");
+ ok(bt_ctf_clock_get_offset(clock, &get_offset) == 0,
+ "bt_ctf_clock_get_offset succeeds");
+ ok(get_offset == DEFAULT_CLOCK_OFFSET,
+ "bt_ctf_clock_get_offset returns the correct default offset (in ticks)");
ok(bt_ctf_clock_set_offset(clock, offset) == 0, "Set clock offset");
- ok(bt_ctf_clock_get_offset(clock) == offset,
- "bt_ctf_clock_get_frequency returns the correct default offset (in ticks) once it is set");
+ ok(bt_ctf_clock_get_offset(clock, &get_offset) == 0,
+ "bt_ctf_clock_get_offset succeeds");
+ ok(get_offset == offset,
+ "bt_ctf_clock_get_offset returns the correct default offset (in ticks) once it is set");
ok(bt_ctf_clock_get_precision(clock) == DEFAULT_CLOCK_PRECISION,
"bt_ctf_clock_get_precision returns the correct default precision");
ok(bt_ctf_clock_get_is_absolute(clock) == !!is_absolute,
"bt_ctf_clock_get_precision returns the correct is_absolute attribute once it is set");
- ok(bt_ctf_clock_get_time(clock) == DEFAULT_CLOCK_TIME,
+ ok(bt_ctf_clock_get_time(clock, &get_time) == 0,
+ "bt_ctf_clock_get_time succeeds");
+ ok(get_time == DEFAULT_CLOCK_TIME,
"bt_ctf_clock_get_time returns the correct default time");
ok(bt_ctf_clock_set_time(clock, current_time) == 0,
"Set clock time");
- ok(bt_ctf_clock_get_time(clock) == current_time,
+ ok(bt_ctf_clock_get_time(clock, &get_time) == 0,
+ "bt_ctf_clock_get_time succeeds");
+ ok(get_time == current_time,
"bt_ctf_clock_get_time returns the correct time once it is set");
ok(bt_ctf_writer_add_clock(writer, clock) == 0,
"bt_ctf_clock_get_frequency correctly handles NULL");
ok(bt_ctf_clock_get_precision(NULL) == -1ULL,
"bt_ctf_clock_get_precision correctly handles NULL");
- ok(bt_ctf_clock_get_offset_s(NULL) == -1ULL,
- "bt_ctf_clock_get_offset_s correctly handles NULL");
- ok(bt_ctf_clock_get_offset(NULL) == -1ULL,
- "bt_ctf_clock_get_offset correctly handles NULL");
+ ok(bt_ctf_clock_get_offset_s(NULL, &get_offset_s) < 0,
+ "bt_ctf_clock_get_offset_s correctly handles NULL clock");
+ ok(bt_ctf_clock_get_offset_s(clock, NULL) < 0,
+ "bt_ctf_clock_get_offset_s correctly handles NULL output");
+ ok(bt_ctf_clock_get_offset(NULL, &get_offset) < 0,
+ "bt_ctf_clock_get_offset correctly handles NULL clock");
+ ok(bt_ctf_clock_get_offset(clock, NULL) < 0,
+ "bt_ctf_clock_get_offset correctly handles NULL output");
ok(bt_ctf_clock_get_is_absolute(NULL) < 0,
"bt_ctf_clock_get_is_absolute correctly handles NULL");
- ok(bt_ctf_clock_get_time(NULL) == -1ULL,
- "bt_ctf_clock_get_time correctly handles NULL");
+ ok(bt_ctf_clock_get_time(NULL, &get_time) < 0,
+ "bt_ctf_clock_get_time correctly handles NULL clock");
+ ok(bt_ctf_clock_get_time(clock, NULL) < 0,
+ "bt_ctf_clock_get_time correctly handles NULL output");
ok(bt_ctf_clock_set_description(NULL, NULL) < 0,
"bt_ctf_clock_set_description correctly handles NULL clock");
#include <tap/tap.h>
#include "common.h"
-#define NR_TESTS 29
+#define NR_TESTS 36
void run_seek_begin(char *path, uint64_t expected_begin)
{
struct bt_ctf_event *event;
struct bt_iter_pos newpos;
int ret;
- uint64_t timestamp_begin;
- uint64_t timestamp_seek_begin;
+ int64_t timestamp_begin;
+ int64_t timestamp_seek_begin;
/* Open the trace */
ctx = create_context_with_path(path);
ok(event, "Event valid");
/* Validate that the first timestamp is right */
- timestamp_begin = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp_begin) == 0);
ok1(timestamp_begin == expected_begin);
ok(event, "Event valid");
- timestamp_seek_begin = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp_seek_begin) == 0);
ok1(timestamp_begin == timestamp_seek_begin);
struct bt_ctf_event *event;
struct bt_iter_pos newpos;
int ret;
- uint64_t timestamp_last;
+ int64_t timestamp_last;
/* Open the trace */
ctx = create_context_with_path(path);
ok(event, "Event valid at last position");
- timestamp_last = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0);
ok1(timestamp_last == expected_last);
struct bt_ctf_event *event;
struct bt_iter_pos newpos;
int ret;
- uint64_t timestamp_last;
+ int64_t timestamp_last;
/* Open the trace */
ctx = create_context_with_path(path);
ok(event, "Event valid at last position");
- timestamp_last = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp_last) == 0);
ok1(timestamp_last == expected_last);
struct bt_ctf_event *event;
struct bt_iter_pos newpos;
int ret;
- uint64_t timestamp;
+ int64_t timestamp;
/* Open the trace */
ctx = create_context_with_path(path);
ok(event, "Event valid at last position");
- timestamp = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0);
ok1(timestamp == expected_last);
ok(event, "Event valid at first position");
- timestamp = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0);
ok1(timestamp == expected_begin);
ok(event, "Event valid at last position");
- timestamp = bt_ctf_get_timestamp(event);
+ ok1(bt_ctf_get_timestamp(event, ×tamp) == 0);
ok1(timestamp == expected_last);