4 * Holds LTTng probes registry.
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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; only
11 * version 2.1 of the License.
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.
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
23 #include <linux/module.h>
24 #include <linux/list.h>
25 #include <linux/mutex.h>
26 #include <linux/seq_file.h>
28 #include "lttng-events.h"
30 static LIST_HEAD(probe_list);
31 static DEFINE_MUTEX(probe_mutex);
34 const struct lttng_event_desc *find_event(const char *name)
36 struct lttng_probe_desc *probe_desc;
39 list_for_each_entry(probe_desc, &probe_list, head) {
40 for (i = 0; i < probe_desc->nr_events; i++) {
41 if (!strcmp(probe_desc->event_desc[i]->name, name))
42 return probe_desc->event_desc[i];
48 int lttng_probe_register(struct lttng_probe_desc *desc)
53 mutex_lock(&probe_mutex);
55 * TODO: This is O(N^2). Turn into a hash table when probe registration
56 * overhead becomes an issue.
58 for (i = 0; i < desc->nr_events; i++) {
59 if (find_event(desc->event_desc[i]->name)) {
64 list_add(&desc->head, &probe_list);
66 mutex_unlock(&probe_mutex);
69 EXPORT_SYMBOL_GPL(lttng_probe_register);
71 void lttng_probe_unregister(struct lttng_probe_desc *desc)
73 mutex_lock(&probe_mutex);
74 list_del(&desc->head);
75 mutex_unlock(&probe_mutex);
77 EXPORT_SYMBOL_GPL(lttng_probe_unregister);
79 const struct lttng_event_desc *lttng_event_get(const char *name)
81 const struct lttng_event_desc *event;
84 mutex_lock(&probe_mutex);
85 event = find_event(name);
86 mutex_unlock(&probe_mutex);
89 ret = try_module_get(event->owner);
93 EXPORT_SYMBOL_GPL(lttng_event_get);
95 void lttng_event_put(const struct lttng_event_desc *event)
97 module_put(event->owner);
99 EXPORT_SYMBOL_GPL(lttng_event_put);
102 void *tp_list_start(struct seq_file *m, loff_t *pos)
104 struct lttng_probe_desc *probe_desc;
107 mutex_lock(&probe_mutex);
108 list_for_each_entry(probe_desc, &probe_list, head) {
109 for (i = 0; i < probe_desc->nr_events; i++) {
111 return (void *) probe_desc->event_desc[i];
119 void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos)
121 struct lttng_probe_desc *probe_desc;
125 list_for_each_entry(probe_desc, &probe_list, head) {
126 for (i = 0; i < probe_desc->nr_events; i++) {
128 return (void *) probe_desc->event_desc[i];
136 void tp_list_stop(struct seq_file *m, void *p)
138 mutex_unlock(&probe_mutex);
142 int tp_list_show(struct seq_file *m, void *p)
144 const struct lttng_event_desc *probe_desc = p;
146 seq_printf(m, "event { name = %s; };\n",
152 const struct seq_operations lttng_tracepoint_list_seq_ops = {
153 .start = tp_list_start,
154 .next = tp_list_next,
155 .stop = tp_list_stop,
156 .show = tp_list_show,
160 int lttng_tracepoint_list_open(struct inode *inode, struct file *file)
162 return seq_open(file, <tng_tracepoint_list_seq_ops);
165 const struct file_operations lttng_tracepoint_list_fops = {
166 .owner = THIS_MODULE,
167 .open = lttng_tracepoint_list_open,
170 .release = seq_release,