ltt-events: initial addition
[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);
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
76exist:
77 mutex_unlock(&sessions_mutex);
78 return NULL;
79}
80
81/*
82 * Only used internally at session destruction.
83 */
84int _ltt_channel_destroy(struct ltt_channel *chan)
85{
86 list_del(&chan->list);
87 kfree(chan);
88}
89
90struct 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
117error:
118 kmem_cache_free(event);
119cache_error:
120exist:
121 mutex_unlock(&sessions_mutex);
122 return NULL;
123}
124
125/*
126 * Only used internally at session destruction.
127 */
128int _ltt_event_destroy(struct ltt_event *event)
129{
130 /* TODO unregister from tracepoint */
131 kfree(event->name);
132 kmem_cache_free(event);
133}
134
135static 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
145static void __exit ltt_events_exit(void)
146{
147 kmem_cache_destroy(events_cache);
148}
This page took 0.027778 seconds and 4 git commands to generate.