demo program: only depend on libdl
[lttng-ust.git] / liblttng-ust / ltt-probes.c
1 /*
2 * ltt-probes.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Holds LTTng probes registry.
7 *
8 * Dual LGPL v2.1/GPL v2 license.
9 */
10
11 #include <string.h>
12 #include <errno.h>
13 #include <urcu/list.h>
14 #include <lttng/ust-events.h>
15 #include <assert.h>
16
17 #include "ltt-tracer-core.h"
18
19 /*
20 * probe list is protected by ust_lock()/ust_unlock().
21 */
22 static CDS_LIST_HEAD(probe_list);
23
24 static
25 const struct lttng_event_desc *find_event(const char *name)
26 {
27 struct lttng_probe_desc *probe_desc;
28 int i;
29
30 cds_list_for_each_entry(probe_desc, &probe_list, head) {
31 for (i = 0; i < probe_desc->nr_events; i++) {
32 if (!strcmp(probe_desc->event_desc[i].name, name))
33 return &probe_desc->event_desc[i];
34 }
35 }
36 return NULL;
37 }
38
39 int ltt_probe_register(struct lttng_probe_desc *desc)
40 {
41 int ret = 0;
42 int i;
43
44 ust_lock();
45 /*
46 * TODO: This is O(N^2). Turn into a hash table when probe registration
47 * overhead becomes an issue.
48 */
49 for (i = 0; i < desc->nr_events; i++) {
50 if (find_event(desc->event_desc[i].name)) {
51 ret = -EEXIST;
52 goto end;
53 }
54 }
55 cds_list_add(&desc->head, &probe_list);
56
57 /*
58 * fix the events awaiting probe load.
59 */
60 for (i = 0; i < desc->nr_events; i++) {
61 ret = pending_probe_fix_events(&desc->event_desc[i]);
62 assert(!ret);
63 }
64 end:
65 ust_unlock();
66 return ret;
67 }
68
69 void ltt_probe_unregister(struct lttng_probe_desc *desc)
70 {
71 ust_lock();
72 cds_list_del(&desc->head);
73 ust_unlock();
74 }
75
76 /*
77 * called with UST lock held.
78 */
79 const struct lttng_event_desc *ltt_event_get(const char *name)
80 {
81 const struct lttng_event_desc *event;
82
83 event = find_event(name);
84 if (!event)
85 return NULL;
86 return event;
87 }
88
89 void ltt_event_put(const struct lttng_event_desc *event)
90 {
91 }
92
93 #if 0
94 static
95 void *tp_list_start(struct seq_file *m, loff_t *pos)
96 {
97 struct lttng_probe_desc *probe_desc;
98 int iter = 0, i;
99
100 pthread_mutex_lock(&probe_mutex);
101 cds_list_for_each_entry(probe_desc, &probe_list, head) {
102 for (i = 0; i < probe_desc->nr_events; i++) {
103 if (iter++ >= *pos)
104 return (void *) &probe_desc->event_desc[i];
105 }
106 }
107 /* End of list */
108 return NULL;
109 }
110
111 static
112 void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos)
113 {
114 struct lttng_probe_desc *probe_desc;
115 int iter = 0, i;
116
117 (*ppos)++;
118 cds_list_for_each_entry(probe_desc, &probe_list, head) {
119 for (i = 0; i < probe_desc->nr_events; i++) {
120 if (iter++ >= *ppos)
121 return (void *) &probe_desc->event_desc[i];
122 }
123 }
124 /* End of list */
125 return NULL;
126 }
127
128 static
129 void tp_list_stop(struct seq_file *m, void *p)
130 {
131 pthread_mutex_unlock(&probe_mutex);
132 }
133
134 static
135 int tp_list_show(struct seq_file *m, void *p)
136 {
137 const struct lttng_event_desc *probe_desc = p;
138
139 /*
140 * Don't export lttng internal events (metadata).
141 */
142 if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1))
143 return 0;
144 seq_printf(m, "event { name = %s; };\n",
145 probe_desc->name);
146 return 0;
147 }
148
149 static
150 const struct seq_operations lttng_tracepoint_list_seq_ops = {
151 .start = tp_list_start,
152 .next = tp_list_next,
153 .stop = tp_list_stop,
154 .show = tp_list_show,
155 };
156
157 static
158 int lttng_tracepoint_list_open(struct inode *inode, struct file *file)
159 {
160 return seq_open(file, &lttng_tracepoint_list_seq_ops);
161 }
162
163 const struct file_operations lttng_tracepoint_list_fops = {
164 .open = lttng_tracepoint_list_open,
165 .read = seq_read,
166 .llseek = seq_lseek,
167 .release = seq_release,
168 };
169 #endif //0
This page took 0.034606 seconds and 4 git commands to generate.