~lttng/lttng-ust/lttng-ust

« back to all changes in this revision

Viewing changes to include/ust/tracepoint.h

  • Committer: Pierre-Marc Fournier
  • Date: 2009-10-27 22:58:15 UTC
  • mfrom: (232.1.5)
  • Revision ID: git-v1:aa08b4413291fabcbd1b1144377d37034ad361de
Merge branch 'for-pierre-marc' of git://git.infradead.org/users/jblunck/ust

Fixed conflicts:
        include/ust/marker.h

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _LINUX_TRACEPOINT_H
 
2
#define _LINUX_TRACEPOINT_H
 
3
 
 
4
/*
 
5
 * Copyright (C) 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
 
6
 * Copyright (C) 2009 Pierre-Marc Fournier
 
7
 *
 
8
 * This library is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public
 
10
 * License as published by the Free Software Foundation; either
 
11
 * version 2.1 of the License, or (at your option) any later version.
 
12
 *
 
13
 * This library is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with this library; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 
21
 *
 
22
 * Heavily inspired from the Linux Kernel Markers.
 
23
 *
 
24
 * Ported to userspace by Pierre-Marc Fournier.
 
25
 */
 
26
 
 
27
//#include <linux/immediate.h>
 
28
//#include <linux/types.h>
 
29
//#include <linux/rcupdate.h>
 
30
 
 
31
#define _LGPL_SOURCE
 
32
#include <urcu-bp.h>
 
33
 
 
34
#include <ust/immediate.h>
 
35
#include <ust/kernelcompat.h>
 
36
 
 
37
struct module;
 
38
struct tracepoint;
 
39
 
 
40
struct tracepoint {
 
41
        const char *name;               /* Tracepoint name */
 
42
        DEFINE_IMV(char, state);        /* State. */
 
43
        void **funcs;
 
44
} __attribute__((aligned(32)));         /*
 
45
                                         * Aligned on 32 bytes because it is
 
46
                                         * globally visible and gcc happily
 
47
                                         * align these on the structure size.
 
48
                                         * Keep in sync with vmlinux.lds.h.
 
49
                                         */
 
50
 
 
51
#define TPPROTO(args...)        args
 
52
#define TPARGS(args...)         args
 
53
 
 
54
#define CONFIG_TRACEPOINTS
 
55
#ifdef CONFIG_TRACEPOINTS
 
56
 
 
57
/*
 
58
 * it_func[0] is never NULL because there is at least one element in the array
 
59
 * when the array itself is non NULL.
 
60
 */
 
61
#define __DO_TRACE(tp, proto, args)                                     \
 
62
        do {                                                            \
 
63
                void **it_func;                                         \
 
64
                                                                        \
 
65
                rcu_read_lock(); /*ust rcu_read_lock_sched_notrace();   */                      \
 
66
                it_func = rcu_dereference((tp)->funcs);                 \
 
67
                if (it_func) {                                          \
 
68
                        do {                                            \
 
69
                                ((void(*)(proto))(*it_func))(args);     \
 
70
                        } while (*(++it_func));                         \
 
71
                }                                                       \
 
72
                rcu_read_unlock(); /*ust rcu_read_unlock_sched_notrace(); */                    \
 
73
        } while (0)
 
74
 
 
75
#define __CHECK_TRACE(name, generic, proto, args)                       \
 
