Update version to 0.16
[ust.git] / libust / channels.c
CommitLineData
99054cee
PMF
1/*
2 * ltt/ltt-channels.c
3 *
4 * (C) Copyright 2008 - Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
5 *
6 * LTTng channel management.
7 *
8 * Author:
9 * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
8fc2d8db
PMF
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
99054cee
PMF
24 */
25
909bc43f 26#include <stdlib.h>
909bc43f 27#include <ust/marker.h>
535b0d0a 28#include <ust/marker-internal.h>
b6bf28ec 29#include "channels.h"
30ffe279 30#include "usterr_signal_safe.h"
99054cee
PMF
31
32/*
33 * ltt_channel_mutex may be nested inside the LTT trace mutex.
34 * ltt_channel_mutex mutex may be nested inside markers mutex.
35 */
36static DEFINE_MUTEX(ltt_channel_mutex);
0222e121 37static CDS_LIST_HEAD(ltt_channels);
99054cee
PMF
38/*
39 * Index of next channel in array. Makes sure that as long as a trace channel is
40 * allocated, no array index will be re-used when a channel is freed and then
41 * another channel is allocated. This index is cleared and the array indexeds
205f7ca7 42 * get reassigned when the index_urcu_ref goes back to 0, which indicates that no
99054cee
PMF
43 * more trace channels are allocated.
44 */
45static unsigned int free_index;
205f7ca7 46static struct urcu_ref index_urcu_ref; /* Keeps track of allocated trace channels */
99054cee 47
8649cd59
PMF
48int ust_channels_overwrite_by_default = 0;
49int ust_channels_request_collection_by_default = 1;
50
99054cee
PMF
51static struct ltt_channel_setting *lookup_channel(const char *name)
52{
53 struct ltt_channel_setting *iter;
54
0222e121 55 cds_list_for_each_entry(iter, &ltt_channels, list)
99054cee
PMF
56 if (strcmp(name, iter->name) == 0)
57 return iter;
58 return NULL;
59}
60
61/*
62 * Must be called when channel refcount falls to 0 _and_ also when the last
63 * trace is freed. This function is responsible for compacting the channel and
64 * event IDs when no users are active.
65 *
66 * Called with lock_markers() and channels mutex held.
67 */
205f7ca7 68static void release_channel_setting(struct urcu_ref *urcu_ref)
99054cee 69{
205f7ca7
DG
70 struct ltt_channel_setting *setting = _ust_container_of(urcu_ref,
71 struct ltt_channel_setting, urcu_ref);
99054cee
PMF
72 struct ltt_channel_setting *iter;
73
205f7ca7
DG
74 if (uatomic_read(&index_urcu_ref.refcount) == 0
75 && uatomic_read(&setting->urcu_ref.refcount) == 0) {
0222e121 76 cds_list_del(&setting->list);
909bc43f 77 free(setting);
99054cee
PMF
78
79 free_index = 0;
0222e121 80 cds_list_for_each_entry(iter, &ltt_channels, list) {
99054cee
PMF
81 iter->index = free_index++;
82 iter->free_event_id = 0;
83 }
909bc43f 84 /* FIXME: why not run this? */
b6bf28ec 85//ust// markers_compact_event_ids();
99054cee
PMF
86 }
87}
88
89/*
90 * Perform channel index compaction when the last trace channel is freed.
91 *
92 * Called with lock_markers() and channels mutex held.
93 */
205f7ca7 94static void release_trace_channel(struct urcu_ref *urcu_ref)
99054cee
PMF
95{
96 struct ltt_channel_setting *iter, *n;
97
0222e121 98 cds_list_for_each_entry_safe(iter, n, &ltt_channels, list)
205f7ca7 99 release_channel_setting(&iter->urcu_ref);
99054cee
PMF
100}
101
102/**
103 * ltt_channels_register - Register a trace channel.
104 * @name: channel name
105 *
106 * Uses refcounting.
107 */
108int ltt_channels_register(const char *name)
109{
110 struct ltt_channel_setting *setting;
111 int ret = 0;
112
f7b16408 113 pthread_mutex_lock(&ltt_channel_mutex);
99054cee
PMF
114 setting = lookup_channel(name);
115 if (setting) {
205f7ca7
DG
116 if (uatomic_read(&setting->urcu_ref.refcount) == 0)
117 goto init_urcu_ref;
99054cee 118 else {
205f7ca7 119 urcu_ref_get(&setting->urcu_ref);
99054cee
PMF
120 goto end;
121 }
122 }
909bc43f 123 setting = zmalloc(sizeof(*setting));
99054cee
PMF
124 if (!setting) {
125 ret = -ENOMEM;
126 goto end;
127 }
0222e121 128 cds_list_add(&setting->list, &ltt_channels);
99054cee
PMF
129 strncpy(setting->name, name, PATH_MAX-1);
130 setting->index = free_index++;
205f7ca7
DG
131init_urcu_ref:
132 urcu_ref_init(&setting->urcu_ref);
99054cee 133end:
f7b16408 134 pthread_mutex_unlock(&ltt_channel_mutex);
99054cee
PMF
135 return ret;
136}
99054cee
PMF
137
138/**
139 * ltt_channels_unregister - Unregister a trace channel.
140 * @name: channel name
141 *
142 * Must be called with markers mutex held.
143 */
144int ltt_channels_unregister(const char *name)
145{
146 struct ltt_channel_setting *setting;
147 int ret = 0;
148
f7b16408 149 pthread_mutex_lock(&ltt_channel_mutex);
99054cee 150 setting = lookup_channel(name);
205f7ca7 151 if (!setting || uatomic_read(&setting->urcu_ref.refcount) == 0) {
99054cee
PMF
152 ret = -ENOENT;
153 goto end;
154 }
205f7ca7 155 urcu_ref_put(&setting->urcu_ref, release_channel_setting);
99054cee 156end:
f7b16408 157 pthread_mutex_unlock(&ltt_channel_mutex);
99054cee
PMF
158 return ret;
159}
99054cee
PMF
160
161/**
162 * ltt_channels_set_default - Set channel default behavior.
163 * @name: default channel name
164 * @subbuf_size: size of the subbuffers
165 * @subbuf_cnt: number of subbuffers
166 */
167int ltt_channels_set_default(const char *name,
168 unsigned int subbuf_size,
169 unsigned int subbuf_cnt)
170{
171 struct ltt_channel_setting *setting;
172 int ret = 0;
173
f7b16408 174 pthread_mutex_lock(&ltt_channel_mutex);
99054cee 175 setting = lookup_channel(name);
205f7ca7 176 if (!setting || uatomic_read(&setting->urcu_ref.refcount) == 0) {
99054cee
PMF
177 ret = -ENOENT;
178 goto end;
179 }
180 setting->subbuf_size = subbuf_size;
181 setting->subbuf_cnt = subbuf_cnt;
182end:
f7b16408 183 pthread_mutex_unlock(&ltt_channel_mutex);
99054cee
PMF
184 return ret;
185}
99054cee
PMF
186
187/**
188 * ltt_channels_get_name_from_index - get channel name from channel index
189 * @index: channel index
190 *
191 * Allows to lookup the channel name given its index. Done to keep the name
192 * information outside of each trace channel instance.
193 */
194const char *ltt_channels_get_name_from_index(unsigned int index)
195{
196 struct ltt_channel_setting *iter;
197
0222e121 198 cds_list_for_each_entry(iter, &ltt_channels, list)
205f7ca7 199 if (iter->index == index && uatomic_read(&iter->urcu_ref.refcount))
99054cee
PMF
200 return iter->name;
201 return NULL;
202}
99054cee
PMF
203
204static struct ltt_channel_setting *
205ltt_channels_get_setting_from_name(const char *name)
206{
207 struct ltt_channel_setting *iter;
208
0222e121 209 cds_list_for_each_entry(iter, &ltt_channels, list)
99054cee 210 if (!strcmp(iter->name, name)
205f7ca7 211 && uatomic_read(&iter->urcu_ref.refcount))
99054cee
PMF
212 return iter;
213 return NULL;
214}
215
216/**
217 * ltt_channels_get_index_from_name - get channel index from channel name
218 * @name: channel name
219 *
220 * Allows to lookup the channel index given its name. Done to keep the name
221 * information outside of each trace channel instance.
222 * Returns -1 if not found.
223 */
224int ltt_channels_get_index_from_name(const char *name)
225{
226 struct ltt_channel_setting *setting;
227
228 setting = ltt_channels_get_setting_from_name(name);
229 if (setting)
230 return setting->index;
231 else
232 return -1;
233}
99054cee
PMF
234
235/**
236 * ltt_channels_trace_alloc - Allocate channel structures for a trace
237 * @subbuf_size: subbuffer size. 0 uses default.
238 * @subbuf_cnt: number of subbuffers per per-cpu buffers. 0 uses default.
239 * @flags: Default channel flags
240 *
241 * Use the current channel list to allocate the channels for a trace.
242 * Called with trace lock held. Does not perform the trace buffer allocation,
243 * because we must let the user overwrite specific channel sizes.
244 */
b5b073e2 245struct ust_channel *ltt_channels_trace_alloc(unsigned int *nr_channels,
99054cee 246 int overwrite,
8649cd59 247 int request_collection,
99054cee
PMF
248 int active)
249{
b5b073e2 250 struct ust_channel *channel = NULL;
99054cee
PMF
251 struct ltt_channel_setting *iter;
252
f7b16408 253 pthread_mutex_lock(&ltt_channel_mutex);
5f54827b
PMF
254 if (!free_index) {
255 WARN("ltt_channels_trace_alloc: no free_index; are there any probes connected?");
99054cee 256 goto end;
5f54827b 257 }
205f7ca7
DG
258 if (!uatomic_read(&index_urcu_ref.refcount))
259 urcu_ref_init(&index_urcu_ref);
99054cee 260 else
205f7ca7 261 urcu_ref_get(&index_urcu_ref);
99054cee 262 *nr_channels = free_index;
909bc43f 263 channel = zmalloc(sizeof(struct ust_channel) * free_index);
5f54827b
PMF
264 if (!channel) {
265 WARN("ltt_channel_struct: channel null after alloc");
99054cee 266 goto end;
5f54827b 267 }
0222e121 268 cds_list_for_each_entry(iter, &ltt_channels, list) {
205f7ca7 269 if (!uatomic_read(&iter->urcu_ref.refcount))
99054cee
PMF
270 continue;
271 channel[iter->index].subbuf_size = iter->subbuf_size;
272 channel[iter->index].subbuf_cnt = iter->subbuf_cnt;
273 channel[iter->index].overwrite = overwrite;
8649cd59 274 channel[iter->index].request_collection = request_collection;
99054cee
PMF
275 channel[iter->index].active = active;
276 channel[iter->index].channel_name = iter->name;
277 }
278end:
f7b16408 279 pthread_mutex_unlock(&ltt_channel_mutex);
99054cee
PMF
280 return channel;
281}
99054cee
PMF
282
283/**
284 * ltt_channels_trace_free - Free one trace's channels
285 * @channels: channels to free
286 *
287 * Called with trace lock held. The actual channel buffers must be freed before
288 * this function is called.
289 */
b5b073e2 290void ltt_channels_trace_free(struct ust_channel *channels)
99054cee 291{
b521931e 292 lock_ust_marker();
f7b16408 293 pthread_mutex_lock(&ltt_channel_mutex);
909bc43f 294 free(channels);
205f7ca7 295 urcu_ref_put(&index_urcu_ref, release_trace_channel);
f7b16408 296 pthread_mutex_unlock(&ltt_channel_mutex);
b521931e 297 unlock_ust_marker();
99054cee 298}
99054cee
PMF
299
300/**
301 * _ltt_channels_get_event_id - get next event ID for a marker
302 * @channel: channel name
303 * @name: event name
304 *
305 * Returns a unique event ID (for this channel) or < 0 on error.
306 * Must be called with channels mutex held.
307 */
308int _ltt_channels_get_event_id(const char *channel, const char *name)
309{
310 struct ltt_channel_setting *setting;
311 int ret;
312
313 setting = ltt_channels_get_setting_from_name(channel);
314 if (!setting) {
315 ret = -ENOENT;
316 goto end;
317 }
318 if (strcmp(channel, "metadata") == 0) {
319 if (strcmp(name, "core_marker_id") == 0)
320 ret = 0;
321 else if (strcmp(name, "core_marker_format") == 0)
322 ret = 1;
9c67dc50
PMF
323 else if (strcmp(name, "testev") == 0)
324 ret = 2;
99054cee
PMF
325 else
326 ret = -ENOENT;
327 goto end;
328 }
329 if (setting->free_event_id == EVENTS_PER_CHANNEL - 1) {
330 ret = -ENOSPC;
331 goto end;
332 }
333 ret = setting->free_event_id++;
334end:
335 return ret;
336}
337
338/**
339 * ltt_channels_get_event_id - get next event ID for a marker
340 * @channel: channel name
341 * @name: event name
342 *
343 * Returns a unique event ID (for this channel) or < 0 on error.
344 */
345int ltt_channels_get_event_id(const char *channel, const char *name)
346{
347 int ret;
348
f7b16408 349 pthread_mutex_lock(&ltt_channel_mutex);
99054cee 350 ret = _ltt_channels_get_event_id(channel, name);
f7b16408 351 pthread_mutex_unlock(&ltt_channel_mutex);
99054cee
PMF
352 return ret;
353}
This page took 0.053049 seconds and 4 git commands to generate.