Fix marker/tracepoint/trace_event lib list: expected to be sorted
[lttng-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
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
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
20#include <errno.h>
21#include <ust/tracepoint.h>
22#include <ust/core.h>
23#include <ust/kcompat/kcompat.h>
24#include "usterr.h"
25
26#define _LGPL_SOURCE
27#include <urcu-bp.h>
28
29/* libraries that contain trace_events (struct trace_event_lib) */
0222e121 30static CDS_LIST_HEAD(libs);
0c0686ee
NC
31
32static DEFINE_MUTEX(trace_events_mutex);
33
34void lock_trace_events(void)
35{
36 pthread_mutex_lock(&trace_events_mutex);
37}
38
39void unlock_trace_events(void)
40{
41 pthread_mutex_unlock(&trace_events_mutex);
42}
43
44
45int lib_get_iter_trace_events(struct trace_event_iter *iter)
46{
47 struct trace_event_lib *iter_lib;
48 int found = 0;
49
0222e121 50 cds_list_for_each_entry(iter_lib, &libs, list) {
0c0686ee
NC
51 if (iter_lib < iter->lib)
52 continue;
53 else if (iter_lib > iter->lib)
54 iter->trace_event = NULL;
55 found = trace_event_get_iter_range(&iter->trace_event,
56 iter_lib->trace_events_start,
57 iter_lib->trace_events_start + iter_lib->trace_events_count);
58 if (found) {
59 iter->lib = iter_lib;
60 break;
61 }
62 }
63 return found;
64}
65
66/**
67 * trace_event_get_iter_range - Get a next trace_event iterator given a range.
68 * @trace_event: current trace_events (in), next trace_event (out)
69 * @begin: beginning of the range
70 * @end: end of the range
71 *
72 * Returns whether a next trace_event has been found (1) or not (0).
73 * Will return the first trace_event in the range if the input trace_event is NULL.
74 */
fc1caebc
MD
75int trace_event_get_iter_range(struct trace_event * const **trace_event,
76 struct trace_event * const *begin,
77 struct trace_event * const *end)
0c0686ee
NC
78{
79 if (!*trace_event && begin != end) {
80 *trace_event = begin;
81 return 1;
82 }
83 if (*trace_event >= begin && *trace_event < end)
84 return 1;
85 return 0;
86}
87
88static void trace_event_get_iter(struct trace_event_iter *iter)
89{
90 int found = 0;
91
92 found = lib_get_iter_trace_events(iter);
e2b46575 93
0c0686ee
NC
94 if (!found)
95 trace_event_iter_reset(iter);
96}
97
98void trace_event_iter_start(struct trace_event_iter *iter)
99{
100 trace_event_get_iter(iter);
101}
102
103void trace_event_iter_next(struct trace_event_iter *iter)
104{
105 iter->trace_event++;
106 /*
107 * iter->trace_event may be invalid because we blindly incremented it.
108 * Make sure it is valid by marshalling on the trace_events, getting the
109 * trace_events from following modules if necessary.
110 */
111 trace_event_get_iter(iter);
112}
113
114void trace_event_iter_reset(struct trace_event_iter *iter)
115{
116 iter->lib = NULL;
117 iter->trace_event = NULL;
118}
119
fc1caebc 120int trace_event_register_lib(struct trace_event * const *trace_events_start,
0c0686ee
NC
121 int trace_events_count)
122{
b467f7a7 123 struct trace_event_lib *pl, *iter;
0c0686ee
NC
124
125 pl = (struct trace_event_lib *) malloc(sizeof(struct trace_event_lib));
126
127 pl->trace_events_start = trace_events_start;
128 pl->trace_events_count = trace_events_count;
129
130 /* FIXME: maybe protect this with its own mutex? */
131 pthread_mutex_lock(&trace_events_mutex);
b467f7a7
MD
132 /*
133 * We sort the libs by struct lib pointer address.
134 */
135 cds_list_for_each_entry_reverse(iter, &libs, list) {
136 BUG_ON(iter == pl); /* Should never be in the list twice */
137 if (iter < pl) {
138 /* We belong to the location right after iter. */
139 cds_list_add(&pl->list, &iter->list);
140 goto lib_added;
141 }
142 }
143 /* We should be added at the head of the list */
0222e121 144 cds_list_add(&pl->list, &libs);
b467f7a7 145lib_added:
0c0686ee
NC
146 pthread_mutex_unlock(&trace_events_mutex);
147
148 DBG("just registered a trace_events section from %p and having %d trace_events", trace_events_start, trace_events_count);
149
150 return 0;
151}
152
fc1caebc 153int trace_event_unregister_lib(struct trace_event * const *trace_events_start)
0c0686ee
NC
154{
155 struct trace_event_lib *lib;
156
157 pthread_mutex_lock(&trace_events_mutex);
158
0222e121 159 cds_list_for_each_entry(lib, &libs, list) {
0c0686ee
NC
160 if(lib->trace_events_start == trace_events_start) {
161 struct trace_event_lib *lib2free = lib;
0222e121 162 cds_list_del(&lib->list);
0c0686ee
NC
163 free(lib2free);
164 break;
165 }
166 }
167
168 pthread_mutex_unlock(&trace_events_mutex);
169
170 return 0;
171}
This page took 0.036839 seconds and 4 git commands to generate.