ir: add stream ID API
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 24 May 2017 00:43:00 +0000 (20:43 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:44 +0000 (12:57 -0400)
The new bt_ctf_stream_create_with_id() function creates a stream object,
just like bt_ctf_stream_create(), but with a numeric ID. You cannot
call this function to create a CTF writer stream because CTF writer
streams initialize their own unique ID.

Use bt_ctf_stream_get_id() to get a stream's ID.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/ctf-ir/stream-internal.h
include/babeltrace/ctf-ir/stream.h
lib/ctf-ir/stream.c

index 0b844b8a23015502896114926e57b7be3c4d36e2..87395b107f37f609a9231401856e3261ced9ab0b 100644 (file)
@@ -49,7 +49,7 @@ struct bt_ctf_stream_destroy_listener {
 
 struct bt_ctf_stream {
        struct bt_object base;
-       uint32_t id;
+       int64_t id;
        struct bt_ctf_stream_class *stream_class;
        GString *name;
        struct bt_ctf_field *packet_header;
index 510f17dc2ea5bda13a61338553679b31dac73686..140970c5aed86924216a7da48c52d64b9009b625 100644 (file)
@@ -55,8 +55,9 @@ A CTF IR <strong><em>stream</em></strong> is an instance of a
 
 You can obtain a CTF IR stream object in two different modes:
 
-- <strong>Normal mode</strong>: use bt_ctf_stream_create() with a stream
-  class having a \link ctfirtraceclass CTF IR trace class\endlink parent
+- <strong>Normal mode</strong>: use bt_ctf_stream_create() or
+  bt_ctf_stream_create_with_id() with a stream class having a
+  \link ctfirtraceclass CTF IR trace class\endlink parent
   \em not created by a \link ctfwriter CTF writer\endlink object to
   create a default stream.
 - <strong>CTF writer mode</strong>: use bt_ctf_stream_create() with
@@ -123,11 +124,48 @@ functions documented in this module on it.
 @prenotnull{stream_class}
 @pre \p stream_class has a parent trace class.
 @postsuccessrefcountret1
+
+@sa bt_ctf_stream_create_with_id(): Create a CTF IR stream with a
+       specific ID.
 */
 extern struct bt_ctf_stream *bt_ctf_stream_create(
                struct bt_ctf_stream_class *stream_class,
                const char *name);
 
+/**
+@brief  Creates a default CTF IR stream named \p name with ID \p id
+       from the CTF IR stream class \p stream_class.
+
+\p stream_class \em must have a parent
+\link ctfirtraceclass CTF IR trace class\endlink.
+
+You \em must have created the trace class of \p stream class directly
+with bt_ctf_trace_create(), not through bt_ctf_writer_create() (use
+bt_ctf_stream_create() for this).
+
+\p id \em must be unique amongst the IDs of all the streams created
+from \p stream_class with bt_ctf_stream_create_with_id().
+
+\p name can be \c NULL to create an unnamed stream object.
+
+@param[in] stream_class        CTF IR stream class to use to create the
+                       CTF IR stream.
+@param[in] name                Name of the stream object to create (copied on
+                       success) or \c NULL to create an unnamed stream.
+@param[in] id          ID of the stream object to create.
+@returns               Created stream object, or \c NULL on error.
+
+@prenotnull{stream_class}
+@pre \p id is lesser than or equal to 9223372036854775807 (\c INT64_MAX).
+@pre \p stream_class has a parent trace class.
+@postsuccessrefcountret1
+
+@sa bt_ctf_stream_create(): Create a CTF IR stream without an ID.
+*/
+extern struct bt_ctf_stream *bt_ctf_stream_create_with_id(
+               struct bt_ctf_stream_class *stream_class,
+               const char *name, uint64_t id);
+
 /**
 @brief Returns the name of the CTF IR stream \p stream.
 
@@ -142,6 +180,18 @@ On success, \p stream remains the sole owner of the returned string.
 */
 extern const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream);
 
+/**
+@brief Returns the numeric ID of the CTF IR stream \p stream.
+
+@param[in] stream      Stream of which to get the numeric ID.
+@returns               ID of stream \p stream, or a negative value
+                       on error.
+
+@prenotnull{stream}
+@postrefcountsame{stream}
+*/
+extern int64_t bt_ctf_stream_get_id(struct bt_ctf_stream *stream);
+
 /**
 @brief Returns the parent CTF IR stream class of the CTF IR
        stream \p stream.
index 402597edd3e1e1905e66c910ca8e1a87e76a934b..3ff937ac4118e7a29e7153d341364c3b7d835619 100644 (file)
@@ -658,7 +658,7 @@ int create_stream_file(struct bt_ctf_writer *writer,
                g_string_printf(filename, "stream_%" PRId64, ret);
        }
 
-       g_string_append_printf(filename, "_%" PRIu32, stream->id);
+       g_string_append_printf(filename, "_%" PRId64, stream->id);
        fd = openat(writer->trace_dir_fd, filename->str,
                O_RDWR | O_CREAT | O_TRUNC,
                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
@@ -697,9 +697,10 @@ void component_destroy_listener(struct bt_component *component, void *data)
        g_hash_table_remove(stream->comp_cur_port, component);
 }
 
-struct bt_ctf_stream *bt_ctf_stream_create(
+static
+struct bt_ctf_stream *bt_ctf_stream_create_with_id_no_check(
                struct bt_ctf_stream_class *stream_class,
-               const char *name)
+               const char *name, uint64_t id)
 {
        int ret;
        struct bt_ctf_stream *stream = NULL;
@@ -712,10 +713,11 @@ struct bt_ctf_stream *bt_ctf_stream_create(
        }
 
        BT_LOGD("Creating stream object: stream-class-addr=%p, "
-               "stream-class-name=\"%s\", stream-name=\"%s\"",
+               "stream-class-name=\"%s\", stream-name=\"%s\", "
+               "stream-id=%" PRIu64,
                stream_class, bt_ctf_stream_class_get_name(stream_class),
-               name);
-       trace = bt_ctf_stream_class_get_trace(stream_class);
+               name, id);
+       trace = bt_ctf_stream_class_borrow_trace(stream_class);
        if (!trace) {
                BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
                        "stream-class-addr=%p, stream-class-name=\"%s\", "
@@ -739,6 +741,29 @@ struct bt_ctf_stream *bt_ctf_stream_create(
                goto error;
        }
 
+       if (id != -1ULL) {
+               /*
+                * Validate that the given ID is unique amongst all the
+                * existing trace's streams created from the same stream
+                * class.
+                */
+               size_t i;
+
+               for (i = 0; i < trace->streams->len; i++) {
+                       struct bt_ctf_stream *trace_stream =
+                               g_ptr_array_index(trace->streams, i);
+
+                       if (trace_stream->stream_class != stream_class) {
+                               continue;
+                       }
+
+                       if (trace_stream->id == id) {
+                               BT_LOGW_STR("Invalid parameter: another stream in the same trace already has this ID.");
+                               goto error;
+                       }
+               }
+       }
+
        stream = g_new0(struct bt_ctf_stream, 1);
        if (!stream) {
                BT_LOGE_STR("Failed to allocate one stream.");
@@ -751,9 +776,9 @@ struct bt_ctf_stream *bt_ctf_stream_create(
         * reachable; it needs its parent to remain valid.
         */
        bt_object_set_parent(stream, trace);
-       stream->id = stream_class->next_stream_id++;
        stream->stream_class = stream_class;
        stream->pos.fd = -1;
+       stream->id = (int64_t) id;
 
        stream->destroy_listeners = g_array_new(FALSE, TRUE,
                sizeof(struct bt_ctf_stream_destroy_listener));
@@ -774,8 +799,8 @@ struct bt_ctf_stream *bt_ctf_stream_create(
 
        if (trace->is_created_by_writer) {
                int fd;
-               writer = (struct bt_ctf_writer *)
-                       bt_object_get_parent(trace);
+               writer = (struct bt_ctf_writer *) bt_object_get_parent(trace);
+               stream->id = (int64_t) stream_class->next_stream_id++;
 
                BT_LOGD("Stream object belongs to a writer's trace: "
                        "writer-addr=%p", writer);
@@ -859,18 +884,71 @@ struct bt_ctf_stream *bt_ctf_stream_create(
 
        /* Add this stream to the trace's streams */
        g_ptr_array_add(trace->streams, stream);
-
-       BT_PUT(trace);
-       BT_PUT(writer);
        BT_LOGD("Created stream object: addr=%p", stream);
-       return stream;
+       goto end;
+
 error:
        BT_PUT(stream);
-       BT_PUT(trace);
-       BT_PUT(writer);
+
+end:
+       bt_put(writer);
+       return stream;
+}
+
+struct bt_ctf_stream *bt_ctf_stream_create_with_id(
+               struct bt_ctf_stream_class *stream_class,
+               const char *name, uint64_t id_param)
+{
+       struct bt_ctf_trace *trace;
+       struct bt_ctf_stream *stream = NULL;
+       int64_t id = (int64_t) id_param;
+
+       if (!stream_class) {
+               BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+               goto end;
+       }
+
+       if (id < 0) {
+               BT_LOGW("Invalid parameter: invalid stream's ID: "
+                       "name=\"%s\", id=%" PRIu64,
+                       name, id_param);
+               goto end;
+       }
+
+       trace = bt_ctf_stream_class_borrow_trace(stream_class);
+       if (!trace) {
+               BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
+                       "stream-class-addr=%p, stream-class-name=\"%s\", "
+                       "stream-name=\"%s\", stream-id=%" PRIu64,
+                       stream_class, bt_ctf_stream_class_get_name(stream_class),
+                       name, id_param);
+               goto end;
+       }
+
+       if (trace->is_created_by_writer) {
+               BT_LOGW("Invalid parameter: cannot create a CTF writer stream with this function; use bt_ctf_stream_create(): "
+                       "stream-class-addr=%p, stream-class-name=\"%s\", "
+                       "stream-name=\"%s\", stream-id=%" PRIu64,
+                       stream_class, bt_ctf_stream_class_get_name(stream_class),
+                       name, id_param);
+               goto end;
+       }
+
+       stream = bt_ctf_stream_create_with_id_no_check(stream_class,
+               name, id_param);
+
+end:
        return stream;
 }
 
+struct bt_ctf_stream *bt_ctf_stream_create(
+               struct bt_ctf_stream_class *stream_class,
+               const char *name)
+{
+       return bt_ctf_stream_create_with_id_no_check(stream_class,
+               name, -1ULL);
+}
+
 struct bt_ctf_stream_class *bt_ctf_stream_get_class(
                struct bt_ctf_stream *stream)
 {
@@ -1838,3 +1916,23 @@ void bt_ctf_stream_remove_destroy_listener(struct bt_ctf_stream *stream,
                }
        }
 }
+
+int64_t bt_ctf_stream_get_id(struct bt_ctf_stream *stream)
+{
+       int64_t ret;
+
+       if (!stream) {
+               BT_LOGW_STR("Invalid parameter: stream is NULL.");
+               ret = (int64_t) -1;
+               goto end;
+       }
+
+       ret = stream->id;
+       if (ret < 0) {
+               BT_LOGV("Stream's ID is not set: addr=%p, name=\"%s\"",
+                       stream, bt_ctf_stream_get_name(stream));
+       }
+
+end:
+       return ret;
+}
This page took 0.028423 seconds and 4 git commands to generate.