lib: add new clock class origin API
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 23 May 2024 20:23:40 +0000 (16:23 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 4 Sep 2024 19:05:14 +0000 (15:05 -0400)
Add the new API set define the origin of clock classes.  The origin is
now defined as a (namespace, name, unique-id) tuple.

If all three tuple elements are NULL, it means the origin is unknown or
undefined.  Otherwise, the origin is defined, and the name and unique-id
be non-NULL (namespace may be NULL).  There is one well-known origin,
the UNIX epoch, which is represented with the tuple
("babeltrace.org,2020", "unix-epoch", "").

The new API functions are (the numbers in square brackets represent the
MIP versions where these functions are allowed):

 - bt_clock_class_set_origin_unknown [0, 1]
 - bt_clock_class_set_origin_unix_epoch [0, 1]
 - bt_clock_class_set_origin [1]
 - bt_clock_class_get_origin_namespace [1]
 - bt_clock_class_get_origin_name [1]
 - bt_clock_class_get_origin_uid [1]

The existing function bt_clock_class_set_origin_is_unix_epoch (which
accepts a boolean) can still be used with MIP 1.  If passed true, it is
equivalent to bt_clock_class_set_origin_unix_epoch.  If passed false, it
is equivalent to bt_clock_class_set_origin_unknown.

The existing function bt_clock_class_origin_is_unix_epoch can still be
used with MIP 1.

Implementation-wise, replace the origin_is_unix_epoch boolean in struct
clock_class with the tuple of three strings.  The behavior of the API
for MIP 0 doesn't change, even if the underlying implementation does.
With MIP 0, the user is still restricted to set or get whether the
origin is the UNIX epoch or is unknown, and can't access the individual
components of the origin.

Philippe updated the documentation.

Change-Id: I1225b89a679952e877583ec8147008928a16eb45
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/12677
Tested-by: jenkins <jenkins@lttng.org>
doc/api/libbabeltrace2/Doxyfile.in
include/babeltrace2/trace-ir/clock-class.h
src/lib/assert-cond.h
src/lib/lib-logging.c
src/lib/trace-ir/clock-class.c
src/lib/trace-ir/clock-class.h

index 293ed439dc9ee228ffd0b58db74987711229532b..12e11382bc86514758d0654bcd7c2805f96ae4c1 100644 (file)
@@ -123,6 +123,7 @@ ALIASES                += bt_pre_is_se_msg{1}="@pre \bt_p{\1} is a \link api-msg
 ALIASES                += bt_pre_tc_with_mip{2}="@pre \bt_p{\1} was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version&nbsp;\2."
 ALIASES                += bt_pre_fc_with_mip{2}="@pre \bt_p{\1} was created from a \bt_trace_cls which was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version&nbsp;\2."
 ALIASES                += bt_pre_trace_with_mip{2}="@pre The \link api-tir-trace-cls class\endlink of \bt_p{\1} was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version&nbsp;\2."
+ALIASES                += bt_pre_clock_cls_with_mip{2}="@pre \bt_p{\1} was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version&nbsp;\2."
 
 # Aliases: field class object types: singular
 ALIASES                += bt_fc="\link api-tir-fc field class\endlink"
index a54e8b8986ec35d8c81efc551762ba67c14b8c32..c7f25fdb5b5eeeec0d9679a5ed4b03639eb8cfbf 100644 (file)
@@ -33,8 +33,8 @@ clocks.
 
 A clock class is a \ref api-tir "trace IR" metadata object.
 
-<em>Stream clocks</em> only exist conceptually in \bt_name because they
-are stateful objects. \bt_cp_msg cannot refer to stateful objects
+<em>Stream clocks</em> only exist conceptually in \bt_name because
+they're stateful objects. \bt_cp_msg cannot refer to stateful objects
 because they must not change while being transported from one
 \bt_comp to the other.
 
@@ -48,9 +48,12 @@ In the illustration above, notice that:
 
 - \bt_cp_stream (horizontal blue rectangles) are instances of a
   \bt_stream_cls (orange).
+
 - A stream class has a default clock class (orange bell alarm clock).
+
 - Each stream has a default clock (yellow bell alarm clock): this is an
   instance of the stream's class's default clock class.
+
 - Each \bt_msg (objects in blue stream rectangles) created for a given
   stream has a default \bt_cs (yellow star): this is a snapshot of the
   stream's default clock.
@@ -76,52 +79,69 @@ The type of a clock class is #bt_clock_class.
 Create a default clock class from a \bt_self_comp with
 bt_clock_class_create().
 
-<h1>\anchor api-tir-clock-cls-origin Clock value vs. clock class origin</h1>
+<h1>\anchor api-tir-clock-cls-origin Clock value vs. clock origin</h1>
 
 The value of a \bt_stream clock (a conceptual instance of a clock class)
 is in <em>cycles</em>. This value is always positive and is relative to
-the clock's class's offset, which is relative to its origin.
+the clock's offset, which is itself relative to its origin.
 
-A clock class's origin is one of:
+A clock's origin is one of, depending on its class:
 
 <dl>
+  <dt>If bt_clock_class_origin_is_unknown() returns #BT_TRUE</dt>
+  <dd>
+    Undefined.
+
+    Two stream clocks of which the classes have an unknown
+    origin only have a correlation if they share the same
+    \link api-tir-clock-cls-prop-iden identity\endlink.
+  </dd>
+
   <dt>If bt_clock_class_origin_is_unix_epoch() returns #BT_TRUE</dt>
   <dd>
     The
     <a href="https://en.wikipedia.org/wiki/Unix_time">Unix epoch</a>.
 
-    The stream clocks of all the clock classes which have a Unix
-    epoch origin, whatever the clock class
-    <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUIDs</a>,
-    are correlatable.
+    All stream clocks with a Unix epoch origin, whatever their
+    \link api-tir-clock-cls-prop-iden identity\endlink,
+    have a correlation.
   </dd>
 
-  <dt>If bt_clock_class_origin_is_unix_epoch() returns #BT_FALSE</dt>
+  <dt>
+    Otherwise (only available when the clock class was created
+    from a \bt_comp which belongs to a trace processing \bt_graph
+    with the effective \bt_mip version&nbsp;1)
+  </dt>
   <dd>
-    Undefined.
-
-    In that case, two clock classes which share the same UUID, as
-    returned by bt_clock_class_get_uuid(), including having no UUID,
-    also share the same origin: their instances (stream clocks) are
-    correlatable.
+    The namespace, name, and
+    <a href="https://en.wikipedia.org/wiki/Unique_identifier">unique identifier</a>
+    (UID) tuple returned by
+    bt_clock_class_get_origin_namespace(),
+    bt_clock_class_get_origin_name(), and
+    bt_clock_class_get_origin_uid().
+
+    All stream clocks with the same custom origin, whatever their
+    \link api-tir-clock-cls-prop-iden identity\endlink,
+    have a correlation.
   </dd>
 </dl>
 
-To compute an effective stream clock value, in cycles from its class's
-origin:
+To compute an effective stream clock value, in cycles from its origin:
 
--# Convert the clock class's
+-# Convert the clock's
    \link api-tir-clock-cls-prop-offset "offset in seconds"\endlink
    property to cycles using its
    \ref api-tir-clock-cls-prop-freq "frequency".
--# Add the value of 1., the stream clock's value, and the clock class's
+
+-# Add the value of step&nbsp;1, the stream clock's value,
+   and the clock's
    \link api-tir-clock-cls-prop-offset "offset in cycles"\endlink
    property.
 
 Because typical tracer clocks have a high frequency (often 1&nbsp;GHz
 and more), an effective stream clock value (cycles since Unix epoch, for
-example) can be larger than \c UINT64_MAX. This is why a clock class has
-two offset properties (one in seconds and one in cycles): to make it
+example) can be \em larger than \c UINT64_MAX. This is why a clock class
+has two offset properties (one in seconds and one in cycles): to make it
 possible for a stream clock to have smaller values, relative to this
 offset.
 
