tracing: Add samples of DECLARE_EVENT_CLASS() and DEFINE_EVENT()
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>
Mon, 9 Feb 2015 22:14:04 +0000 (17:14 -0500)
committerSteven Rostedt <rostedt@goodmis.org>
Mon, 9 Feb 2015 23:05:51 +0000 (18:05 -0500)
Add to samples/trace_events/ the macros DECLARE_EVENT_CLASS() and
DEFINE_EVENT() and recommend using them over multiple TRACE_EVENT()
macros if the multiple events have the same format.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
samples/trace_events/trace-events-sample.c
samples/trace_events/trace-events-sample.h

index 39d4484..880a7d1 100644 (file)
@@ -35,7 +35,13 @@ static void simple_thread_func(int cnt)
        trace_foo_bar("hello", cnt, array, random_strings[len],
                      tsk_cpus_allowed(current));
 
+       trace_foo_with_template_simple("HELLO", cnt);
+
        trace_foo_bar_with_cond("Some times print", cnt);
+
+       trace_foo_with_template_cond("prints other times", cnt);
+
+       trace_foo_with_template_print("I have to be different", cnt);
 }
 
 static int simple_thread(void *arg)
@@ -58,6 +64,7 @@ static void simple_thread_func_fn(int cnt)
 
        /* More silly tracepoints */
        trace_foo_bar_with_fn("Look at me", cnt);
+       trace_foo_with_template_fn("Look at me too", cnt);
 }
 
 static int simple_thread_fn(void *arg)
index d0be841..a2c8b02 100644 (file)
@@ -314,6 +314,87 @@ TRACE_EVENT_FN(foo_bar_with_fn,
        foo_bar_reg, foo_bar_unreg
 );
 
+/*
+ * Each TRACE_EVENT macro creates several helper functions to produce
+ * the code to add the tracepoint, create the files in the trace
+ * directory, hook it to perf, assign the values and to print out
+ * the raw data from the ring buffer. To prevent too much bloat,
+ * if there are more than one tracepoint that uses the same format
+ * for the proto, args, struct, assign and printk, and only the name
+ * is different, it is highly recommended to use the DECLARE_EVENT_CLASS
+ *
+ * DECLARE_EVENT_CLASS() macro creates most of the functions for the
+ * tracepoint. Then DEFINE_EVENT() is use to hook a tracepoint to those
+ * functions. This DEFINE_EVENT() is an instance of the class and can
+ * be enabled and disabled separately from other events (either TRACE_EVENT
+ * or other DEFINE_EVENT()s).
+ *
+ * Note, TRACE_EVENT() itself is simply defined as:
+ *
+ * #define TRACE_EVENT(name, proto, args, tstruct, assign, printk)  \
+ *  DEFINE_EVENT_CLASS(name, proto, args, tstruct, assign, printk); \
+ *  DEFINE_EVENT(name, name, proto, args)
+ *
+ * The DEFINE_EVENT() also can be declared with conditions and reg functions:
+ *
+ * DEFINE_EVENT_CONDITION(template, name, proto, args, cond);
+ * DEFINE_EVENT_FN(template, name, proto, args, reg, unreg);
+ */
+DECLARE_EVENT_CLASS(foo_template,
+
+       TP_PROTO(const char *foo, int bar),
+
+       TP_ARGS(foo, bar),
+
+       TP_STRUCT__entry(
+               __string(       foo,    foo             )
+               __field(        int,    bar             )
+       ),
+
+       TP_fast_assign(
+               __assign_str(foo, foo);
+               __entry->bar    = bar;
+       ),
+
+       TP_printk("foo %s %d", __get_str(foo), __entry->bar)
+);
+
+/*
+ * Here's a better way for the previous samples (except, the first
+ * exmaple had more fields and could not be used here).
+ */
+DEFINE_EVENT(foo_template, foo_with_template_simple,
+       TP_PROTO(const char *foo, int bar),
+       TP_ARGS(foo, bar));
+
+DEFINE_EVENT_CONDITION(foo_template, foo_with_template_cond,
+       TP_PROTO(const char *foo, int bar),
+       TP_ARGS(foo, bar),
+       TP_CONDITION(!(bar % 8)));
+
+
+DEFINE_EVENT_FN(foo_template, foo_with_template_fn,
+       TP_PROTO(const char *foo, int bar),
+       TP_ARGS(foo, bar),
+       foo_bar_reg, foo_bar_unreg);
+
+/*
+ * Anytime two events share basically the same values and have
+ * the same output, use the DECLARE_EVENT_CLASS() and DEFINE_EVENT()
+ * when ever possible.
+ */
+
+/*
+ * If the event is similar to the DECLARE_EVENT_CLASS, but you need
+ * to have a different output, then use DEFINE_EVENT_PRINT() which
+ * lets you override the TP_printk() of the class.
+ */
+
+DEFINE_EVENT_PRINT(foo_template, foo_with_template_print,
+       TP_PROTO(const char *foo, int bar),
+       TP_ARGS(foo, bar),
+       TP_printk("bar %s %d", __get_str(foo), __entry->bar));
+
 #endif
 
 /***** NOTICE! The #if protection ends here. *****/