X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=include%2Fust%2Ftracepoint.h;h=1a91b79ff526fab81d1b09a9cc256b2dd99ac02b;hb=22d7294822cce9fdc893b8ab272e322270456ac9;hp=908d5abd553378c0cb0ffa0292e49541f4596ae0;hpb=27b052e353653e0e0e2ab72217bcbab5aff237c2;p=ust.git diff --git a/include/ust/tracepoint.h b/include/ust/tracepoint.h index 908d5ab..1a91b79 100644 --- a/include/ust/tracepoint.h +++ b/include/ust/tracepoint.h @@ -4,6 +4,7 @@ /* * Copyright (C) 2008 Mathieu Desnoyers * Copyright (C) 2009 Pierre-Marc Fournier + * Copyright (C) 2009 Steven Rostedt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,15 +25,10 @@ * Ported to userspace by Pierre-Marc Fournier. */ -//#include -//#include -//#include - #define _LGPL_SOURCE #include - #include -#include +#include struct module; struct tracepoint; @@ -48,8 +44,10 @@ struct tracepoint { * Keep in sync with vmlinux.lds.h. */ -#define TPPROTO(args...) args -#define TPARGS(args...) args +#define PARAMS(args...) args + +#define TP_PROTO(args...) args +#define TP_ARGS(args...) args #define CONFIG_TRACEPOINTS #ifdef CONFIG_TRACEPOINTS @@ -77,11 +75,11 @@ struct tracepoint { if (!generic) { \ if (unlikely(imv_read(__tracepoint_##name.state))) \ __DO_TRACE(&__tracepoint_##name, \ - TPPROTO(proto), TPARGS(args)); \ + TP_PROTO(proto), TP_ARGS(args)); \ } else { \ if (unlikely(_imv_read(__tracepoint_##name.state))) \ __DO_TRACE(&__tracepoint_##name, \ - TPPROTO(proto), TPARGS(args)); \ + TP_PROTO(proto), TP_ARGS(args)); \ } \ } while (0) @@ -99,11 +97,11 @@ struct tracepoint { extern struct tracepoint __tracepoint_##name; \ static inline void trace_##name(proto) \ { \ - __CHECK_TRACE(name, 0, TPPROTO(proto), TPARGS(args)); \ + __CHECK_TRACE(name, 0, TP_PROTO(proto), TP_ARGS(args)); \ } \ static inline void _trace_##name(proto) \ { \ - __CHECK_TRACE(name, 1, TPPROTO(proto), TPARGS(args)); \ + __CHECK_TRACE(name, 1, TP_PROTO(proto), TP_ARGS(args)); \ } \ static inline int register_trace_##name(void (*probe)(proto)) \ { \ @@ -121,11 +119,6 @@ struct tracepoint { __attribute__((section("__tracepoints"), aligned(32))) = \ { __tpstrtab_##name, 0, NULL } -#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ - EXPORT_SYMBOL_GPL(__tracepoint_##name) -#define EXPORT_TRACEPOINT_SYMBOL(name) \ - EXPORT_SYMBOL(__tracepoint_##name) - extern void tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end); @@ -200,6 +193,7 @@ struct tracepoint_lib { extern int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoints_count); +extern int tracepoint_unregister_lib(struct tracepoint *tracepoints_start); #define TRACEPOINT_LIB \ extern struct tracepoint __start___tracepoints[] __attribute__((weak, visibility("hidden"))); \ @@ -208,6 +202,128 @@ extern int tracepoint_register_lib(struct tracepoint *tracepoints_start, { \ tracepoint_register_lib(__start___tracepoints, \ (((long)__stop___tracepoints)-((long)__start___tracepoints))/sizeof(struct tracepoint)); \ + } \ + \ + static void __attribute__((destructor)) __tracepoints__destroy(void) \ + { \ + tracepoint_unregister_lib(__start___tracepoints); \ } + +#ifndef TRACE_EVENT +/* + * For use with the TRACE_EVENT macro: + * + * We define a tracepoint, its arguments, its printf format + * and its 'fast binary record' layout. + * + * Firstly, name your tracepoint via TRACE_EVENT(name : the + * 'subsystem_event' notation is fine. + * + * Think about this whole construct as the + * 'trace_sched_switch() function' from now on. + * + * + * TRACE_EVENT(sched_switch, + * + * * + * * A function has a regular function arguments + * * prototype, declare it via TP_PROTO(): + * * + * + * TP_PROTO(struct rq *rq, struct task_struct *prev, + * struct task_struct *next), + * + * * + * * Define the call signature of the 'function'. + * * (Design sidenote: we use this instead of a + * * TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.) + * * + * + * TP_ARGS(rq, prev, next), + * + * * + * * Fast binary tracing: define the trace record via + * * TP_STRUCT__entry(). You can think about it like a + * * regular C structure local variable definition. + * * + * * This is how the trace record is structured and will + * * be saved into the ring buffer. These are the fields + * * that will be exposed to readers. + * * + * * The declared 'local variable' is called '__entry' + * * + * * __field(pid_t, prev_prid) is equivalent to a standard declariton: + * * + * * pid_t prev_pid; + * * + * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to: + * * + * * char prev_comm[TASK_COMM_LEN]; + * * + * + * TP_STRUCT__entry( + * __array( char, prev_comm, TASK_COMM_LEN ) + * __field( pid_t, prev_pid ) + * __field( int, prev_prio ) + * __array( char, next_comm, TASK_COMM_LEN ) + * __field( pid_t, next_pid ) + * __field( int, next_prio ) + * ), + * + * * + * * Assign the entry into the trace record, by embedding + * * a full C statement block into TP_fast_assign(). You + * * can refer to the trace record as '__entry' - + * * otherwise you can put arbitrary C code in here. + * * + * * Note: this C code will execute every time a trace event + * * happens, on an active tracepoint. + * * + * + * TP_fast_assign( + * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); + * __entry->prev_pid = prev->pid; + * __entry->prev_prio = prev->prio; + * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); + * __entry->next_pid = next->pid; + * __entry->next_prio = next->prio; + * ) + * + * * + * * Formatted output of a trace record via TP_printf(). + * * This is how the tracepoint will appear under debugging + * * of tracepoints. + * * + * * (raw-binary tracing wont actually perform this step.) + * * + * + * TP_printf("task %s:%d [%d] ==> %s:%d [%d]", + * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, + * __entry->next_comm, __entry->next_pid, __entry->next_prio), + * + * ); + * + * This macro construct is thus used for the regular printf format + * tracing setup. + * + * A set of (un)registration functions can be passed to the variant + * TRACE_EVENT_FN to perform any (un)registration work. + */ + +#define DECLARE_TRACE_EVENT_CLASS(name, proto, args, tstruct, assign, print) +#define DEFINE_TRACE_EVENT(template, name, proto, args) \ + DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#define DEFINE_TRACE_EVENT_PRINT(template, name, proto, args, print) \ + DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) + +#define TRACE_EVENT(name, proto, args, struct, assign, print) \ + DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#define TRACE_EVENT_FN(name, proto, args, struct, \ + assign, print, reg, unreg) \ + DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) + +#endif /* ifdef TRACE_EVENT (see note above) */ + + #endif /* _UST_TRACEPOINT_H */