Commit | Line | Data |
---|---|---|
ce5aef0b MD |
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 | ||
8d8a24c8 MD |
11 | #include <string.h> |
12 | #include <errno.h> | |
13 | #include <urcu/list.h> | |
4318ae1b | 14 | #include <lttng/ust-events.h> |
a3bb4b27 | 15 | #include <assert.h> |
ce5aef0b | 16 | |
8165c8da MD |
17 | #include "ltt-tracer-core.h" |
18 | ||
19 | /* | |
17dfb34b | 20 | * probe list is protected by ust_lock()/ust_unlock(). |
8165c8da | 21 | */ |
8d8a24c8 | 22 | static CDS_LIST_HEAD(probe_list); |
ce5aef0b | 23 | |
df854e41 MD |
24 | static |
25 | const struct lttng_probe_desc *find_provider(const char *provider) | |
26 | { | |
27 | struct lttng_probe_desc *iter; | |
28 | ||
29 | cds_list_for_each_entry(iter, &probe_list, head) { | |
30 | if (!strcmp(iter->provider, provider)) | |
31 | return iter; | |
32 | } | |
33 | return NULL; | |
34 | } | |
35 | ||
ce5aef0b MD |
36 | static |
37 | const struct lttng_event_desc *find_event(const char *name) | |
38 | { | |
39 | struct lttng_probe_desc *probe_desc; | |
40 | int i; | |
41 | ||
8d8a24c8 | 42 | cds_list_for_each_entry(probe_desc, &probe_list, head) { |
ce5aef0b | 43 | for (i = 0; i < probe_desc->nr_events; i++) { |
df854e41 MD |
44 | if (!strcmp(probe_desc->event_desc[i]->name, name)) |
45 | return probe_desc->event_desc[i]; | |
ce5aef0b MD |
46 | } |
47 | } | |
48 | return NULL; | |
49 | } | |
50 | ||
51 | int ltt_probe_register(struct lttng_probe_desc *desc) | |
52 | { | |
df854e41 | 53 | struct lttng_probe_desc *iter; |
ce5aef0b MD |
54 | int ret = 0; |
55 | int i; | |
56 | ||
17dfb34b | 57 | ust_lock(); |
df854e41 MD |
58 | if (find_provider(desc->provider)) { |
59 | ret = -EEXIST; | |
60 | goto end; | |
61 | } | |
ce5aef0b MD |
62 | /* |
63 | * TODO: This is O(N^2). Turn into a hash table when probe registration | |
64 | * overhead becomes an issue. | |
65 | */ | |
66 | for (i = 0; i < desc->nr_events; i++) { | |
df854e41 | 67 | if (find_event(desc->event_desc[i]->name)) { |
ce5aef0b MD |
68 | ret = -EEXIST; |
69 | goto end; | |
70 | } | |
71 | } | |
df854e41 MD |
72 | |
73 | /* | |
74 | * We sort the providers by struct lttng_probe_desc pointer | |
75 | * address. | |
76 | */ | |
77 | cds_list_for_each_entry_reverse(iter, &probe_list, head) { | |
78 | BUG_ON(iter == desc); /* Should never be in the list twice */ | |
79 | if (iter < desc) { | |
80 | /* We belong to the location right after iter. */ | |
81 | cds_list_add(&desc->head, &iter->head); | |
82 | goto desc_added; | |
83 | } | |
84 | } | |
85 | /* We should be added at the head of the list */ | |
8d8a24c8 | 86 | cds_list_add(&desc->head, &probe_list); |
df854e41 | 87 | desc_added: |
8165c8da MD |
88 | |
89 | /* | |
90 | * fix the events awaiting probe load. | |
91 | */ | |
92 | for (i = 0; i < desc->nr_events; i++) { | |
df854e41 | 93 | ret = pending_probe_fix_events(desc->event_desc[i]); |
8165c8da MD |
94 | assert(!ret); |
95 | } | |
ce5aef0b | 96 | end: |
17dfb34b | 97 | ust_unlock(); |
ce5aef0b MD |
98 | return ret; |
99 | } | |
ce5aef0b MD |
100 | |
101 | void ltt_probe_unregister(struct lttng_probe_desc *desc) | |
102 | { | |
17dfb34b | 103 | ust_lock(); |
8d8a24c8 | 104 | cds_list_del(&desc->head); |
17dfb34b | 105 | ust_unlock(); |
ce5aef0b | 106 | } |
ce5aef0b | 107 | |
8165c8da MD |
108 | /* |
109 | * called with UST lock held. | |
110 | */ | |
ce5aef0b MD |
111 | const struct lttng_event_desc *ltt_event_get(const char *name) |
112 | { | |
113 | const struct lttng_event_desc *event; | |
ce5aef0b | 114 | |
ce5aef0b | 115 | event = find_event(name); |
ce5aef0b MD |
116 | if (!event) |
117 | return NULL; | |
ce5aef0b MD |
118 | return event; |
119 | } | |
ce5aef0b MD |
120 | |
121 | void ltt_event_put(const struct lttng_event_desc *event) | |
122 | { | |
ce5aef0b | 123 | } |