From: Mathieu Desnoyers Date: Thu, 19 May 2011 15:29:57 +0000 (-0400) Subject: Tracepoint and TRACEPOINT_EVENT API cleanup X-Git-Tag: v0.14~20 X-Git-Url: https://git.liburcu.org/?p=ust.git;a=commitdiff_plain;h=8161463975e218e0833d31ab1577a7ceb9e8e9f3 Tracepoint and TRACEPOINT_EVENT API cleanup We want to move towards a TRACEPOINT_EVENT-based API only, so start cleaning up right now. Prefix with _ or __ all members that are internal to UST. Move all the non-exported API members (that don't need to be around in program inclusion) to tracepoint-internal.h (which is not meant to be installed on the system). Unit tests can still use the internal API members for now, but should gradually move to use TRACEPOINT_EVENT as we start implementing the FIELDS() declaration. TRACEPOINT_EVENT is changed from the kernel incarnation (TRACE_EVENT): we take only 3 arguments: proto, args and fields. The "fields" describe the event layout _and_ targets the data source. Signed-off-by: Mathieu Desnoyers --- diff --git a/include/ust/define_trace.h b/include/ust/define_trace.h index 3d29541..f377ddb 100644 --- a/include/ust/define_trace.h +++ b/include/ust/define_trace.h @@ -40,25 +40,20 @@ #include #undef TRACEPOINT_EVENT -#define TRACEPOINT_EVENT(name, proto, args, tstruct, assign, print) \ - DEFINE_TRACEPOINT(name) +#define TRACEPOINT_EVENT(name, proto, args, fields) \ + _DEFINE_TRACEPOINT(name) -#undef TRACEPOINT_EVENT_FN -#define TRACEPOINT_EVENT_FN(name, proto, args, tstruct, \ - assign, print, reg, unreg) \ - DEFINE_TRACEPOINT_FN(name, reg, unreg) +#undef TRACEPOINT_EVENT_INSTANCE +#define TRACEPOINT_EVENT_INSTANCE(template, name, proto, args) \ + _DEFINE_TRACEPOINT(name) -#undef DEFINE_TRACEPOINT_EVENT -#define DEFINE_TRACEPOINT_EVENT(template, name, proto, args) \ - DEFINE_TRACEPOINT(name) +#undef TRACEPOINT_EVENT_NOARGS +#define TRACEPOINT_EVENT_NOARGS(name, fields) \ + _DEFINE_TRACEPOINT(name) -#undef DEFINE_TRACEPOINT_EVENT_PRINT -#define DEFINE_TRACEPOINT_EVENT_PRINT(template, name, proto, args, print) \ - DEFINE_TRACEPOINT(name) - -#undef DECLARE_TRACEPOINT -#define DECLARE_TRACEPOINT(name, proto, args) \ - DEFINE_TRACEPOINT(name) +#undef TRACEPOINT_EVENT_INSTANCE_NOARGS +#define TRACEPOINT_EVENT_INSTANCE_NOARGS(template, name) \ + _DEFINE_TRACEPOINT(name) #undef TRACE_INCLUDE #undef __TRACE_INCLUDE @@ -82,21 +77,17 @@ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -/* Make all open coded DECLARE_TRACEPOINT nops */ -#undef DECLARE_TRACEPOINT -#define DECLARE_TRACEPOINT(name, proto, args) - #ifndef CONFIG_NO_EVENT_TRACING #include #endif #undef TRACEPOINT_EVENT -#undef TRACEPOINT_EVENT_FN -#undef DECLARE_TRACEPOINT_EVENT_CLASS -#undef DEFINE_TRACEPOINT_EVENT -#undef DEFINE_TRACEPOINT_EVENT_PRINT +#undef TRACEPOINT_EVENT_CLASS +#undef TRACEPOINT_EVENT_INSTANCE +#undef TRACEPOINT_EVENT_NOARGS +#undef TRACEPOINT_EVENT_CLASS_NOARGS +#undef TRACEPOINT_EVENT_INSTANCE_NOARGS #undef TRACE_HEADER_MULTI_READ -#undef DECLARE_TRACEPOINT /* Only undef what we defined in this file */ #ifdef UNDEF_TRACE_INCLUDE_FILE diff --git a/include/ust/tracepoint-internal.h b/include/ust/tracepoint-internal.h new file mode 100644 index 0000000..6fcc491 --- /dev/null +++ b/include/ust/tracepoint-internal.h @@ -0,0 +1,86 @@ +#ifndef _UST_TRACEPOINT_INTERNAL_H +#define _UST_TRACEPOINT_INTERNAL_H + +/* + * tracepoint-internal.h + * + * Tracepoint internal header. + * + * 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 + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Heavily inspired from the Linux Kernel Markers. + * + * Ported to userspace by Pierre-Marc Fournier. + */ + +#include +#include +#include + +extern void tracepoint_update_probe_range(struct tracepoint * const *begin, + struct tracepoint * const *end); + +extern int tracepoint_probe_register_noupdate(const char *name, void *probe, + void *data); +extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe, + void *data); +extern void tracepoint_probe_update_all(void); + +struct tracepoint_iter { + struct tracepoint_lib *lib; + struct tracepoint * const *tracepoint; +}; + +extern void tracepoint_iter_start(struct tracepoint_iter *iter); +extern void tracepoint_iter_next(struct tracepoint_iter *iter); +extern void tracepoint_iter_stop(struct tracepoint_iter *iter); +extern void tracepoint_iter_reset(struct tracepoint_iter *iter); +extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, + struct tracepoint * const *begin, struct tracepoint * const *end); + +/* + * tracepoint_synchronize_unregister must be called between the last tracepoint + * probe unregistration and the end of module exit to make sure there is no + * caller executing a probe when it is freed. + */ +static inline void tracepoint_synchronize_unregister(void) +{ + synchronize_rcu(); +} + +extern void lock_trace_events(void); +extern void unlock_trace_events(void); + +struct trace_event_iter { + struct trace_event_lib *lib; + struct trace_event * const *trace_event; +}; + +extern void trace_event_iter_start(struct trace_event_iter *iter); +extern void trace_event_iter_next(struct trace_event_iter *iter); +extern void trace_event_iter_reset(struct trace_event_iter *iter); + +extern int trace_event_get_iter_range(struct trace_event * const **trace_event, + struct trace_event * const *begin, + struct trace_event * const *end); + +extern void trace_event_update_process(void); +extern int is_trace_event_enabled(const char *channel, const char *name); + +#endif /* _UST_TRACEPOINT_INTERNAL_H */ diff --git a/include/ust/tracepoint.h b/include/ust/tracepoint.h index b11d69d..4d84ead 100644 --- a/include/ust/tracepoint.h +++ b/include/ust/tracepoint.h @@ -29,8 +29,6 @@ #include #include -struct tracepoint; - struct tracepoint_probe { void *func; void *data; @@ -42,24 +40,33 @@ struct tracepoint { struct tracepoint_probe *probes; }; -#define TP_PARAMS(args...) args -#define TP_PROTO(args...) args -#define TP_ARGS(args...) args - /* * Tracepoints should be added to the instrumented code using the * "tracepoint()" macro. */ #define tracepoint(name, args...) __trace_##name(args) -#define register_tracepoint(name, probe, data) \ - __register_trace_##name(probe, data) - -#define unregister_tracepoint(name, probe, data) \ - __unregister_trace_##name(probe, data) - -#define CONFIG_TRACEPOINTS -#ifdef CONFIG_TRACEPOINTS +/* + * Library should be made known to libust by declaring TRACEPOINT_LIB in + * the source file. (Usually at the end of the file, in the outermost + * scope). + */ +#define TRACEPOINT_LIB \ + extern struct tracepoint * const __start___tracepoints_ptrs[] __attribute__((weak, visibility("hidden"))); \ + extern struct tracepoint * const __stop___tracepoints_ptrs[] __attribute__((weak, visibility("hidden"))); \ + static struct tracepoint * __tracepoint_ptr_dummy \ + __attribute__((used, section("__tracepoints_ptrs"))); \ + static void __attribute__((constructor)) __tracepoints__init(void) \ + { \ + tracepoint_register_lib(__start___tracepoints_ptrs, \ + __stop___tracepoints_ptrs - \ + __start___tracepoints_ptrs); \ + } \ + \ + static void __attribute__((destructor)) __tracepoints__destroy(void) \ + { \ + tracepoint_unregister_lib(__start___tracepoints_ptrs); \ + } /* * it_func[0] is never NULL because there is at least one element in the array @@ -83,6 +90,10 @@ struct tracepoint { rcu_read_unlock(); \ } while (0) +#define TP_PARAMS(args...) args +#define TP_PROTO(args...) args +#define TP_ARGS(args...) args + #define __CHECK_TRACE(name, proto, args) \ do { \ if (unlikely(__tracepoint_##name.state)) \ @@ -105,63 +116,19 @@ struct tracepoint { static inline int \ __register_trace_##name(void (*probe)(data_proto), void *data) \ { \ - return tracepoint_probe_register(#name, (void *)probe, \ + return __tracepoint_probe_register(#name, (void *)probe,\ data); \ \ } \ static inline int \ __unregister_trace_##name(void (*probe)(data_proto), void *data)\ { \ - return tracepoint_probe_unregister(#name, (void *)probe, \ + return __tracepoint_probe_unregister(#name, (void *)probe, \ data); \ } /* - * __tracepoints_ptrs section is not const (read-only) to let the linker update - * the pointer, allowing PIC code. - */ -#define DEFINE_TRACEPOINT_FN(name, reg, unreg) \ - static const char __tpstrtab_##name[] \ - __attribute__((section("__tracepoints_strings"))) = #name; \ - struct tracepoint __tracepoint_##name \ - __attribute__((section("__tracepoints"))) = \ - { __tpstrtab_##name, 0, NULL }; \ - static struct tracepoint * __tracepoint_ptr_##name \ - __attribute__((used, section("__tracepoints_ptrs"))) = \ - &__tracepoint_##name; - -#define DEFINE_TRACEPOINT(name) \ - DEFINE_TRACEPOINT_FN(name, NULL, NULL) - -extern void tracepoint_update_probe_range(struct tracepoint * const *begin, - struct tracepoint * const *end); - -#else /* !CONFIG_TRACEPOINTS */ -#define __DECLARE_TRACEPOINT(name, proto, args) \ - static inline void trace_##name(proto) \ - { } \ - static inline void _trace_##name(proto) \ - { } \ - static inline int __register_trace_##name(void (*probe)(proto), void *data) \ - { \ - return -ENOSYS; \ - } \ - static inline int __unregister_trace_##name(void (*probe)(proto), void *data) \ - { \ - return -ENOSYS; \ - } - -#define DEFINE_TRACEPOINT(name) -#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) -#define EXPORT_TRACEPOINT_SYMBOL(name) - -static inline void tracepoint_update_probe_range(struct tracepoint *begin, - struct tracepoint *end) -{ } -#endif /* CONFIG_TRACEPOINTS */ - -/* - * The need for the DECLARE_TRACEPOINT_NOARGS() is to handle the prototype + * The need for the _DECLARE_TRACEPOINT_NOARGS() is to handle the prototype * (void). "void" is a special value in a function prototype and can * not be combined with other arguments. Since the DECLARE_TRACEPOINT() * macro adds a data element at the beginning of the prototype, @@ -174,53 +141,47 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, * DECLARE_TRACEPOINT() passes "proto" as the tracepoint protoype and * "void *__tp_cb_data, proto" as the callback prototype. */ -#define DECLARE_TRACEPOINT_NOARGS(name) \ - __DECLARE_TRACEPOINT(name, void, , void *__tp_cb_data, __tp_cb_data) +#define _DECLARE_TRACEPOINT_NOARGS(name) \ + __DECLARE_TRACEPOINT(name, void, , void *__tp_cb_data, __tp_cb_data) -#define DECLARE_TRACEPOINT(name, proto, args) \ - __DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args),\ - TP_PARAMS(void *__tp_cb_data, proto), \ - TP_PARAMS(__tp_cb_data, args)) +#define _DECLARE_TRACEPOINT(name, proto, args) \ + __DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args), \ + TP_PARAMS(void *__tp_cb_data, proto), \ + TP_PARAMS(__tp_cb_data, args)) /* - * Connect a probe to a tracepoint. - * Internal API, should not be used directly. - */ -extern int tracepoint_probe_register(const char *name, void *probe, void *data); - -/* - * Disconnect a probe from a tracepoint. - * Internal API, should not be used directly. + * __tracepoints_ptrs section is not const (read-only) to let the linker update + * the pointer, allowing PIC code. */ -extern int tracepoint_probe_unregister(const char *name, void *probe, void *data); +#define _DEFINE_TRACEPOINT(name) \ + static const char __tpstrtab_##name[] \ + __attribute__((section("__tracepoints_strings"))) = #name; \ + struct tracepoint __tracepoint_##name \ + __attribute__((section("__tracepoints"))) = \ + { __tpstrtab_##name, 0, NULL }; \ + static struct tracepoint * __tracepoint_ptr_##name \ + __attribute__((used, section("__tracepoints_ptrs"))) = \ + &__tracepoint_##name; -extern int tracepoint_probe_register_noupdate(const char *name, void *probe, - void *data); -extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe, - void *data); -extern void tracepoint_probe_update_all(void); -struct tracepoint_iter { - struct tracepoint_lib *lib; - struct tracepoint * const *tracepoint; -}; +#define __register_tracepoint(name, probe, data) \ + __register_trace_##name(probe, data) +#define __unregister_tracepoint(name, probe, data) \ + __unregister_trace_##name(probe, data) -extern void tracepoint_iter_start(struct tracepoint_iter *iter); -extern void tracepoint_iter_next(struct tracepoint_iter *iter); -extern void tracepoint_iter_stop(struct tracepoint_iter *iter); -extern void tracepoint_iter_reset(struct tracepoint_iter *iter); -extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, - struct tracepoint * const *begin, struct tracepoint * const *end); +/* + * Connect a probe to a tracepoint. + * Internal API. + */ +extern +int __tracepoint_probe_register(const char *name, void *probe, void *data); /* - * tracepoint_synchronize_unregister must be called between the last tracepoint - * probe unregistration and the end of module exit to make sure there is no - * caller executing a probe when it is freed. + * Disconnect a probe from a tracepoint. + * Internal API. */ -static inline void tracepoint_synchronize_unregister(void) -{ -//ust// synchronize_sched(); -} +extern +int __tracepoint_probe_unregister(const char *name, void *probe, void *data); struct tracepoint_lib { struct tracepoint * const *tracepoints_start; @@ -228,26 +189,11 @@ struct tracepoint_lib { struct cds_list_head list; }; -extern int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, - int tracepoints_count); -extern int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start); - -#define TRACEPOINT_LIB \ - extern struct tracepoint * const __start___tracepoints_ptrs[] __attribute__((weak, visibility("hidden"))); \ - extern struct tracepoint * const __stop___tracepoints_ptrs[] __attribute__((weak, visibility("hidden"))); \ - static struct tracepoint * __tracepoint_ptr_dummy \ - __attribute__((used, section("__tracepoints_ptrs"))); \ - static void __attribute__((constructor)) __tracepoints__init(void) \ - { \ - tracepoint_register_lib(__start___tracepoints_ptrs, \ - __stop___tracepoints_ptrs - \ - __start___tracepoints_ptrs); \ - } \ - \ - static void __attribute__((destructor)) __tracepoints__destroy(void) \ - { \ - tracepoint_unregister_lib(__start___tracepoints_ptrs); \ - } +extern +int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, + int tracepoints_count); +extern +int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start); #ifndef TRACEPOINT_EVENT @@ -284,108 +230,61 @@ extern int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_star * * * * * Fast binary tracing: define the trace record via - * * TP_STRUCT__entry(). You can think about it like a + * * TP_FIELDS(). 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' + * * tp_field(pid_t, prev_pid, prev->pid) is equivalent + * * to a standard declaraton: * * - * * __field(pid_t, prev_prid) is equivalent to a standard declariton: + * * pid_t prev_pid; * * - * * pid_t prev_pid; + * * followed by an assignment: * * - * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to: + * * prev_pid = prev->pid; * * - * * char prev_comm[TASK_COMM_LEN]; + * * tp_array(char, prev_comm, TASK_COMM_LEN, prev->comm) is + * * equivalent to: * * - * - * 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 ) - * ), - * + * * char prev_comm[TASK_COMM_LEN]; * * - * * 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. + * * followed by an assignment: * * - * * Note: this C code will execute every time a trace event - * * happens, on an active tracepoint. + * * memcpy(prev_comm, prev->comm, TASK_COMM_LEN); * * * - * 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; + * TP_FIELDS( + * tp_array(char, prev_comm, TASK_COMM_LEN, prev->comm) + * tp_field(pid_t, prev_pid, prev->pid) + * tp_field(int, prev_prio, prev->prio) + * tp_array(char, next_comm, TASK_COMM_LEN, next->comm) + * tp_field(pid_t, next_pid, next->pid) + * tp_field(int, 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 - * TRACEPOINT_EVENT_FN to perform any (un)registration work. */ -struct trace_event { - const char *name; - int (*regfunc)(void *data); - int (*unregfunc)(void *data); -}; +#define TRACEPOINT_EVENT(name, proto, args, fields) \ + _DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args)) -struct trace_event_lib { - struct trace_event * const *trace_events_start; - int trace_events_count; - struct cds_list_head list; -}; +#define TRACEPOINT_EVENT_CLASS(name, proto, args, fields) +#define TRACEPOINT_EVENT_INSTANCE(template, name, proto, args) \ + _DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args)) -struct trace_event_iter { - struct trace_event_lib *lib; - struct trace_event * const *trace_event; -}; - -extern void lock_trace_events(void); -extern void unlock_trace_events(void); - -extern void trace_event_iter_start(struct trace_event_iter *iter); -extern void trace_event_iter_next(struct trace_event_iter *iter); -extern void trace_event_iter_reset(struct trace_event_iter *iter); - -extern int trace_event_get_iter_range(struct trace_event * const **trace_event, - struct trace_event * const *begin, - struct trace_event * const *end); +/* + * Declaration of tracepoints that take 0 argument. + */ +#define TRACEPOINT_EVENT_NOARGS(name, fields) \ + _DECLARE_TRACEPOINT_NOARGS(name) -extern void trace_event_update_process(void); -extern int is_trace_event_enabled(const char *channel, const char *name); +#define TRACEPOINT_EVENT_CLASS_NOARGS(name, fields) +#define TRACEPOINT_EVENT_INSTANCE_NOARGS(template, name) \ + _DECLARE_TRACEPOINT_NOARGS(name) -extern int trace_event_register_lib(struct trace_event * const *start_trace_events, - int trace_event_count); -extern int trace_event_unregister_lib(struct trace_event * const *start_trace_events); #define TRACEPOINT_EVENT_LIB \ extern struct trace_event * const __start___trace_events_ptrs[] \ @@ -408,19 +307,22 @@ extern int trace_event_unregister_lib(struct trace_event * const *start_trace_ev trace_event_unregister_lib(__start___trace_events_ptrs);\ } -#define DECLARE_TRACEPOINT_EVENT_CLASS(name, proto, args, tstruct, assign, print) -#define DEFINE_TRACEPOINT_EVENT(template, name, proto, args) \ - DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args)) -#define DEFINE_TRACEPOINT_EVENT_PRINT(template, name, proto, args, print)\ - DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args)) +struct trace_event { + const char *name; +}; -#define TRACEPOINT_EVENT(name, proto, args, struct, assign, print) \ - DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args)) -#define TRACEPOINT_EVENT_FN(name, proto, args, struct, \ - assign, print, reg, unreg) \ - DECLARE_TRACEPOINT(name, TP_PARAMS(proto), TP_PARAMS(args)) +struct trace_event_lib { + struct trace_event * const *trace_events_start; + int trace_events_count; + struct cds_list_head list; +}; -#endif /* ifdef TRACEPOINT_EVENT (see note above) */ +extern +int trace_event_register_lib(struct trace_event * const *start_trace_events, + int trace_event_count); +extern +int trace_event_unregister_lib(struct trace_event * const *start_trace_events); +#endif /* #ifndef TRACEPOINT_EVENT */ #endif /* _UST_TRACEPOINT_H */ diff --git a/include/ust/ust_trace.h b/include/ust/ust_trace.h index dfbe166..fe27da2 100644 --- a/include/ust/ust_trace.h +++ b/include/ust/ust_trace.h @@ -19,67 +19,69 @@ */ /* - * This whole file is currently a dummy, mapping a TRACEPOINT_EVENT - * to a printf + * This whole file is currently a dummy. */ #include -/* - * Stage 1. Create a struct and a printf calling function - * that is connected to the tracepoint at load time. - */ #undef TRACEPOINT_EVENT -#define TRACEPOINT_EVENT(name, proto, args, tstruct, assign, print) \ - DECLARE_TRACEPOINT_EVENT_CLASS(name, \ - TP_PARAMS(proto), \ - TP_PARAMS(args), \ - TP_PARAMS(tstruct), \ - TP_PARAMS(assign), \ - TP_PARAMS(print)); \ - DEFINE_TRACEPOINT_EVENT(name, name, TP_PARAMS(proto), TP_PARAMS(args)); - -#undef __field -#define __field(type, item) type item; +#define TRACEPOINT_EVENT(name, proto, args, fields) \ + TRACEPOINT_EVENT_CLASS(name, \ + TP_PARAMS(proto), \ + TP_PARAMS(args), \ + TP_PARAMS(fields)); \ + TRACEPOINT_EVENT_INSTANCE(name, name, TP_PARAMS(proto), \ + TP_PARAMS(args)); -#undef TP_STRUCT__entry -#define TP_STRUCT__entry(args...) args +#undef TRACEPOINT_EVENT_NOARGS +#define TRACEPOINT_EVENT_NOARGS(name, fields) \ + TRACEPOINT_EVENT_CLASS_NOARGS(name, \ + TP_PARAMS(fields)); \ + TRACEPOINT_EVENT_INSTANCE_NOARGS(name, name); -#undef TP_printf -#define TP_printf(fmt, args...) fmt "\n", args +#undef tp_field +#define tp_field(type, item, src) type item; -#undef TP_fast_assign -#define TP_fast_assign(args...) args +#undef TP_FIELDS +#define TP_FIELDS(args...) args -#undef DEFINE_TRACEPOINT_EVENT -#define DEFINE_TRACEPOINT_EVENT(template, name, proto, args) +#undef TRACEPOINT_EVENT_INSTANCE +#define TRACEPOINT_EVENT_INSTANCE(template, name, proto, args) +#undef TRACEPOINT_EVENT_INSTANCE_NOARGS +#define TRACEPOINT_EVENT_INSTANCE_NOARGS(template, name) -#undef DECLARE_TRACEPOINT_EVENT_CLASS -#define DECLARE_TRACEPOINT_EVENT_CLASS(name, proto, args, tstruct, assign, print) \ +#undef TRACEPOINT_EVENT_CLASS +#define TRACEPOINT_EVENT_CLASS(name, proto, args, fields) \ struct trace_raw_##name { \ - tstruct \ + fields \ }; \ static void trace_printf_##name(void *dummy, proto) \ { \ - struct trace_raw_##name entry_struct, *__entry; \ - __entry = &entry_struct; \ - { assign }; \ - \ - printf(print); \ } \ - static inline int register_event_##name(void *data) \ + struct trace_event __event_##name = { \ + __tpstrtab_##name, \ + }; \ + static struct trace_event * const __event_ptrs_##name \ + __attribute__((used, section("__trace_events_ptrs"))) = \ + &__event_##name; \ + \ + static void __attribute__((constructor)) init_##name() \ { \ - return register_tracepoint(name, trace_printf_##name, data); \ - } \ - static inline int unregister_event_##name(void *data) \ + void *dummy = NULL; \ + __register_tracepoint(name, trace_printf_##name, dummy);\ + } + +#undef TRACEPOINT_EVENT_CLASS_NOARGS +#define TRACEPOINT_EVENT_CLASS_NOARGS(name, fields) \ + struct trace_raw_##name { \ + fields \ + }; \ + static void trace_printf_##name(void *dummy) \ { \ - return unregister_tracepoint(name, trace_printf_##name, data); \ } \ struct trace_event __event_##name = { \ __tpstrtab_##name, \ - register_event_##name, \ - unregister_event_##name \ }; \ static struct trace_event * const __event_ptrs_##name \ __attribute__((used, section("__trace_events_ptrs"))) = \ @@ -88,8 +90,7 @@ static void __attribute__((constructor)) init_##name() \ { \ void *dummy = NULL; \ - register_tracepoint(name, trace_printf_##name, dummy); \ + __register_tracepoint(name, trace_printf_##name, dummy);\ } - #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) diff --git a/libust/marker.c b/libust/marker.c index 9599975..0149e68 100644 --- a/libust/marker.c +++ b/libust/marker.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "usterr_signal_safe.h" #include "channels.h" diff --git a/libust/trace_event.c b/libust/trace_event.c index a605901..6b30b68 100644 --- a/libust/trace_event.c +++ b/libust/trace_event.c @@ -20,6 +20,7 @@ #define _LGPL_SOURCE #include #include +#include #include #include #include diff --git a/libust/tracectl.c b/libust/tracectl.c index 2f45d6b..bd640c3 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include "tracer.h" diff --git a/libust/tracepoint.c b/libust/tracepoint.c index 737e5f5..6a8795b 100644 --- a/libust/tracepoint.c +++ b/libust/tracepoint.c @@ -22,6 +22,7 @@ #define _LGPL_SOURCE #include #include +#include #include #include #include @@ -354,14 +355,14 @@ tracepoint_add_probe(const char *name, void *probe, void *data) } /** - * tracepoint_probe_register - Connect a probe to a tracepoint + * __tracepoint_probe_register - Connect a probe to a tracepoint * @name: tracepoint name * @probe: probe handler * * Returns 0 if ok, error value on error. * The probe address must at least be aligned on the architecture pointer size. */ -int tracepoint_probe_register(const char *name, void *probe, void *data) +int __tracepoint_probe_register(const char *name, void *probe, void *data) { void *old; @@ -375,7 +376,6 @@ int tracepoint_probe_register(const char *name, void *probe, void *data) release_probes(old); return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register); static void *tracepoint_remove_probe(const char *name, void *probe, void *data) { @@ -404,7 +404,7 @@ static void *tracepoint_remove_probe(const char *name, void *probe, void *data) * itself uses stop_machine(), which insures that every preempt disabled section * have finished. */ -int tracepoint_probe_unregister(const char *name, void *probe, void *data) +int __tracepoint_probe_unregister(const char *name, void *probe, void *data) { void *old; @@ -418,7 +418,6 @@ int tracepoint_probe_unregister(const char *name, void *probe, void *data) release_probes(old); return 0; } -//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_unregister); static CDS_LIST_HEAD(old_probes); static int need_update; diff --git a/tests/hello/hello.c b/tests/hello/hello.c index a786fbf..bb44773 100644 --- a/tests/hello/hello.c +++ b/tests/hello/hello.c @@ -1,4 +1,6 @@ -/* Copyright (C) 2009 Pierre-Marc Fournier +/* + * Copyright (C) 2009 Pierre-Marc Fournier + * Copyright (C) 2011 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,7 +43,7 @@ int init_int_handler(void) struct sigaction act; result = sigemptyset(&act.sa_mask); - if(result == -1) { + if (result == -1) { PERROR("sigemptyset"); return -1; } @@ -53,7 +55,7 @@ int init_int_handler(void) * syscalls to disturb the traced program as little as possible. */ result = sigaction(SIGINT, &act, NULL); - if(result == -1) { + if (result == -1) { PERROR("sigaction"); return -1; } @@ -70,7 +72,7 @@ int main() printf("Hello, World!\n"); sleep(1); - for(i=0; i<50; i++) { + for (i = 0; i < 50; i++) { ust_marker(bar, "str %s", "FOOBAZ"); ust_marker(bar2, "number1 %d number2 %d", 53, 9800); tracepoint(hello_tptest, i); diff --git a/tests/hello/tp.c b/tests/hello/tp.c index 05cd7a2..dfe06dd 100644 --- a/tests/hello/tp.c +++ b/tests/hello/tp.c @@ -1,4 +1,6 @@ -/* Copyright (C) 2009 Pierre-Marc Fournier +/* + * Copyright (C) 2009 Pierre-Marc Fournier + * Copyright (C) 2011 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,10 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "tp.h" #include #include "usterr.h" +#define TRACEPOINT_CREATE_PROBES +#include "tp.h" + struct hello_trace_struct { char *message; }; @@ -27,12 +31,10 @@ struct hello_trace_struct hello_struct = { .message = "ehlo\n", }; -DEFINE_TRACEPOINT(hello_tptest); - void tptest_probe(void *data, int anint) { struct hello_trace_struct *hello; - hello=(struct hello_trace_struct *)data; + hello = (struct hello_trace_struct *)data; DBG("in tracepoint probe..."); printf("this is the message: %s\n", hello->message); } @@ -44,6 +46,10 @@ void tptest2_probe(void *data) static void __attribute__((constructor)) init() { DBG("connecting tracepoint...\n"); - register_tracepoint(hello_tptest, tptest_probe, &hello_struct); - register_tracepoint(hello_tptest2, tptest2_probe, &hello_struct); + /* + * Note: this is an internal API that will be used within + * TRACEPOINT_EVENT only eventually. + */ + __register_tracepoint(hello_tptest, tptest_probe, &hello_struct); + __register_tracepoint(hello_tptest2, tptest2_probe, &hello_struct); } diff --git a/tests/hello/tp.h b/tests/hello/tp.h index 833cb40..d6d8d99 100644 --- a/tests/hello/tp.h +++ b/tests/hello/tp.h @@ -1,4 +1,11 @@ -/* Copyright (C) 2009 Pierre-Marc Fournier +#undef TRACE_SYSTEM +#define TRACE_SYSTEM tp + +#if !defined(_TRACE_TP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_TP_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,8 +24,20 @@ #include -DECLARE_TRACEPOINT(hello_tptest, - TP_PROTO(int anint), - TP_ARGS(anint)); +TRACEPOINT_EVENT(hello_tptest, + TP_PROTO(int anint), + TP_ARGS(anint), + TP_FIELDS()); + +TRACEPOINT_EVENT_NOARGS(hello_tptest2, + TP_FIELDS()); + +#endif /* _TRACE_TP_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE tp -DECLARE_TRACEPOINT_NOARGS(hello_tptest2); +/* This part must be outside protection */ +#include diff --git a/tests/register_test/register_test.c b/tests/register_test/register_test.c index 8198a2c..1221e0a 100644 --- a/tests/register_test/register_test.c +++ b/tests/register_test/register_test.c @@ -1,4 +1,6 @@ -/* Copyright (C) 2010 Nils Carlson +/* + * Copyright (C) 2010 Nils Carlson + * Copyright (C) 2011 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,10 +29,9 @@ #include #include "usterr.h" -#include "tp.h" - -DEFINE_TRACEPOINT(hello_tptest); +#define TRACEPOINT_CREATE_PROBES +#include "tp.h" struct hello_trace_struct { char *message; @@ -44,7 +45,7 @@ void tptest_probe(void *data, int anint) { struct hello_trace_struct *hello; char message[30]; - hello=(struct hello_trace_struct *)data; + hello = (struct hello_trace_struct *)data; //printf("this is the message: %s\n", hello->message); snprintf(message, 30, "this is the %s\n", hello->message); } @@ -52,27 +53,26 @@ void tptest_probe(void *data, int anint) #define HELLO_LENGTH 100 -static void * register_thread_main(void *data) +static void *register_thread_main(void *data) { int i, j = 0; - struct hello_trace_struct hello[HELLO_LENGTH]; - for (i=0; i * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,6 +24,17 @@ #include -DECLARE_TRACEPOINT(hello_tptest, - TP_PROTO(int anint), - TP_ARGS(anint)); +TRACEPOINT_EVENT(hello_tptest, + TP_PROTO(int anint), + TP_ARGS(anint), + TP_FIELDS()); + +#endif /* _TRACE_TP_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE tp + +/* This part must be outside protection */ +#include diff --git a/tests/trace_event/trace_event_test.c b/tests/trace_event/trace_event_test.c index 8e87846..4c98c95 100644 --- a/tests/trace_event/trace_event_test.c +++ b/tests/trace_event/trace_event_test.c @@ -1,4 +1,6 @@ -/* Copyright (C) 2010 Nils Carlson +/* + * Copyright (C) 2010 Nils Carlson + * Copyright (C) 2011 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,6 +16,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #include #include @@ -22,9 +25,10 @@ int main(int argc, char * argv[]) { - static unsigned long time, i; - for (i=0; i<10; i++) { - time=trace_clock_read64(); + unsigned long time, i; + + for (i = 0; i < 10; i++) { + time = trace_clock_read64(); tracepoint(test, time, i); } return 0; diff --git a/tests/trace_event/trace_event_test.h b/tests/trace_event/trace_event_test.h index 38f0b46..3a126d4 100644 --- a/tests/trace_event/trace_event_test.h +++ b/tests/trace_event/trace_event_test.h @@ -1,4 +1,12 @@ -/* Copyright (C) 2010 Nils Carlson +#undef TRACE_SYSTEM +#define TRACE_SYSTEM trace_event_test + +#if !defined(_TRACEPOINT_EVENT_TEST_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACEPOINT_EVENT_TEST_H + +/* + * Copyright (C) 2010 Nils Carlson + * Copyright (C) 2011 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,11 +22,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM trace_event_test - -#if !defined(_TRACEPOINT_EVENT_TEST_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACEPOINT_EVENT_TEST_H #include @@ -28,17 +31,10 @@ TRACEPOINT_EVENT(test, TP_ARGS(time, count), - TP_STRUCT__entry( - __field( unsigned long, time ) - __field( unsigned long, count ) - ), - - TP_fast_assign( - __entry->time = time; - __entry->count = count; - ), - - TP_printf("time=%lu count=%lu", __entry->time, __entry->count) + TP_FIELDS( + tp_field(unsigned long, time, time) + tp_field(unsigned long, count, count) + ) ); #endif /* _TRACEPOINT_EVENT_TEST_H */ diff --git a/tests/tracepoint/benchmark/tracepoint_benchmark.c b/tests/tracepoint/benchmark/tracepoint_benchmark.c index 50a1847..45f7d3c 100644 --- a/tests/tracepoint/benchmark/tracepoint_benchmark.c +++ b/tests/tracepoint/benchmark/tracepoint_benchmark.c @@ -25,13 +25,13 @@ */ #include + +#define TRACEPOINT_CREATE_PROBES #include "tracepoint_benchmark.h" #include #define NR_EVENTS 10000000 -DEFINE_TRACEPOINT(ust_event); - void tp_probe(void *data, unsigned int p1); DEFINE_UST_MARKER_TP(event, ust_event, tp_probe, "p1 %u"); @@ -49,7 +49,7 @@ void tp_probe(void *data, unsigned int p1) static void __attribute__((constructor)) init() { - register_tracepoint(ust_event, tp_probe, NULL); + __register_tracepoint(ust_event, tp_probe, NULL); } void single_trace(unsigned int v) diff --git a/tests/tracepoint/benchmark/tracepoint_benchmark.h b/tests/tracepoint/benchmark/tracepoint_benchmark.h index f96f462..c5301d5 100644 --- a/tests/tracepoint/benchmark/tracepoint_benchmark.h +++ b/tests/tracepoint/benchmark/tracepoint_benchmark.h @@ -1,3 +1,40 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM tracepoint_benchmark + +#if !defined(_TRACE_TRACEPOINT_BENCHMARK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_TRACEPOINT_BENCHMARK_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + #include -DECLARE_TRACEPOINT(ust_event, TP_PROTO(unsigned int v), TP_ARGS(v)); +TRACEPOINT_EVENT(ust_event, + TP_PROTO(unsigned int v), + TP_ARGS(v), + TP_FIELDS()); + +#endif /* _TRACE_TRACEPOINT_BENCHMARK_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE tracepoint_benchmark + +/* This part must be outside protection */ +#include