New section: using-tracepoint-classes
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 23 Oct 2014 19:18:48 +0000 (15:18 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 23 Oct 2014 19:18:48 +0000 (15:18 -0400)
contents/using-lttng/instrumenting/c-application/using-tracepoint-classes.md [new file with mode: 0644]
toc/docs.yml

diff --git a/contents/using-lttng/instrumenting/c-application/using-tracepoint-classes.md b/contents/using-lttng/instrumenting/c-application/using-tracepoint-classes.md
new file mode 100644 (file)
index 0000000..ba872b4
--- /dev/null
@@ -0,0 +1,163 @@
+---
+id: using-tracepoint-classes
+---
+
+In LTTng-UST, a _tracepoint class_ is a class of tracepoints sharing the
+same field types and names. A _tracepoint instance_ is one instance of
+such a declared tracepoint class, with its own event name and tracepoint
+provider name.
+
+What is documented in [Defining tracepoints](#doc-defining-tracepoints)
+is actually how to declare a _tracepoint class_ and define a
+_tracepoint instance_ at the same time. Without revealing the internals
+of LTTng-UST too much, it has to be noted that one serialization
+function is created for each tracepoint class. A serialization
+function is responsible for serializing the fields of a tracepoint
+into a sub-buffer when tracing. For various performance reasons, when
+your situation requires multiple tracepoints with different names, but
+with the same fields layout, the best practice is to manually create
+a tracepoint class and instantiate as many tracepoint instances as
+needed. One positive effect of such a design, amongst other advantages,
+is that all tracepoint instances of the same tracepoint class will
+reuse the same serialization function, thus reducing cache pollution.
+
+As an example, here are three tracepoint definitions as we know them:
+
+~~~ c
+TRACEPOINT_EVENT(
+    my_app,
+    get_account,
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    ),
+    TP_FIELDS(
+        ctf_integer(int, userid, userid)
+        ctf_integer(size_t, len, len)
+    )
+)
+
+TRACEPOINT_EVENT(
+    my_app,
+    get_settings,
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    ),
+    TP_FIELDS(
+        ctf_integer(int, userid, userid)
+        ctf_integer(size_t, len, len)
+    )
+)
+
+TRACEPOINT_EVENT(
+    my_app,
+    get_transaction,
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    ),
+    TP_FIELDS(
+        ctf_integer(int, userid, userid)
+        ctf_integer(size_t, len, len)
+    )
+)
+~~~
+
+In this case, three tracepoint classes are created, with one tracepoint
+instance for each of them: `get_account`, `get_settings` and
+`get_transaction`. However, they all share the same field names and
+types. Declaring one tracepoint class and three tracepoint instances of
+the latter is a better design choice:
+
+~~~ c
+/* the tracepoint class */
+TRACEPOINT_EVENT_CLASS(
+    /* tracepoint provider name */
+    my_app,
+
+    /* tracepoint class name */
+    my_class,
+
+    /* arguments */
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    ),
+
+    /* fields */
+    TP_FIELDS(
+        ctf_integer(int, userid, userid)
+        ctf_integer(size_t, len, len)
+    )
+)
+
+/* the tracepoint instances */
+TRACEPOINT_EVENT_INSTANCE(
+    /* tracepoint provider name */
+    my_app,
+
+    /* tracepoint class name */
+    my_class,
+
+    /* tracepoint/event name */
+    get_account,
+
+    /* arguments */
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    )
+)
+TRACEPOINT_EVENT_INSTANCE(
+    my_app,
+    my_class,
+    get_settings,
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    )
+)
+TRACEPOINT_EVENT_INSTANCE(
+    my_app,
+    my_class,
+    get_transaction,
+    TP_ARGS(
+        int, userid,
+        size_t, len
+    )
+)
+~~~
+
+Of course, all those names and `TP_ARGS()` invocations are redundant,
+but some C preprocessor magic can solve this:
+
+~~~ c
+#define MY_TRACEPOINT_ARGS \
+    TP_ARGS( \
+        int, userid, \
+        size_t, len \
+    )
+
+TRACEPOINT_EVENT_CLASS(
+    my_app,
+    my_class,
+    MY_TRACEPOINT_ARGS,
+    TP_FIELDS(
+        ctf_integer(int, userid, userid)
+        ctf_integer(size_t, len, len)
+    )
+)
+
+#define MY_APP_TRACEPOINT_INSTANCE(name) \
+    TRACEPOINT_EVENT_INSTANCE( \
+        my_app, \
+        my_class, \
+        name, \
+        MY_TRACEPOINT_ARGS \
+    )
+
+MY_APP_TRACEPOINT_INSTANCE(get_account)
+MY_APP_TRACEPOINT_INSTANCE(get_settings)
+MY_APP_TRACEPOINT_INSTANCE(get_transaction)
+~~~
index 67a56e93ad7134b07a51da2e905a50910096272f..794781ab2c26ef8bf8ebab65a3825aeb5e21639f 100644 (file)
@@ -98,6 +98,8 @@ cats:
                 title: Using <code>lttng-gen-tp</code>
               - id: defining-tracepoints
                 title: Defining tracepoints
+              - id: using-tracepoint-classes
+                title: Using tracepoint classes
               - id: assigning-log-levels
                 title: Assigning log levels to tracepoints
               - id: probing-the-application-source-code
This page took 0.025036 seconds and 4 git commands to generate.