doc_examples_hello_static_libdir = ${docdir}/examples/hello-static-lib
doc_examples_demo_tracefdir = ${docdir}/examples/demo-tracef
doc_examples_clock_overridedir = ${docdir}/examples/clock-override
+doc_examples_getcpu_overridedir = ${docdir}/examples/getcpu-override
if BUILD_JAVA_AGENT
doc_examples_java_juldir = ${docdir}/examples/java-jul
clock-override/run-clock-override \
clock-override/README
+dist_doc_examples_getcpu_override_DATA = getcpu-override/Makefile \
+ getcpu-override/lttng-ust-getcpu-override-example.c \
+ getcpu-override/run-getcpu-override \
+ getcpu-override/README
+
if NO_SHARED
# Don't build examples if shared libraries support was explicitly
# disabled.
else
# Copies are for VPATH build support
-SUBDIRS_PROXY = easy-ust demo hello-static-lib demo-tracef clock-override
+SUBDIRS_PROXY = easy-ust demo hello-static-lib demo-tracef clock-override \
+ getcpu-override
if BUILD_GEN_TP_EXAMPLES
SUBDIRS_PROXY += gen-tp
--- /dev/null
+# Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+# Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+#
+# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+#
+# Permission is hereby granted to use or copy this program for any
+# purpose, provided the above notices are retained on all copies.
+# Permission to modify the code and to distribute modified code is
+# granted, provided the above notices are retained, and a notice that
+# the code was modified is included with the above copyright notice.
+#
+# This Makefile is not using automake so that users may see how to build
+# a program with tracepoint provider probes as stand-alone shared objects.
+#
+# This makefile is purposefully kept simple to support GNU and BSD make.
+
+ifdef AM_CC
+ CC = $(AM_CC)
+endif
+
+LIBS = -ldl # On Linux
+#LIBS = -lc # On BSD
+LOCAL_CPPFLAGS += -I.
+
+all: lttng-ust-getcpu-override-example.so
+
+lttng-ust-getcpu-override-example.o: lttng-ust-getcpu-override-example.c
+ $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(CFLAGS) $(AM_CPPFLAGS) \
+ $(AM_CFLAGS) -fpic -c -o $@ $<
+
+lttng-ust-getcpu-override-example.so: lttng-ust-getcpu-override-example.o
+ $(CC) -shared -Wl,--no-as-needed -o $@ $(LDFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(AM_CFLAGS) lttng-ust-getcpu-override-example.o
+
+.PHONY: clean
+clean:
+ rm -f *.o *.so
--- /dev/null
+This getcpu override example shows how to implement and load a getcpu
+override plugin for LTTng-UST. This can be useful in cases where direct
+hardware access is available for architecture-specific registers holding
+the CPU number, and where it should be used rather than the Linux kernel
+sched_getcpu() vDSO/syscall.
--- /dev/null
+/*
+ * lttng-getcpu-override-example.c
+ *
+ * Copyright (c) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+#include <lttng/ust-getcpu.h>
+
+static
+int plugin_getcpu(void)
+{
+ /* Dummy: always return CPU 0. */
+ return 0;
+}
+
+void lttng_ust_getcpu_plugin_init(void)
+{
+ int ret;
+
+ ret = lttng_ust_getcpu_override(plugin_getcpu);
+ if (ret) {
+ fprintf(stderr, "Error enabling getcpu override: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+ return;
+
+error:
+ exit(EXIT_FAILURE);
+}
--- /dev/null
+#!/bin/sh
+
+# launch with: run-getcpu-override progname args
+
+DIR=$(dirname $0)
+DIR=$(readlink -f $DIR)
+
+LTTNG_UST_GETCPU_PLUGIN="$DIR/lttng-ust-getcpu-override-example.so" ${*}
lttng/ust-error.h \
lttng/tracef.h \
lttng/lttng-ust-tracef.h \
- lttng/ust-clock.h
+ lttng/ust-clock.h \
+ lttng/ust-getcpu.h
# note: usterr-signal-safe.h, core.h and share.h need namespace cleanup.
--- /dev/null
+#ifndef LTTNG_UST_GETCPU_H
+#define LTTNG_UST_GETCPU_H
+
+/*
+ * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+/*
+ * Set getcpu override read callback. This callback should return the
+ * current CPU number.
+ */
+int lttng_ust_getcpu_override(int (*getcpu)(void));
+
+#endif /* LTTNG_UST_GETCPU_H */
lttng-ring-buffer-client-overwrite-rt.c \
lttng-ring-buffer-metadata-client.h \
lttng-ring-buffer-metadata-client.c \
- lttng-clock.c
+ lttng-clock.c lttng-getcpu.c
liblttng_ust_la_SOURCES =
--- /dev/null
+/*
+ * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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
+ */
+
+#define _GNU_SOURCE
+#include <error.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <usterr-signal-safe.h>
+#include <lttng/ust-getcpu.h>
+#include <urcu/system.h>
+#include <urcu/arch.h>
+
+#include "../libringbuffer/getcpu.h"
+
+int (*lttng_get_cpu)(void);
+
+int lttng_ust_getcpu_override(int (*getcpu)(void))
+{
+ CMM_STORE_SHARED(lttng_get_cpu, getcpu);
+ return 0;
+}
+
+void lttng_ust_getcpu_init(void)
+{
+ const char *libname;
+ void *handle;
+ void (*libinit)(void);
+
+ libname = secure_getenv("LTTNG_UST_GETCPU_PLUGIN");
+ if (!libname)
+ return;
+ handle = dlopen(libname, RTLD_NOW);
+ if (!handle) {
+ PERROR("Cannot load LTTng UST getcpu override library %s",
+ libname);
+ return;
+ }
+ dlerror();
+ libinit = (void (*)(void)) dlsym(handle,
+ "lttng_ust_getcpu_plugin_init");
+ if (!libinit) {
+ PERROR("Cannot find LTTng UST getcpu override library %s initialization function lttng_ust_getcpu_plugin_init()",
+ libname);
+ return;
+ }
+ libinit();
+}
*/
#define _LGPL_SOURCE
+#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include "../libringbuffer/tlsfixup.h"
#include "lttng-ust-baddr.h"
#include "clock.h"
+#include "../libringbuffer/getcpu.h"
/*
* Has lttng ust comm constructor been called ?
init_usterr();
init_tracepoint();
lttng_ust_clock_init();
+ lttng_ust_getcpu_init();
lttng_ust_baddr_statedump_init();
lttng_ring_buffer_metadata_client_init();
lttng_ring_buffer_client_overwrite_init();
*/
#include <urcu/compiler.h>
+#include <urcu/system.h>
+#include <urcu/arch.h>
+
+void lttng_ust_getcpu_init(void);
+
+extern int (*lttng_get_cpu)(void);
#ifdef LTTNG_UST_DEBUG_VALGRIND
* migration, so it is only statistically accurate.
*/
static inline
-int lttng_ust_get_cpu(void)
+int lttng_ust_get_cpu_internal(void)
{
return 0;
}
* If getcpu is not implemented in the kernel, use cpu 0 as fallback.
*/
static inline
-int lttng_ust_get_cpu(void)
+int lttng_ust_get_cpu_internal(void)
{
int cpu, ret;
* If getcpu is not implemented in the kernel, use cpu 0 as fallback.
*/
static inline
-int lttng_ust_get_cpu(void)
+int lttng_ust_get_cpu_internal(void)
{
int cpu;
* number 0, with the assocated performance degradation on SMP.
*/
static inline
-int lttng_ust_get_cpu(void)
+int lttng_ust_get_cpu_internal(void)
{
return 0;
}
#endif
+static inline
+int lttng_ust_get_cpu(void)
+{
+ int (*getcpu)(void) = CMM_LOAD_SHARED(lttng_get_cpu);
+
+ if (caa_likely(!getcpu)) {
+ return lttng_ust_get_cpu_internal();
+ } else {
+ return getcpu();
+ }
+}
+
#endif /* _LTTNG_GETCPU_H */