@@ -133,20 +153,22 @@ using the relevant clock class properties (frequency and offset).
 
 Those functions perform this computation:
 
--# Convert the clock class's "offset in cycles" property to seconds
-   using its frequency.
--# Convert the stream clock's value to seconds using the clock class's
+-# Convert the clock's "offset in cycles" property to seconds using its
    frequency.
--# Add the values of 1., 2., and the clock class's "offset in seconds"
-   property.
--# Convert the value of 3. to nanoseconds.
+
+-# Convert the clock's value to seconds using the clock's frequency.
+
+-# Add the values of step&nbsp;1, step&nbsp;2, and the clock's
+   "offset in seconds" property.
+
+-# Convert the value of step&nbsp;3 to nanoseconds.
 
 The following illustration shows the possible scenarios:
 
 @image html clock-terminology.png
 
-The clock class's "offset in seconds" property can be negative.
-For example, considering:
+The clock's "offset in seconds" property can be negative. For example,
+considering:
 
 - Frequency: 1000&nbsp;Hz.
 - Offset in seconds: −10&nbsp;seconds.
@@ -175,10 +197,10 @@ A clock class has the following properties:
     Offset (in seconds and in cycles)
   </dt>
   <dd>
-    Offset in seconds relative to the clock class's
-    \ref api-tir-clock-cls-origin "origin", and offset in cycles
-    relative to the offset in seconds, of the clock class's
-    instances (stream clocks).
+    Offset in seconds relative to the
+    \ref api-tir-clock-cls-origin "origin" of the clock class's
+    instances (stream clocks), and offset in cycles relative to the
+    offset in seconds.
 
     The values of the clock class's instances are relative to the
     computed offset.
@@ -200,24 +222,72 @@ A clock class has the following properties:
   </dd>
 
   <dt>
-    \anchor api-tir-clock-cls-prop-origin-unix-epoch
-    Origin is Unix epoch?
+    \anchor api-tir-clock-cls-prop-origin
+    Origin
   </dt>
   <dd>
-    Whether or not the clock class's
-    \ref api-tir-clock-cls-origin "origin"
-    is the
-    <a href="https://en.wikipedia.org/wiki/Unix_time">Unix epoch</a>.
-
-    Use bt_clock_class_set_origin_is_unix_epoch() and
-    bt_clock_class_origin_is_unix_epoch().
+    Origin of the clock class's instances (stream clocks).
+
+    Depending on the effective \bt_mip (MIP) version of the trace
+    processing \bt_graph:
+
+    <dl>
+      <dt>MIP&nbsp;0 or MIP&nbsp;1</dt>
+      <dd>
+        <dl>
+          <dt>Unknown origin</dt>
+          <dd>
+            Use bt_clock_class_set_origin_unknown() and
+            bt_clock_class_origin_is_unknown().
+          </dd>
+
+          <dt>Unix epoch origin</dt>
+          <dd>
+            Use bt_clock_class_set_origin_unix_epoch() and
+            bt_clock_class_origin_is_unix_epoch(),
+          </dd>
+        </dl>
+      </dd>
+
+      <dt>MIP&nbsp;1: custom origin</dt>
+      <dd>
+        Use bt_clock_class_set_origin(),
+        bt_clock_class_get_origin_namespace(),
+        bt_clock_class_get_origin_name(), and
+        bt_clock_class_get_origin_uid().
+      </dd>
+    </dl>
   </dd>
 
