ltt-events: initial addition
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 23 Nov 2010 22:25:15 +0000 (17:25 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 23 Nov 2010 22:25:15 +0000 (17:25 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
ltt-events.c [new file with mode: 0644]
ltt-events.h [new file with mode: 0644]

diff --git a/ltt-events.c b/ltt-events.c
new file mode 100644 (file)
index 0000000..a85b793
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * ltt-events.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Holds LTTng per-session event registry.
+ */
+
+#include <linux/module.h>
+#include "ltt-events.h"
+
+static LIST_HEAD(sessions);
+static DEFINE_MUTEX(sessions_mutex);
+static struct kmem_cache *event_cache;
+
+struct ltt_session *ltt_session_create(char *name)
+{
+       struct ltt_session *session;
+
+       mutex_lock(&sessions_mutex);
+       list_for_each_entry(session, &sessions, list)
+               if (!strcmp(session->name, name))
+                       goto exist;
+       session = kmalloc(sizeof(struct ltt_session) + strlen(name) + 1);
+       if (!session)
+               return NULL;
+       strcpy(session->name, name);
+       INIT_LIST_HEAD(&session->chan);
+       list_add(&session->list, &sessions);
+       mutex_unlock(&sessions_mutex);
+       return session;
+
+exist:
+       mutex_unlock(&sessions_mutex);
+       return NULL;
+}
+
+int ltt_session_destroy(struct ltt_session *session)
+{
+       struct ltt_channel *chan, *tmpchan;
+       struct ltt_event *event, *tmpevent;
+
+       mutex_lock(&sessions_mutex);
+       list_for_each_entry_safe(event, tmpevent, &session->events, list)
+               _ltt_event_destroy(event);
+       list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
+               _ltt_channel_destroy(chan);
+       list_del(&session->list);
+       mutex_unlock(&sessions_mutex);
+       kfree(session);
+}
+
+struct ltt_channel *ltt_channel_create(struct ltt_session *session, char *name,
+                                      int overwrite, void *buf_addr,
+                                      size_t subbuf_size, size_t num_subbuf,
+                                      unsigned int switch_timer_interval,
+                                      unsigned int read_timer_interval)
+{
+       struct ltt_channel *chan;
+
+       mutex_lock(&sessions_mutex);
+       list_for_each_entry(chan, &session->chan, list)
+               if (!strcmp(chan->name, name))
+                       goto exist;
+       chan = kmalloc(sizeof(struct ltt_channel) + strlen(name) + 1, GFP_KERNEL);
+       if (!chan)
+               return NULL;
+       strcpy(chan->name, name);
+       chan->session = session;
+
+       /* TODO: create rb channel */
+       list_add(&chan->list, &session->chan);
+       mutex_unlock(&sessions_mutex);
+       return chan;
+
+exist:
+       mutex_unlock(&sessions_mutex);
+       return NULL;
+}
+
+/*
+ * Only used internally at session destruction.
+ */
+int _ltt_channel_destroy(struct ltt_channel *chan)
+{
+       list_del(&chan->list);
+       kfree(chan);
+}
+
+struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
+                                  void *filter)
+{
+       struct ltt_event *event;
+
+       mutex_lock(&sessions_mutex);
+       /*
+        * This is O(n^2) (for each event loop called at event creation).
+        * Might require a hash if we have lots of events.
+        */
+       list_for_each_entry(event, &chan->session->events, list)
+               if (!strcmp(event->name, name))
+                       goto exist;
+       event = kmem_cache_zalloc(events_cache, GFP_KERNEL);
+       if (!event)
+               goto cache_error;
+       event->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+       if (!event->name)
+               goto error;
+       strcpy(event->name, name);
+       event->chan = chan;
+       event->filter = filter;
+       event->id = atomic_inc_return(&chan->free_event_id) - 1;
+       /* TODO register to tracepoint */
+       mutex_unlock(&sessions_mutex);
+       return event;
+
+error:
+       kmem_cache_free(event);
+cache_error:
+exist:
+       mutex_unlock(&sessions_mutex);
+       return NULL;
+}
+
+/*
+ * Only used internally at session destruction.
+ */
+int _ltt_event_destroy(struct ltt_event *event)
+{
+       /* TODO unregister from tracepoint */
+       kfree(event->name);
+       kmem_cache_free(event);
+}
+
+static int __init ltt_events_init(void)
+{
+       int ret;
+
+       events_cache = KMEM_CACHE(ltt_event, 0);
+       if (!events_cache)
+               return -ENOMEM;
+       return 0;
+}
+
+static void __exit ltt_events_exit(void)
+{
+       kmem_cache_destroy(events_cache);
+}
diff --git a/ltt-events.h b/ltt-events.h
new file mode 100644 (file)
index 0000000..d205cdb
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * ltt-events.h
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Holds LTTng per-session event registry.
+ */
+
+#include <linux/list.h>
+
+struct ltt_channel;
+struct ltt_session;
+
+/*
+ * ltt_event structure is referred to by the tracing fast path. It must be
+ * kept small.
+ */
+struct ltt_event {
+       unsigned int id;
+       struct ltt_channel *chan;
+       void *filter;
+       char *name;
+       struct list_head list;          /* Event list */
+};
+
+struct ltt_channel {
+       struct channel *chan;           /* Channel buffers */
+       /* Event ID management */
+       struct ltt_session *session;
+       atomic_t free_event_id;         /* Next event ID to allocate */
+       struct list_head list;          /* Channel list */
+       char name[PATH_MAX];
+};
+
+struct ltt_session {
+       struct list_head chan;          /* Channel list head */
+       struct list_head events;        /* Event list head */
+       struct list_head list;          /* Session list */
+       char name[PATH_MAX];
+};
+
+struct ltt_session *ltt_session_create(char *name);
+int ltt_session_destroy(struct ltt_session *session);
+
+struct ltt_channel *ltt_channel_create(struct ltt_session *session, char *name,
+                                      int overwrite, void *buf_addr,
+                                      size_t subbuf_size, size_t num_subbuf,
+                                      unsigned int switch_timer_interval,
+                                      unsigned int read_timer_interval);
+int _ltt_channel_destroy(struct ltt_channel *chan);
+
+struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
+                                  void *filter);
+int _ltt_event_destroy(struct ltt_event *event);
This page took 0.028325 seconds and 4 git commands to generate.