From cce547fa7a49d9795a278d293af882ef66e4145f Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 23 Oct 2014 15:18:48 -0400 Subject: [PATCH] New section: using-tracepoint-classes --- .../c-application/using-tracepoint-classes.md | 163 ++++++++++++++++++ toc/docs.yml | 2 + 2 files changed, 165 insertions(+) create mode 100644 contents/using-lttng/instrumenting/c-application/using-tracepoint-classes.md 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 index 0000000..ba872b4 --- /dev/null +++ b/contents/using-lttng/instrumenting/c-application/using-tracepoint-classes.md @@ -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) +~~~ diff --git a/toc/docs.yml b/toc/docs.yml index 67a56e9..794781a 100644 --- a/toc/docs.yml +++ b/toc/docs.yml @@ -98,6 +98,8 @@ cats: title: Using lttng-gen-tp - 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 -- 2.34.1