-  <dt>\anchor api-tir-clock-cls-prop-name \bt_dt_opt Name</dt>
+  <dt>\anchor api-tir-clock-cls-prop-iden \bt_dt_opt Identity</dt>
   <dd>
-    Name of the clock class.
+    Identity of the clock class's instances (stream clocks).
+
+    Depending on the effective \bt_mip (MIP) version of the trace
+    processing \bt_graph:
+
+    <dl>
+      <dt>MIP&nbsp;0</dt>
+      <dd>
+        The name and UUID property pair.
+
+        A valid identity only requires the UUID property.
 
-    Use bt_clock_class_set_name() and bt_clock_class_get_name().
+        Use bt_clock_class_set_name(), bt_clock_class_get_name(),
+        bt_clock_class_set_uuid(), and bt_clock_class_get_uuid().
+      </dd>
+
+      <dt>MIP&nbsp;1</dt>
+      <dd>
+        The namespace, name, and UID property tuple.
+
+        A valid identity only requires the name and UID properties.
+
+        Use bt_clock_class_set_namespace(), bt_clock_class_get_namespace(),
+        bt_clock_class_set_name(), bt_clock_class_get_name(),
+        bt_clock_class_set_uid(), and bt_clock_class_get_uid().
+      </dd>
+    </dl>
   </dd>
 
   <dt>\anchor api-tir-clock-cls-prop-descr \bt_dt_opt Description</dt>
@@ -228,21 +298,6 @@ A clock class has the following properties:
     bt_clock_class_get_description().
   </dd>
 
-  <dt>\anchor api-tir-clock-cls-prop-uuid \bt_dt_opt UUID</dt>
-  <dd>
-    <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a>
-    of the clock class.
-
-    The clock class's UUID uniquely identifies the clock class.
-
-    When the clock class's origin is \em not the
-    <a href="https://en.wikipedia.org/wiki/Unix_time">Unix epoch</a>,
-    then the clock class's UUID determines whether or not two different
-    clock classes have correlatable instances.
-
-    Use bt_clock_class_set_uuid() and bt_clock_class_get_uuid().
-  </dd>
-
   <dt>
     \anchor api-tir-clock-cls-prop-user-attrs
     \bt_dt_opt User attributes
@@ -302,17 +357,24 @@ On success, the returned clock class has the following property values:
     <td>\ref api-tir-clock-cls-prop-precision "Precision"
     <td>0&nbsp;cycles
   <tr>
-    <td>\ref api-tir-clock-cls-prop-origin-unix-epoch "Origin is Unix epoch?"
-    <td>Yes
+    <td>\ref api-tir-clock-cls-prop-origin "Origin"
+    <td>Unix epoch
   <tr>
-    <td>\ref api-tir-clock-cls-prop-name "Name"
-    <td>\em None
+    <td>\ref api-tir-clock-cls-prop-iden "Identity"
+    <td>
+      <em>None</em>, that is, depending on the effective \bt_mip (MIP)
+      version of the trace processing \bt_graph:
+
+      <dl>
+        <dt>MIP&nbsp;0</dt>
+        <dd>No name and no UUID</dd>
+
+        <dt>MIP&nbsp;1</dt>
+        <dd>No namespace, no name, and no UID</dd>
+      </dl>
   <tr>
     <td>\ref api-tir-clock-cls-prop-descr "Description"
     <td>\em None
-  <tr>
-    <td>\ref api-tir-clock-cls-prop-uuid "UUID"
-    <td>\em None
   <tr>
     <td>\ref api-tir-clock-cls-prop-user-attrs "User attributes"
     <td>Empty \bt_map_val