76
        do {                                                            \
 
77
                if (!generic) {                                         \
 
78
                        if (unlikely(imv_read(__tracepoint_##name.state))) \
 
79
                                __DO_TRACE(&__tracepoint_##name,        \
 
80
                                        TPPROTO(proto), TPARGS(args));  \
 
81
                } else {                                                \
 
82
                        if (unlikely(_imv_read(__tracepoint_##name.state))) \
 
83
                                __DO_TRACE(&__tracepoint_##name,        \
 
84
                                        TPPROTO(proto), TPARGS(args));  \
 
85
                }                                                       \
 
86
        } while (0)
 
87
 
 
88
/*
 
89
 * Make sure the alignment of the structure in the __tracepoints section will
 
90
 * not add unwanted padding between the beginning of the section and the
 
91
 * structure. Force alignment to the same alignment as the section start.
 
92
 *
 
93
 * The "generic" argument, passed to the declared __trace_##name inline
 
94
 * function controls which tracepoint enabling mechanism must be used.
 
95
 * If generic is true, a variable read is used.
 
96
 * If generic is false, immediate values are used.
 
97
 */
 
98
#define DECLARE_TRACE(name, proto, args)                                \
 
99
        extern struct tracepoint __tracepoint_##name;                   \
 
100
        static inline void trace_##name(proto)                          \
 
101
        {                                                               \
 
102
                __CHECK_TRACE(name, 0, TPPROTO(proto), TPARGS(args));   \
 
103
        }                                                               \
 
104
        static inline void _trace_##name(proto)                         \
 
105
        {                                                               \
 
106
                __CHECK_TRACE(name, 1, TPPROTO(proto), TPARGS(args));   \
 
107
        }                                                               \
 
108
        static inline int register_trace_##name(void (*probe)(proto))   \
 
109
        {                                                               \
 
110
                return tracepoint_probe_register(#name, (void *)probe); \
 
111
        }                                                               \
 
112
        static inline int unregister_trace_##name(void (*probe)(proto)) \
 
113
        {                                                               \
 
114
                return tracepoint_probe_unregister(#name, (void *)probe);\
 
115
        }
 
116
 
 
117
#define DEFINE_TRACE(name)                                              \
 
118
        static const char __tpstrtab_##name[]                           \
 
119
        __attribute__((section("__tracepoints_strings"))) = #name;      \
 
120
        struct tracepoint __tracepoint_##name                           \
 
121
        __attribute__((section("__tracepoints"), aligned(32))) =        \
 
122
                { __tpstrtab_##name, 0, NULL }
 
123
 
 
124
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)                              \
 
125
        EXPORT_SYMBOL_GPL(__tracepoint_##name)
 
126
#define EXPORT_TRACEPOINT_SYMBOL(name)                                  \
 
127
        EXPORT_SYMBOL(__tracepoint_##name)
 
128
 
 
129
extern void tracepoint_update_probe_range(struct tracepoint *begin,
 
130
        struct tracepoint *end);
 
131
 
 
132
#else /* !CONFIG_TRACEPOINTS */
 
133
#define DECLARE_TRACE(name, proto, args)                                \
 
134
        static inline void trace_##name(proto)                          \
 
135
        { }                                                             \
 
136
        static inline void _trace_##name(proto)                         \
 
137
        { }                                                             \
 
138
        static inline int register_trace_##name(void (*probe)(proto))   \
 
139
        {                                                               \
 
140
                return -ENOSYS;                                         \
 
141
        }                                                               \
 
142
        static inline int unregister_trace_##name(void (*probe)(proto)) \
 
143
        {                                                               \
 
144
                return -ENOSYS;                                         \
 
145
        }
 
146
 
 
147
#define DEFINE_TRACE(name)
 
148
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
 
149
#define EXPORT_TRACEPOINT_SYMBOL(name)
 
150
 
 
151
static inline void tracepoint_update_probe_range(struct tracepoint *begin,
 
152
        struct tracepoint *end)
 
153
{ }
 
154
#endif /* CONFIG_TRACEPOINTS */
 
155
 
 
156
/*
 
157
 * Connect a probe to a tracepoint.
 
158
 * Internal API, should not be used directly.
 
159
 */
 
160
extern int tracepoint_probe_register(const char *name, void *probe);
 
161
 
 
162
/*
 
163
 * Disconnect a probe from a tracepoint.
 
164
 * Internal API, should not be used directly.
 
165
 */
 
166
extern int tracepoint_probe_unregister(const char *name, void *probe);
 
167
 
 
168
extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
 
169
extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
 
170
extern void tracepoint_probe_update_all(void);
 
171
 
 
172
struct tracepoint_iter {
 
173
//ust// struct module *module;
 
174
        struct tracepoint_lib *lib;
 
175
        struct tracepoint *tracepoint;
 
176
};
 
177
 
 
178
extern void tracepoint_iter_start(struct tracepoint_iter *iter);
 
179
extern void tracepoint_iter_next(struct tracepoint_iter *iter);
 
180
extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
 
181
extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
 
182
extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
 
183
        struct tracepoint *begin, struct tracepoint *end);
 
184
 
 
185
/*
 
186
 * tracepoint_synchronize_unregister must be called between the last tracepoint
 
187
 * probe unregistration and the end of module exit to make sure there is no
 
188
 * caller executing a probe when it is freed.
 
189
 */
 
190
static inline void tracepoint_synchronize_unregister(void)
 
191
{
 
192
//ust// synchronize_sched();
 
193
}
 
194
 
 
195
struct tracepoint_lib {
 
196
        struct tracepoint *tracepoints_start;
 
197
        int tracepoints_count;
 
198
        struct list_head list;
 
199
};
 
200
 
 
201
extern int tracepoint_register_lib(struct tracepoint *tracepoints_start,
 
202
                                   int tracepoints_count);
 
203
 
 
204
#define TRACEPOINT_LIB                                                  \
 
205
        extern struct tracepoint __start___tracepoints[] __attribute__((visibility("hidden"))); \
 
206
        extern struct tracepoint __stop___tracepoints[] __attribute__((visibility("hidden"))); \
 
207
        static void __attribute__((constructor)) __tracepoints__init(void) \
 
208
        {                                                               \
 
209
                tracepoint_register_lib(__start___tracepoints,          \
 
210
                                        (((long)__stop___tracepoints)-((long)__start___tracepoints))/sizeof(struct tracepoint)); \
 
211
        }
 
212
 
 
213
#endif