From 51489cadd9c38c10261bdbab9b5e72803c95a732 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 9 Nov 2011 09:55:49 -0500 Subject: [PATCH] Implement LTTNG_UST_TRACEPOINT_LIST Signed-off-by: Mathieu Desnoyers --- include/Makefile.am | 1 + include/lttng/tracepoint-internal.h | 10 +-- include/lttng/tracepoint-types.h | 45 +++++++++++ include/lttng/tracepoint.h | 20 +---- include/lttng/ust-abi.h | 3 + include/lttng/ust-comm.h | 1 + include/lttng/ust-events.h | 14 +++- liblttng-ust/lttng-ust-abi.c | 116 ++++++++++++++++++++++------ 8 files changed, 162 insertions(+), 48 deletions(-) create mode 100644 include/lttng/tracepoint-types.h diff --git a/include/Makefile.am b/include/Makefile.am index a843ea6b..3a667956 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,7 @@ nobase_include_HEADERS = \ lttng/marker.h \ lttng/tracepoint.h \ + lttng/tracepoint-types.h \ lttng/tracepoint-event.h \ lttng/ust-tracepoint-event.h \ lttng/ust-tracepoint-event-reset.h \ diff --git a/include/lttng/tracepoint-internal.h b/include/lttng/tracepoint-internal.h index 928eb4f3..54278c8f 100644 --- a/include/lttng/tracepoint-internal.h +++ b/include/lttng/tracepoint-internal.h @@ -1,5 +1,5 @@ -#ifndef _UST_TRACEPOINT_INTERNAL_H -#define _UST_TRACEPOINT_INTERNAL_H +#ifndef _LTTNG_TRACEPOINT_INTERNAL_H +#define _LTTNG_TRACEPOINT_INTERNAL_H /* * tracepoint-internal.h @@ -25,14 +25,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Heavily inspired from the Linux Kernel Markers. - * - * Ported to userspace by Pierre-Marc Fournier. */ #include #include #include -#include +#include struct tracepoint_lib { struct tracepoint * const *tracepoints_start; @@ -84,4 +82,4 @@ extern int is_trace_event_enabled(const char *channel, const char *name); extern void init_tracepoint(void); extern void exit_tracepoint(void); -#endif /* _UST_TRACEPOINT_INTERNAL_H */ +#endif /* _LTTNG_TRACEPOINT_INTERNAL_H */ diff --git a/include/lttng/tracepoint-types.h b/include/lttng/tracepoint-types.h new file mode 100644 index 00000000..5f387086 --- /dev/null +++ b/include/lttng/tracepoint-types.h @@ -0,0 +1,45 @@ +#ifndef _LTTNG_TRACEPOINT_TYPES_H +#define _LTTNG_TRACEPOINT_TYPES_H + +/* + * Copyright (C) 2008-2011 Mathieu Desnoyers + * Copyright (C) 2009 Pierre-Marc Fournier + * Copyright (C) 2009 Steven Rostedt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Heavily inspired from the Linux Kernel Markers. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct tracepoint_probe { + void *func; + void *data; +}; + +struct tracepoint { + const char *name; /* Tracepoint name */ + char state; /* State. */ + struct tracepoint_probe *probes; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _LTTNG_TRACEPOINT_TYPES_H */ diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index 6e1026dc..6023ba5e 100644 --- a/include/lttng/tracepoint.h +++ b/include/lttng/tracepoint.h @@ -1,5 +1,5 @@ -#ifndef _UST_TRACEPOINT_H -#define _UST_TRACEPOINT_H +#ifndef _LTTNG_TRACEPOINT_H +#define _LTTNG_TRACEPOINT_H /* * Copyright (C) 2008-2011 Mathieu Desnoyers @@ -21,28 +21,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Heavily inspired from the Linux Kernel Markers. - * - * Ported to userspace by Pierre-Marc Fournier. */ #include #include +#include #ifdef __cplusplus extern "C" { #endif -struct tracepoint_probe { - void *func; - void *data; -}; - -struct tracepoint { - const char *name; /* Tracepoint name */ - char state; /* State. */ - struct tracepoint_probe *probes; -}; - /* * Tracepoints should be added to the instrumented code using the * "tracepoint()" macro. @@ -423,4 +411,4 @@ static void __attribute__((destructor)) __tracepoints__destroy(void) } #endif -#endif /* _UST_TRACEPOINT_H */ +#endif /* _LTTNG_TRACEPOINT_H */ diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h index ced2929a..90a0822f 100644 --- a/include/lttng/ust-abi.h +++ b/include/lttng/ust-abi.h @@ -137,6 +137,9 @@ struct lttng_ust_object_data { #define LTTNG_UST_ENABLE _UST_CMD(0x80) #define LTTNG_UST_DISABLE _UST_CMD(0x81) +/* Tracepoint list commands */ +#define LTTNG_UST_TRACEPOINT_LIST_GET _UST_CMD(0x90) + #define LTTNG_UST_ROOT_HANDLE 0 struct lttng_ust_obj; diff --git a/include/lttng/ust-comm.h b/include/lttng/ust-comm.h index 4367cf7d..556da21e 100644 --- a/include/lttng/ust-comm.h +++ b/include/lttng/ust-comm.h @@ -129,6 +129,7 @@ struct ustcomm_ust_msg { struct lttng_ust_event event; struct lttng_ust_context context; struct lttng_ust_tracer_version version; + char tracepoint_list_entry[LTTNG_UST_SYM_NAME_LEN]; } u; }; diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h index 9ce39701..5c649e73 100644 --- a/include/lttng/ust-events.h +++ b/include/lttng/ust-events.h @@ -1,8 +1,8 @@ -#ifndef _UST_LTTNG_EVENTS_H -#define _UST_LTTNG_EVENTS_H +#ifndef _LTTNG_UST_EVENTS_H +#define _LTTNG_UST_EVENTS_H /* - * ust/lttng-events.h + * lttng/ust-events.h * * Copyright 2010 (c) - Mathieu Desnoyers * @@ -18,6 +18,7 @@ #include #include #include +#include struct ltt_channel; struct ltt_session; @@ -295,6 +296,11 @@ struct ltt_transport { struct ltt_channel_ops ops; }; +struct ltt_tracepoint_list { + struct tracepoint_iter iter; + int got_first; +}; + struct ltt_session *ltt_session_create(void); int ltt_session_enable(struct ltt_session *session); int ltt_session_disable(struct ltt_session *session); @@ -357,4 +363,4 @@ const struct lttng_ust_lib_ring_buffer_client_cb *lttng_client_callbacks_overwri struct cds_list_head ltt_transport_list; struct ltt_transport *ltt_transport_find(const char *name); -#endif /* _UST_LTTNG_EVENTS_H */ +#endif /* _LTTNG_UST_EVENTS_H */ diff --git a/liblttng-ust/lttng-ust-abi.c b/liblttng-ust/lttng-ust-abi.c index e7ef1579..4b8a8e71 100644 --- a/liblttng-ust/lttng-ust-abi.c +++ b/liblttng-ust/lttng-ust-abi.c @@ -32,6 +32,9 @@ #include "lttng/core.h" #include "ltt-tracer.h" +static +int lttng_abi_tracepoint_list(void); + /* * Object descriptor table. Should be protected from concurrent access * by the caller. @@ -197,6 +200,7 @@ static const struct lttng_ust_objd_ops lttng_channel_ops; static const struct lttng_ust_objd_ops lttng_metadata_ops; static const struct lttng_ust_objd_ops lttng_event_ops; static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops; +static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops; enum channel_type { PER_CPU_CHANNEL, @@ -233,26 +237,6 @@ objd_error: return ret; } -#if 0 -static -int lttng_abi_tracepoint_list(void) -{ - int list_objd, ret; - - /* TODO: Create list private data */ - list_objd = objd_alloc(NULL, <tng_tracepoint_list_ops); - if (list_objd < 0) { - ret = list_objd; - goto objd_error; - } - - return list_objd; - -objd_error: - return ret; -} -#endif //0 - static long lttng_abi_tracer_version(int objd, struct lttng_ust_tracer_version *v) @@ -314,8 +298,7 @@ long lttng_cmd(int objd, unsigned int cmd, unsigned long arg) return lttng_abi_tracer_version(objd, (struct lttng_ust_tracer_version *) arg); case LTTNG_UST_TRACEPOINT_LIST: - return -ENOSYS; //TODO - //return lttng_abi_tracepoint_list(); + return lttng_abi_tracepoint_list(); case LTTNG_UST_WAIT_QUIESCENT: synchronize_trace(); return 0; @@ -511,6 +494,95 @@ static const struct lttng_ust_objd_ops lttng_session_ops = { .cmd = lttng_session_cmd, }; +/* + * beware: we don't keep the mutex over the send, but we must walk the + * whole list each time we are called again. So sending one tracepoint + * at a time means this is O(n^2). TODO: do as in the kernel and send + * multiple tracepoints for each call to amortize this cost. + */ +static +void ltt_tracepoint_list_get(struct ltt_tracepoint_list *list, + char *tp_list_entry) +{ + if (!list->got_first) { + tracepoint_iter_start(&list->iter); + list->got_first = 1; + goto copy; + } + tracepoint_iter_next(&list->iter); +copy: + if (!list->iter.tracepoint) { + tp_list_entry[0] = '\0'; /* end of list */ + } else { + memcpy(tp_list_entry, (*list->iter.tracepoint)->name, + LTTNG_UST_SYM_NAME_LEN); + } +} + +static +long lttng_tracepoint_list_cmd(int objd, unsigned int cmd, unsigned long arg) +{ + struct ltt_tracepoint_list *list = objd_private(objd); + + switch (cmd) { + case LTTNG_UST_TRACEPOINT_LIST_GET: + ltt_tracepoint_list_get(list, (char *) arg); + return 0; + default: + return -EINVAL; + } +} + +static +int lttng_abi_tracepoint_list(void) +{ + int list_objd, ret; + struct ltt_tracepoint_list *list; + + list_objd = objd_alloc(NULL, <tng_tracepoint_list_ops); + if (list_objd < 0) { + ret = list_objd; + goto objd_error; + } + list = zmalloc(sizeof(*list)); + if (!list) { + ret = -ENOMEM; + goto alloc_error; + } + objd_set_private(list_objd, list); + + return list_objd; + +alloc_error: + { + int err; + + err = lttng_ust_objd_unref(list_objd); + assert(!err); + } +objd_error: + return ret; +} + +static +int lttng_release_tracepoint_list(int objd) +{ + struct ltt_tracepoint_list *list = objd_private(objd); + + if (list) { + tracepoint_iter_stop(&list->iter); + free(list); + return 0; + } else { + return -EINVAL; + } +} + +static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops = { + .release = lttng_release_tracepoint_list, + .cmd = lttng_tracepoint_list_cmd, +}; + struct stream_priv_data { struct lttng_ust_lib_ring_buffer *buf; struct ltt_channel *ltt_chan; -- 2.34.1