@@ -483,18 +545,31 @@ extern uint64_t bt_clock_class_get_precision(
 
 /*!
 @brief
-    Sets whether or not the \ref api-tir-clock-cls-origin "origin"
-    of the clock class \bt_p{clock_class} is the
+    Sets whether the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class} is unknown or the
     <a href="https://en.wikipedia.org/wiki/Unix_time">Unix epoch</a>.
 
-See the \ref api-tir-clock-cls-prop-origin-unix-epoch "origin is Unix epoch?"
-property.
+@deprecated
+    Use bt_clock_class_set_origin_unknown() or
+    bt_clock_class_set_origin_unix_epoch().
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
 
 @param[in] clock_class
-    Clock class of which to set whether or not its origin is the
-    Unix epoch.
+    Clock class of which to set whether its origin is unknown or
+    the Unix epoch.
 @param[in] origin_is_unix_epoch
-    #BT_TRUE to make \bt_p{clock_class} have a Unix epoch origin.
+    @parblock
+    One of:
+
+    <dl>
+      <dt>#BT_FALSE</dt>
+      <dd>Make the origin of \bt_p{clock_class} unknown.</dd>
+
+      <dt>#BT_TRUE</dt>
+      <dd>Make the origin of \bt_p{clock_class} the Unix epoch.</dd>
+    </dl>
+    @endparblock
 
 @bt_pre_not_null{clock_class}
 @bt_pre_hot{clock_class}
@@ -506,14 +581,180 @@ property.
 extern void bt_clock_class_set_origin_is_unix_epoch(bt_clock_class *clock_class,
                bt_bool origin_is_unix_epoch) __BT_NOEXCEPT;
 
+/*!
+@brief
+    Makes the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class} unknown.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@param[in] clock_class
+    Clock class of which to make the origin unknown.
+
+@bt_pre_not_null{clock_class}
+@bt_pre_hot{clock_class}
+
+@post
+    bt_clock_class_get_origin_namespace(),
+    bt_clock_class_get_origin_name(),
+    and bt_clock_class_get_origin_uid() return \c NULL.
+
+@sa bt_clock_class_set_origin_unix_epoch() &mdash;
+    Makes the origin of a clock class the Unix epoch.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
+@sa bt_clock_class_origin_is_unknown() &mdash;
+    Returns whether or not the origin of a clock class is unknown.
+*/
+extern void
+bt_clock_class_set_origin_unknown(bt_clock_class *clock_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Makes the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class} the
+    <a href="https://en.wikipedia.org/wiki/Unix_time">Unix epoch</a>.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@note
+    @parblock
+    As of \bt_name_version_min_maj, this function sets the origin
+    of the \bt_p{clock_class} to:
+
+    <dl>
+      <dt>Namespace</dt>
+      <dd><code>babeltrace.org,2020</code></dd>
+
+      <dt>Name</dt>
+      <dd><code>unix-epoch</code></dd>
+
+      <dt>UID</dt>
+      <dd>Empty string</dd>
+    </dl>
+
+    You must not rely on the specific values of this special origin.
+    @endparblock
+
+@param[in] clock_class
+    Clock class of which to make the origin the Unix epoch.
+
+@bt_pre_not_null{clock_class}
+@bt_pre_hot{clock_class}
+
+@sa bt_clock_class_set_origin_unknown() &mdash;
+    Makes the origin of a clock class unknown.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
+@sa bt_clock_class_origin_is_unix_epoch() &mdash;
+    Returns whether or not the origin of a clock class is the
+    Unix epoch.
+*/
+extern void
+bt_clock_class_set_origin_unix_epoch(bt_clock_class *clock_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Status codes for bt_clock_class_set_origin().
+*/
+typedef enum bt_clock_class_set_origin_status {
+       /*!
+       @brief
+           Success.
+       */
+       BT_CLOCK_CLASS_SET_ORIGIN_STATUS_OK             = __BT_FUNC_STATUS_OK,
+
+       /*!
+       @brief
+           Out of memory.
+       */
+       BT_CLOCK_CLASS_SET_ORIGIN_STATUS_MEMORY_ERROR   = __BT_FUNC_STATUS_MEMORY_ERROR,
+} bt_clock_class_set_origin_status;
+
+/*!
+@brief
+    Sets the custom \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class} to the
+    \bt_p{ns}, \bt_p{name}, and \bt_p{uid} tuple.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@param[in] clock_class
+    Clock class of which to set the origin to the
+    \bt_p{ns}, \bt_p{name}, and \bt_p{uid} tuple.
+@param[in] ns
+    @parblock
+    Namespace of the custom origin of \bt_p{clock_class} (copied).
+
+    Can be \c NULL.
+    @endparblock
+@param[in] name
+    Name of the custom origin of \bt_p{clock_class} (copied).
+@param[in] uid
+    <a href="https://en.wikipedia.org/wiki/Unique_identifier">Unique identifier</a>
+    (UID) of the custom origin of \bt_p{clock_class} (copied).
+
+@retval #BT_CLOCK_CLASS_SET_ORIGIN_STATUS_OK
+    Success.
+@retval #BT_CLOCK_CLASS_SET_ORIGIN_STATUS_MEMORY_ERROR
+    Out of memory.
+
+@bt_pre_not_null{clock_class}
+@bt_pre_hot{clock_class}
+@bt_pre_clock_cls_with_mip{clock_class, 1}
+@bt_pre_not_null{name}
+@bt_pre_not_null{uid}
+
+@sa bt_clock_class_set_origin_unknown() &mdash;
+    Makes the origin of a clock class unknown.
+@sa bt_clock_class_set_origin_unix_epoch() &mdash;
+    Makes the origin of a clock class the Unix epoch.
+@sa bt_clock_class_get_origin_namespace() &mdash;
+    Returns the namespace of the origin of a clock class.
+@sa bt_clock_class_get_origin_name() &mdash;
+    Returns the name of the origin of a clock class.
+@sa bt_clock_class_get_origin_uid() &mdash;
+    Returns the UID of the origin of a clock class.
+*/
+extern bt_clock_class_set_origin_status bt_clock_class_set_origin(
+               bt_clock_class *clock_class, const char *ns, const char *name,
+               const char *uid) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Returns whether or not the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class} is unknown.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@param[in] clock_class
+    Clock class of which to get whether or not its origin is unknown.
+
+@returns
+    #BT_TRUE if the origin of \bt_p{clock_class} is unknown.
+
+@bt_pre_not_null{clock_class}
+
+@sa bt_clock_class_origin_is_unix_epoch() &mdash;
+    Returns whether or not the origin of a clock class is the
+    Unix epoch.
+@sa bt_clock_class_set_origin_unknown() &mdash;
+    Makes the origin of a clock class unknown.
+@sa bt_clock_class_set_origin_unix_epoch() &mdash;
+    Makes the origin of a clock class the Unix epoch.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
+*/
+extern bt_bool bt_clock_class_origin_is_unknown(
+               const bt_clock_class *clock_class) __BT_NOEXCEPT;
+
 /*!
 @brief
     Returns whether or not the \ref api-tir-clock-cls-origin "origin"
     of the clock class \bt_p{clock_class} is the
     <a href="https://en.wikipedia.org/wiki/Unix_time">Unix epoch</a>.
 
-See the \ref api-tir-clock-cls-prop-origin-unix-epoch "origin is Unix epoch?"
-property.
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
 
 @param[in] clock_class
     Clock class of which to get whether or not its origin is the
@@ -524,12 +765,117 @@ property.
 
 @bt_pre_not_null{clock_class}
 
-@sa bt_clock_class_set_origin_is_unix_epoch() &mdash;
-    Sets whether or not the origin of a clock class is the Unix epoch.
+@sa bt_clock_class_origin_is_unknown() &mdash;
+    Returns whether or not the origin of a clock class is unknown.
+@sa bt_clock_class_set_origin_unknown() &mdash;
+    Makes the origin of a clock class unknown.
+@sa bt_clock_class_set_origin_unix_epoch() &mdash;
+    Makes the origin of a clock class the Unix epoch.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
 */
 extern bt_bool bt_clock_class_origin_is_unix_epoch(
                const bt_clock_class *clock_class) __BT_NOEXCEPT;
 
+/*!
+@brief
+    Returns the namespace of the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class}.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@param[in] clock_class
+    Clock class of which to get the origin namespace.
+
+@returns
+    @parblock
+    Origin namespace of \bt_p{clock_class}, or \c NULL if none.
+
+    The returned pointer remains valid as long as \bt_p{clock_class}
+    is not modified.
+    @endparblock
+
+@bt_pre_not_null{clock_class}
+@bt_pre_clock_cls_with_mip{clock_class, 1}
+
+@sa bt_clock_class_get_origin_name() &mdash;
+    Returns the name of the origin of a clock class.
+@sa bt_clock_class_get_origin_uid() &mdash;
+    Returns the UID of the origin of a clock class.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
+*/
+extern const char *bt_clock_class_get_origin_namespace(
+       const bt_clock_class *clock_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Returns the name of the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class}.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@param[in] clock_class
+    Clock class of which to get the origin name.
+
+@returns
+    @parblock
+    Origin name of \bt_p{clock_class}, or \c NULL if none.
+
+    If this function doesn't return \c NULL, then
+    bt_clock_class_get_origin_uid() also doesn't return \c NULL.
+
+    The returned pointer remains valid as long as \bt_p{clock_class}
+    is not modified.
+    @endparblock
+
+@bt_pre_not_null{clock_class}
+@bt_pre_clock_cls_with_mip{clock_class, 1}
+
+@sa bt_clock_class_get_origin_namespace() &mdash;
+    Returns the namespace of the origin of a clock class.
+@sa bt_clock_class_get_origin_uid() &mdash;
+    Returns the UID of the origin of a clock class.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
+*/
+extern const char *bt_clock_class_get_origin_name(
+       const bt_clock_class *clock_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Returns the UID of the \ref api-tir-clock-cls-origin "origin"
+    of the clock class \bt_p{clock_class}.
+
+See the \ref api-tir-clock-cls-prop-origin "origin" property.
+
+@param[in] clock_class
+    Clock class of which to get the origin UID.
+
+@returns
+    @parblock
+    Origin UID of \bt_p{clock_class}, or \c NULL if none.
+
+    If this function doesn't return \c NULL, then
+    bt_clock_class_get_origin_name() also doesn't return \c NULL.
+
+    The returned pointer remains valid as long as \bt_p{clock_class}
+    is not modified.
+    @endparblock
+
+@bt_pre_not_null{clock_class}
+@bt_pre_clock_cls_with_mip{clock_class, 1}
+
+@sa bt_clock_class_get_origin_namespace() &mdash;
+    Returns the namespace of the origin of a clock class.
+@sa bt_clock_class_get_origin_name() &mdash;
+    Returns the name of the origin of a clock class.
+@sa bt_clock_class_set_origin() &mdash;
+    Sets the custom origin of a clock class.
+*/
+extern const char *bt_clock_class_get_origin_uid(
+       const bt_clock_class *clock_class) __BT_NOEXCEPT;
+
 /*!
 @brief
     Status codes for bt_clock_class_set_name().
@@ -553,7 +899,7 @@ typedef enum bt_clock_class_set_name_status {
     Sets the name of the clock class \bt_p{clock_class} to
     a copy of \bt_p{name}.
 
-See the \ref api-tir-clock-cls-prop-name "name" property.
+See the \ref api-tir-clock-cls-prop-iden "identity" property.
 
 @param[in] clock_class
     Clock class of which to set the name to \bt_p{name}.
@@ -579,7 +925,7 @@ extern bt_clock_class_set_name_status bt_clock_class_set_name(
 @brief
     Returns the name of the clock class \bt_p{clock_class}.
 
-See the \ref api-tir-clock-cls-prop-name "name" property.
+See the \ref api-tir-clock-cls-prop-iden "identity" property.
 
 If \bt_p{clock_class} has no name, this function returns \c NULL.
 
@@ -622,96 +968,108 @@ typedef enum bt_clock_class_set_description_status {
 
 /*!
 @brief
-    Sets the description of the clock class \bt_p{clock_class} to a copy
-    of \bt_p{description}.
+    Sets the
+    <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a>
+    of the clock class \bt_p{clock_class} to a copy of \bt_p{uuid}.
 
-See the \ref api-tir-clock-cls-prop-descr "description" property.
+@note
+    This function is only available when \bt_p{clock_class} was
+    created from a \bt_comp which belongs to a trace processing \bt_graph
+    with the effective \bt_mip (MIP) version&nbsp;0.
 
-@param[in] clock_class
-    Clock class of which to set the description to \bt_p{description}.
-@param[in] description
-    New description of \bt_p{clock_class} (copied).
+See the \ref api-tir-clock-cls-prop-iden "identity" property.
 
-@retval #BT_CLOCK_CLASS_SET_DESCRIPTION_STATUS_OK
-    Success.
-@retval #BT_CLOCK_CLASS_SET_DESCRIPTION_STATUS_MEMORY_ERROR
-    Out of memory.
+@param[in] clock_class
+    Clock class of which to set the UUID to \bt_p{uuid}.
+@param[in] uuid
+    New UUID of \bt_p{clock_class} (copied).
 
 @bt_pre_not_null{clock_class}
 @bt_pre_hot{clock_class}
-@bt_pre_not_null{description}
+@bt_pre_clock_cls_with_mip{clock_class, 0}
+@bt_pre_not_null{uuid}
 
-@sa bt_clock_class_get_description() &mdash;
-    Returns the description of a clock class.
+@sa bt_clock_class_get_uuid() &mdash;
+    Returns the UUID of a clock class.
 */
-extern bt_clock_class_set_description_status bt_clock_class_set_description(
-               bt_clock_class *clock_class, const char *description)
-               __BT_NOEXCEPT;
+extern void bt_clock_class_set_uuid(bt_clock_class *clock_class,
+               bt_uuid uuid) __BT_NOEXCEPT;
 
 /*!
 @brief
-    Returns the description of the clock class \bt_p{clock_class}.
+    Returns the UUID of the clock class \bt_p{clock_class}.
 
-See the \ref api-tir-clock-cls-prop-descr "description" property.
+@note
+    This function is only available when \bt_p{clock_class} was
+    created from a \bt_comp which belongs to a trace processing \bt_graph
+    with the effective \bt_mip (MIP) version&nbsp;0.
 
-If \bt_p{clock_class} has no description, this function returns \c NULL.
+See the \ref api-tir-clock-cls-prop-iden "identity" property.
+
+If \bt_p{clock_class} has no UUID, this function returns \c NULL.
 
 @param[in] clock_class
-    Clock class of which to get the description.
+    Clock class of which to get the UUID.
 
 @returns
     @parblock
-    Description of \bt_p{clock_class}, or \c NULL if none.
+    UUID of \bt_p{clock_class}, or \c NULL if none.
 
     The returned pointer remains valid as long as \bt_p{clock_class}
     is not modified.
     @endparblock
 
 @bt_pre_not_null{clock_class}
+@bt_pre_clock_cls_with_mip{clock_class, 0}
 
-@sa bt_clock_class_set_description() &mdash;
-    Sets the description of a clock class.
+@sa bt_clock_class_set_uuid() &mdash;
+    Sets the UUID of a clock class.
 */
-extern const char *bt_clock_class_get_description(
+extern bt_uuid bt_clock_class_get_uuid(
                const bt_clock_class *clock_class) __BT_NOEXCEPT;
 
 /*!
 @brief
-    Sets the
-    <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a>
-    of the clock class \bt_p{clock_class} to a copy of \bt_p{uuid}.
+    Sets the description of the clock class \bt_p{clock_class} to a copy
+    of \bt_p{description}.
 
-See the \ref api-tir-clock-cls-prop-uuid "UUID" property.
+See the \ref api-tir-clock-cls-prop-descr "description" property.
 
 @param[in] clock_class
-    Clock class of which to set the UUID to \bt_p{uuid}.
-@param[in] uuid
-    New UUID of \bt_p{clock_class} (copied).
+    Clock class of which to set the description to \bt_p{description}.
+@param[in] description
+    New description of \bt_p{clock_class} (copied).
+
+@retval #BT_CLOCK_CLASS_SET_DESCRIPTION_STATUS_OK
+    Success.
+@retval #BT_CLOCK_CLASS_SET_DESCRIPTION_STATUS_MEMORY_ERROR
+    Out of memory.
 
 @bt_pre_not_null{clock_class}
 @bt_pre_hot{clock_class}
-@bt_pre_not_null{uuid}
+@bt_pre_not_null{description}
 
-@sa bt_clock_class_get_uuid() &mdash;
-    Returns the UUID of a clock class.
+@sa bt_clock_class_get_description() &mdash;
+    Returns the description of a clock class.
 */
-extern void bt_clock_class_set_uuid(bt_clock_class *clock_class,
-               bt_uuid uuid) __BT_NOEXCEPT;
+extern bt_clock_class_set_description_status bt_clock_class_set_description(
+               bt_clock_class *clock_class, const char *description)
+               __BT_NOEXCEPT;
 
 /*!
 @brief
-    Returns the UUID of the clock class \bt_p{clock_class}.
+    Returns the description of the clock class \bt_p{clock_class}.
 
-See the \ref api-tir-clock-cls-prop-uuid "UUID" property.
+See the \ref api-tir-clock-cls-prop-descr "description" property.
 
-If \bt_p{clock_class} has no UUID, this function returns \c NULL.
+If \bt_p{clock_class} has no description, this function returns \c NULL.
 
 @param[in] clock_class
-    Clock class of which to get the UUID.
+    Clock class of which to get the description.
 
 @returns
     @parblock
-    UUID of \bt_p{clock_class}, or \c NULL if none.
+    Description of \bt_p{clock_class}, or \c NULL if none.
 
     The returned pointer remains valid as long as \bt_p{clock_class}
     is not modified.
@@ -719,10 +1077,10 @@ If \bt_p{clock_class} has no UUID, this function returns \c NULL.
 
 @bt_pre_not_null{clock_class}
 
-@sa bt_clock_class_set_uuid() &mdash;
-    Sets the UUID of a clock class.
+@sa bt_clock_class_set_description() &mdash;
+    Sets the description of a clock class.
 */
-extern bt_uuid bt_clock_class_get_uuid(
+extern const char *bt_clock_class_get_description(
                const bt_clock_class *clock_class) __BT_NOEXCEPT;
 
 /*!
index cba1655ae388c584a93a557729695bac43e71748..93072f781c01ba2790644fa9621681b1a097de53 100644 (file)
 #define BT_ASSERT_PRE_CC_MIP_VERSION_EQ(_clock_class, _val)            \
        BT_ASSERT_PRE_MIP_VERSION_EQ((_clock_class)->mip_version, _val)
 
+/*
+ * Asserts that the effective MIP version for `_clock_class` is greater than or
+ * equal to `_val`.
+ */
+#define BT_ASSERT_PRE_CC_MIP_VERSION_GE(_clock_class, _val)            \
+       BT_ASSERT_PRE_MIP_VERSION_GE((_clock_class)->mip_version, _val)
+
 /*
  * Asserts that the effective MIP version for `_trace_class` is equal to `_val`.
  */
        BT_ASSERT_PRE_DEV_NON_NULL(_BT_ASSERT_PRE_NAME_ID, (_name),     \
                _BT_ASSERT_PRE_NAME_NAME)
 
+#define _BT_ASSERT_PRE_NAMESPACE_NAME  "Namespace"
+#define _BT_ASSERT_PRE_NAMESPACE_ID    "namespace"
+
+#define BT_ASSERT_PRE_NAMESPACE_NON_NULL(_name)                                \
+       BT_ASSERT_PRE_NON_NULL(_BT_ASSERT_PRE_NAMESPACE_ID, (_name),    \
+               _BT_ASSERT_PRE_NAMESPACE_NAME)
+
 #define _BT_ASSERT_PRE_DESCR_NAME      "Description"
 #define _BT_ASSERT_PRE_DESCR_ID                "description"
 
index 41bdc66f66d44a8686394eab785d6e44e9999257..2a8f500919f530ddf5be2bd5c958eaf163de0e3c 100644 (file)
@@ -865,12 +865,17 @@ static inline void format_clock_class(char **buf_ch, bool extended,
 
        BUF_APPEND(", %sis-frozen=%d, %sprecision=%" PRIu64 ", "
                "%soffset-s=%" PRId64 ", "
-               "%soffset-cycles=%" PRIu64 ", %sorigin-is-unix-epoch=%d, "
+               "%soffset-cycles=%" PRIu64 ", "
+               "%sorigin-namespace=%s, "
+               "%sorigin-name=%s, "
+               "%sorigin-uid=%s, "
                "%sbase-offset-ns=%" PRId64,
                PRFIELD(clock_class->frozen), PRFIELD(clock_class->precision),
                PRFIELD(clock_class->offset_seconds),
                PRFIELD(clock_class->offset_cycles),
-               PRFIELD(clock_class->origin_is_unix_epoch),
+               PRFIELD(clock_class->origin.ns),
+               PRFIELD(clock_class->origin.name),
+               PRFIELD(clock_class->origin.uid),
                PRFIELD(clock_class->base_offset.value_ns));
 
        SET_TMP_PREFIX("cs-pool-");
index 0a6437ec562823f78452ac9e405bff614fa00616..2939b5a8550f382d7aa3545bb4271fb1ef6e4ec4 100644 (file)
        BT_ASSERT_PRE_DEV_HOT("clock-class", (_cc), "Clock class",      \
                ": %!+K", (_cc))
 
+/* Constants for the UNIX epoch origin */
+static const char *const CC_ORIGIN_UNIX_EPOCH_NS = "babeltrace.org,2020";
+static const char *const CC_ORIGIN_UNIX_EPOCH_NAME = "unix-epoch";
+static const char *const CC_ORIGIN_UNIX_EPOCH_UID = "";
+
+static
+void free_clock_class_origin_data(struct bt_clock_class *clock_class)
+{
+       /*
+        * If the origin was set using set_origin_unix_epoch(), then the
+        * pointers are equal to the `CC_ORIGIN_UNIX_EPOCH_*` constants,
+        * therefore the strings aren't dynamically allocated.
+        */
+       if (clock_class->origin.ns != CC_ORIGIN_UNIX_EPOCH_NS) {
+               g_free(clock_class->origin.ns);
+       }
+
+       clock_class->origin.ns = NULL;
+
+       if (clock_class->origin.name != CC_ORIGIN_UNIX_EPOCH_NAME) {
+               g_free(clock_class->origin.name);
+       }
+
+       clock_class->origin.name = NULL;
+
+       if (clock_class->origin.uid != CC_ORIGIN_UNIX_EPOCH_UID) {
+               g_free(clock_class->origin.uid);
+       }
+
+       clock_class->origin.uid = NULL;
+}
+
 static
 void destroy_clock_class(struct bt_object *obj)
 {
@@ -39,6 +71,7 @@ void destroy_clock_class(struct bt_object *obj)
 
        g_free(clock_class->name);
        g_free(clock_class->description);
+       free_clock_class_origin_data(clock_class);
        bt_object_pool_finalize(&clock_class->cs_pool);
        g_free(clock_class);
 }
@@ -58,6 +91,26 @@ void set_base_offset(struct bt_clock_class *clock_class)
                clock_class->frequency, &clock_class->base_offset.value_ns);
 }
 
+static void
+set_origin_unix_epoch(struct bt_clock_class *clock_class)
+{
+       free_clock_class_origin_data(clock_class);
+
+       /*
+        * For the Unix epoch origin, don't use g_strdup() to avoid
+        * allocations.
+        */
+       clock_class->origin.ns = (gchar *) CC_ORIGIN_UNIX_EPOCH_NS;
+       clock_class->origin.name = (gchar *) CC_ORIGIN_UNIX_EPOCH_NAME;
+       clock_class->origin.uid = (gchar *) CC_ORIGIN_UNIX_EPOCH_UID;
+}
+
+static void
+set_origin_unknown(struct bt_clock_class *clock_class)
+{
+       free_clock_class_origin_data(clock_class);
+}
+
 BT_EXPORT
 struct bt_clock_class *bt_clock_class_create(bt_self_component *self_comp)
 {
@@ -87,7 +140,7 @@ struct bt_clock_class *bt_clock_class_create(bt_self_component *self_comp)
        }
 
        clock_class->frequency = UINT64_C(1000000000);
-       clock_class->origin_is_unix_epoch = BT_TRUE;
+       set_origin_unix_epoch(clock_class);
        set_base_offset(clock_class);
        ret = bt_object_pool_initialize(&clock_class->cs_pool,
                (bt_object_pool_new_object_func) bt_clock_snapshot_new,
@@ -229,24 +282,115 @@ void bt_clock_class_set_offset(struct bt_clock_class *clock_class,
        BT_LIB_LOGD("Set clock class's offset: %!+K", clock_class);
 }
 
+BT_EXPORT
+const char *bt_clock_class_get_origin_namespace(
+               const bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_DEV_CLK_CLS_NON_NULL(clock_class);
+       BT_ASSERT_PRE_CC_MIP_VERSION_GE(clock_class, 1);
+       return clock_class->origin.ns;
+}
+
+BT_EXPORT
+const char *bt_clock_class_get_origin_name(
+               const bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_DEV_CLK_CLS_NON_NULL(clock_class);
+       BT_ASSERT_PRE_CC_MIP_VERSION_GE(clock_class, 1);
+       return clock_class->origin.name;
+}
+
+BT_EXPORT
+const char *bt_clock_class_get_origin_uid(
+               const bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_DEV_CLK_CLS_NON_NULL(clock_class);
+       BT_ASSERT_PRE_CC_MIP_VERSION_GE(clock_class, 1);
+       return clock_class->origin.uid;
+}
+
 BT_EXPORT
 bt_bool bt_clock_class_origin_is_unix_epoch(const struct bt_clock_class *clock_class)
 {
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_DEV_CLK_CLS_NON_NULL(clock_class);
+
+       /*
+        * We don't just compare the pointers to the constants, as the
+        * user could set the same values using
+        * bt_clock_class_set_origin().
+        */
+       return g_strcmp0(clock_class->origin.ns, CC_ORIGIN_UNIX_EPOCH_NS) == 0 &&
+               g_strcmp0(clock_class->origin.name, CC_ORIGIN_UNIX_EPOCH_NAME) == 0 &&
+               g_strcmp0(clock_class->origin.uid, CC_ORIGIN_UNIX_EPOCH_UID) == 0;
+}
+
+BT_EXPORT
+bt_bool bt_clock_class_origin_is_unknown(const struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NO_ERROR();
        BT_ASSERT_PRE_DEV_CLK_CLS_NON_NULL(clock_class);
-       return (bool) clock_class->origin_is_unix_epoch;
+       return !clock_class->origin.ns && !clock_class->origin.name &&
+               !clock_class->origin.uid;
 }
 
 BT_EXPORT
 void bt_clock_class_set_origin_is_unix_epoch(struct bt_clock_class *clock_class,
                bt_bool origin_is_unix_epoch)
 {
+       BT_ASSERT_PRE_NO_ERROR();
        BT_ASSERT_PRE_CLK_CLS_NON_NULL(clock_class);
        BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
-       clock_class->origin_is_unix_epoch = (bool) origin_is_unix_epoch;
+
+       if (origin_is_unix_epoch) {
+               set_origin_unix_epoch(clock_class);
+       } else {
+               set_origin_unknown(clock_class);
+       }
+
        BT_LIB_LOGD("Set clock class's origin is Unix epoch property: %!+K",
                clock_class);
 }
 
+BT_EXPORT
+void bt_clock_class_set_origin_unknown(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_CLK_CLS_NON_NULL(clock_class);
+       BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
+       set_origin_unknown(clock_class);
+}
+
+BT_EXPORT
+enum bt_clock_class_set_origin_status bt_clock_class_set_origin(
+               struct bt_clock_class *clock_class, const char *ns,
+               const char *name, const char *uid)
+{
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_CLK_CLS_NON_NULL(clock_class);
+       BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
+       BT_ASSERT_PRE_CC_MIP_VERSION_GE(clock_class, 1);
+       BT_ASSERT_PRE_NAME_NON_NULL(name);
+       BT_ASSERT_PRE_UID_NON_NULL(uid);
+       free_clock_class_origin_data(clock_class);
+       clock_class->origin.ns = g_strdup(ns);
+       clock_class->origin.name = g_strdup(name);
+       clock_class->origin.uid = g_strdup(uid);
+       return BT_FUNC_STATUS_OK;
+}
+
+BT_EXPORT
+void bt_clock_class_set_origin_unix_epoch(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NO_ERROR();
+       BT_ASSERT_PRE_CLK_CLS_NON_NULL(clock_class);
+       BT_ASSERT_PRE_DEV_CLOCK_CLASS_HOT(clock_class);
+       set_origin_unix_epoch(clock_class);
+}
+
 BT_EXPORT
 bt_uuid bt_clock_class_get_uuid(const struct bt_clock_class *clock_class)
 {
index 3c2243d1fe05b2c37182be0ba4ebab10cb3a82dd..bca58088030ec4d29ec4b22ea301101734cc5ec1 100644 (file)
@@ -45,7 +45,11 @@ struct bt_clock_class {
                bt_uuid value;
        } uuid;
 
-       bool origin_is_unix_epoch;
+       struct {
+               gchar *ns;
+               gchar *name;
+               gchar *uid;
+       } origin;
 
        /*
         * This is computed every time you call
This page took 0.038205 seconds and 4 git commands to generate.