Tracepoint and TRACEPOINT_EVENT API cleanup
[ust.git] / libust / trace_event.c
CommitLineData
0c0686ee
NC
1/*
2 * Copyright (C) 2010 Nils Carlson
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
f37142a4
MD
6 * License as published by the Free Software Foundation;
7 * version 2.1 of the License.
0c0686ee
NC
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 */
19
b0c4126f 20#define _LGPL_SOURCE
0c0686ee
NC
21#include <errno.h>
22#include <ust/tracepoint.h>
81614639 23#include <ust/tracepoint-internal.h>
0c0686ee
NC
24#include <ust/core.h>
25#include <ust/kcompat/kcompat.h>
0c0686ee
NC
26#include <urcu-bp.h>
27
b0c4126f
MD
28#include "usterr_signal_safe.h"
29
0c0686ee 30/* libraries that contain trace_events (struct trace_event_lib) */
0222e121 31static CDS_LIST_HEAD(libs);
0c0686ee
NC
32
33static DEFINE_MUTEX(trace_events_mutex);
34
35void lock_trace_events(void)
36{
37 pthread_mutex_lock(&trace_events_mutex);
38}
39
40void unlock_trace_events(void)
41{
42 pthread_mutex_unlock(&trace_events_mutex);
43}
44
45
46int lib_get_iter_trace_events(struct trace_event_iter *iter)
47{
48 struct trace_event_lib *iter_lib;
49 int found = 0;
50
0222e121 51 cds_list_for_each_entry(iter_lib, &libs, list) {
0c0686ee
NC
52 if (iter_lib < iter->lib)
53 continue;
54 else if (iter_lib > iter->lib)
55 iter->trace_event = NULL;
56 found = trace_event_get_iter_range(&iter->trace_event,
57 iter_lib->trace_events_start,
58 iter_lib->trace_events_start + iter_lib->trace_events_count);
59 if (found) {
60 iter->lib = iter_lib;
61 break;
62 }
63 }
64 return found;
65}
66
67/**
68 * trace_event_get_iter_range - Get a next trace_event iterator given a range.
69 * @trace_event: current trace_events (in), next trace_event (out)
70 * @begin: beginning of the range
71 * @end: end of the range
72 *
73 * Returns whether a next trace_event has been found (1) or not (0).
74 * Will return the first trace_event in the range if the input trace_event is NULL.
75 */
fc1caebc
MD
76int trace_event_get_iter_range(struct trace_event * const **trace_event,
77 struct trace_event * const *begin,
78 struct trace_event * const *end)
0c0686ee 79{
f08ebbe2 80 if (!*trace_event && begin != end)
0c0686ee 81 *trace_event = begin;
f08ebbe2
MD
82 while (*trace_event >= begin && *trace_event < end) {
83 if (!**trace_event)
84 (*trace_event)++; /* skip dummy */
85 else
86 return 1;
0c0686ee 87 }
0c0686ee
NC
88 return 0;
89}
90
91static void trace_event_get_iter(struct trace_event_iter *iter)
92{
93 int found = 0;
94
95 found = lib_get_iter_trace_events(iter);
e2b46575 96
0c0686ee
NC
97 if (!found)
98 trace_event_iter_reset(iter);
99}
100
101void trace_event_iter_start(struct trace_event_iter *iter)
102{
103 trace_event_get_iter(iter);
104}
105
106void trace_event_iter_next(struct trace_event_iter *iter)
107{
108 iter->trace_event++;
109 /*
110 * iter->trace_event may be invalid because we blindly incremented it.
111 * Make sure it is valid by marshalling on the trace_events, getting the
112 * trace_events from following modules if necessary.
113 */
114 trace_event_get_iter(iter);
115}
116
117void trace_event_iter_reset(struct trace_event_iter *iter)
118{
119 iter->lib = NULL;
120 iter->trace_event = NULL;
121}
122
fc1caebc 123int trace_event_register_lib(struct trace_event * const *trace_events_start,
0c0686ee
NC
124 int trace_events_count)
125{
b467f7a7 126 struct trace_event_lib *pl, *iter;
0c0686ee
NC
127
128 pl = (struct trace_event_lib *) malloc(sizeof(struct trace_event_lib));
129
130 pl->trace_events_start = trace_events_start;
131 pl->trace_events_count = trace_events_count;
132
133 /* FIXME: maybe protect this with its own mutex? */
134 pthread_mutex_lock(&trace_events_mutex);
b467f7a7
MD
135 /*
136 * We sort the libs by struct lib pointer address.
137 */
138 cds_list_for_each_entry_reverse(iter, &libs, list) {
139 BUG_ON(iter == pl); /* Should never be in the list twice */
140 if (iter < pl) {
141 /* We belong to the location right after iter. */
142 cds_list_add(&pl->list, &iter->list);
143 goto lib_added;
144 }
145 }
146 /* We should be added at the head of the list */
0222e121 147 cds_list_add(&pl->list, &libs);
b467f7a7 148lib_added:
0c0686ee
NC
149 pthread_mutex_unlock(&trace_events_mutex);
150
f08ebbe2 151 /* trace_events_count - 1: skip dummy */
3b297856 152 DBG("just registered a trace_events section from %p and having %d trace_events (minus dummy trace_event)", trace_events_start, trace_events_count);
0c0686ee
NC
153
154 return 0;
155}
156
fc1caebc 157int trace_event_unregister_lib(struct trace_event * const *trace_events_start)
0c0686ee
NC
158{
159 struct trace_event_lib *lib;
160
161 pthread_mutex_lock(&trace_events_mutex);
162
0222e121 163 cds_list_for_each_entry(lib, &libs, list) {
0c0686ee
NC
164 if(lib->trace_events_start == trace_events_start) {
165 struct trace_event_lib *lib2free = lib;
0222e121 166 cds_list_del(&lib->list);
0c0686ee
NC
167 free(lib2free);
168 break;
169 }
170 }
171
172 pthread_mutex_unlock(&trace_events_mutex);
173
174 return 0;
175}
This page took 0.034188 seconds and 4 git commands to generate.