update ltt-events
[lttng-modules.git] / ltt-events.c
CommitLineData
4e3c1b9b
MD
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
12static LIST_HEAD(sessions);
13static DEFINE_MUTEX(sessions_mutex);
14static struct kmem_cache *event_cache;
15
16struct 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
33exist:
34 mutex_unlock(&sessions_mutex);
35 return NULL;
36}
37
38int 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
53struct 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);
e5382b6d
MD
62 if (session->active)
63 goto active; /* Refuse to add channel to active session */
4e3c1b9b
MD
64 list_for_each_entry(chan, &session->chan, list)
65 if (!strcmp(chan->name, name))
66 goto exist;
67 chan = kmalloc(sizeof(struct ltt_channel) + strlen(name) + 1, GFP_KERNEL);
68 if (!chan)
69 return NULL;
70 strcpy(chan->name, name);
71 chan->session = session;
72
73 /* TODO: create rb channel */
74 list_add(&chan->list, &session->chan);
75 mutex_unlock(&sessions_mutex);
76 return chan;
77
78exist:
e5382b6d 79active:
4e3c1b9b
MD
80 mutex_unlock(&sessions_mutex);
81 return NULL;
82}
83
84/*
85 * Only used internally at session destruction.
86 */
87int _ltt_channel_destroy(struct ltt_channel *chan)
88{
89 list_del(&chan->list);
90 kfree(chan);
91}
92
e5382b6d
MD
93/*
94 * Supports event creation while tracing session is active.
95 */
4e3c1b9b
MD
96struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
97 void *filter)
98{
99 struct ltt_event *event;
100
101 mutex_lock(&sessions_mutex);
e5382b6d
MD
102 if (chan->free_event_id == -1UL)
103 goto full;
4e3c1b9b
MD
104 /*
105 * This is O(n^2) (for each event loop called at event creation).
106 * Might require a hash if we have lots of events.
107 */
108 list_for_each_entry(event, &chan->session->events, list)
109 if (!strcmp(event->name, name))
110 goto exist;
111 event = kmem_cache_zalloc(events_cache, GFP_KERNEL);
112 if (!event)
113 goto cache_error;
114 event->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
115 if (!event->name)
116 goto error;
117 strcpy(event->name, name);
118 event->chan = chan;
119 event->filter = filter;
e5382b6d 120 event->id = chan->free_event_id++;
4e3c1b9b 121 mutex_unlock(&sessions_mutex);
e5382b6d
MD
122 /* Populate ltt_event structure before tracepoint registration. */
123 smp_wmb();
124 /* TODO register to tracepoint */
4e3c1b9b
MD
125 return event;
126
127error:
128 kmem_cache_free(event);
129cache_error:
130exist:
e5382b6d 131full:
4e3c1b9b
MD
132 mutex_unlock(&sessions_mutex);
133 return NULL;
134}
135
136/*
137 * Only used internally at session destruction.
138 */
139int _ltt_event_destroy(struct ltt_event *event)
140{
141 /* TODO unregister from tracepoint */
142 kfree(event->name);
143 kmem_cache_free(event);
144}
145
146static int __init ltt_events_init(void)
147{
148 int ret;
149
150 events_cache = KMEM_CACHE(ltt_event, 0);
151 if (!events_cache)
152 return -ENOMEM;
92e94819
MD
153
154 /* TODO: show ABI to userspace */
155
4e3c1b9b
MD
156 return 0;
157}
158
159static void __exit ltt_events_exit(void)
160{
92e94819
MD
161 struct ltt_session *session, *tmpsession;
162
163 /* TODO: hide ABI from userspace, wait for callers to release refs. */
164
165 list_for_each_entry_safe(session, tmpsession, &sessions, list)
166 ltt_session_destroy(session);
4e3c1b9b
MD
167 kmem_cache_destroy(events_cache);
168}
92e94819
MD
169
170MODULE_LICENSE("GPL and additional rights");
171MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
172MODULE_DESCRIPTION("LTTng Events");
This page took 0.028769 seconds and 4 git commands to generate.