ltt-events: initial addition
[lttng-modules.git] / ltt-events.c
1 /*
2 * ltt-events.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Holds LTTng per-session event registry.
7 */
8
9 #include <linux/module.h>
10 #include "ltt-events.h"
11
12 static LIST_HEAD(sessions);
13 static DEFINE_MUTEX(sessions_mutex);
14 static struct kmem_cache *event_cache;
15
16 struct ltt_session *ltt_session_create(char *name)
17 {
18 struct ltt_session *session;
19
20 mutex_lock(&sessions_mutex);
21 list_for_each_entry(session, &sessions, list)
22 if (!strcmp(session->name, name))
23 goto exist;
24 session = kmalloc(sizeof(struct ltt_session) + strlen(name) + 1);
25 if (!session)
26 return NULL;
27 strcpy(session->name, name);
28 INIT_LIST_HEAD(&session->chan);
29 list_add(&session->list, &sessions);
30 mutex_unlock(&sessions_mutex);
31 return session;
32
33 exist:
34 mutex_unlock(&sessions_mutex);
35 return NULL;
36 }
37
38 int ltt_session_destroy(struct ltt_session *session)
39 {
40 struct ltt_channel *chan, *tmpchan;
41 struct ltt_event *event, *tmpevent;
42
43 mutex_lock(&sessions_mutex);
44 list_for_each_entry_safe(event, tmpevent, &session->events, list)
45 _ltt_event_destroy(event);
46 list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
47 _ltt_channel_destroy(chan);
48 list_del(&session->list);
49 mutex_unlock(&sessions_mutex);
50 kfree(session);
51 }
52
53 struct ltt_channel *ltt_channel_create(struct ltt_session *session, char *name,
54 int overwrite, void *buf_addr,
55 size_t subbuf_size, size_t num_subbuf,
56 unsigned int switch_timer_interval,
57 unsigned int read_timer_interval)
58 {
59 struct ltt_channel *chan;
60
61 mutex_lock(&sessions_mutex);
62 list_for_each_entry(chan, &session->chan, list)
63 if (!strcmp(chan->name, name))
64 goto exist;
65 chan = kmalloc(sizeof(struct ltt_channel) + strlen(name) + 1, GFP_KERNEL);
66 if (!chan)
67 return NULL;
68 strcpy(chan->name, name);
69 chan->session = session;
70
71 /* TODO: create rb channel */
72 list_add(&chan->list, &session->chan);
73 mutex_unlock(&sessions_mutex);
74 return chan;
75
76 exist:
77 mutex_unlock(&sessions_mutex);
78 return NULL;
79 }
80
81 /*
82 * Only used internally at session destruction.
83 */
84 int _ltt_channel_destroy(struct ltt_channel *chan)
85 {
86 list_del(&chan->list);
87 kfree(chan);
88 }
89
90 struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
91 void *filter)
92 {
93 struct ltt_event *event;
94
95 mutex_lock(&sessions_mutex);
96 /*
97 * This is O(n^2) (for each event loop called at event creation).
98 * Might require a hash if we have lots of events.
99 */
100 list_for_each_entry(event, &chan->session->events, list)
101 if (!strcmp(event->name, name))
102 goto exist;
103 event = kmem_cache_zalloc(events_cache, GFP_KERNEL);
104 if (!event)
105 goto cache_error;
106 event->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
107 if (!event->name)
108 goto error;
109 strcpy(event->name, name);
110 event->chan = chan;
111 event->filter = filter;
112 event->id = atomic_inc_return(&chan->free_event_id) - 1;
113 /* TODO register to tracepoint */
114 mutex_unlock(&sessions_mutex);
115 return event;
116
117 error:
118 kmem_cache_free(event);
119 cache_error:
120 exist:
121 mutex_unlock(&sessions_mutex);
122 return NULL;
123 }
124
125 /*
126 * Only used internally at session destruction.
127 */
128 int _ltt_event_destroy(struct ltt_event *event)
129 {
130 /* TODO unregister from tracepoint */
131 kfree(event->name);
132 kmem_cache_free(event);
133 }
134
135 static int __init ltt_events_init(void)
136 {
137 int ret;
138
139 events_cache = KMEM_CACHE(ltt_event, 0);
140 if (!events_cache)
141 return -ENOMEM;
142 return 0;
143 }
144
145 static void __exit ltt_events_exit(void)
146 {
147 kmem_cache_destroy(events_cache);
148 }
This page took 0.032176 seconds and 5 git commands to generate.