~lttng/lttng-ust/lttng-ust

« back to all changes in this revision

Viewing changes to libust/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 "immediate.h"
35
 
#include "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