doc_examples_demodir = ${docdir}/examples/demo
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
if BUILD_JAVA_AGENT
doc_examples_java_juldir = ${docdir}/examples/java-jul
demo-tracef/demo-tracef.c \
demo-tracef/README
+dist_doc_examples_clock_override_DATA = clock-override/Makefile \
+ clock-override/lttng-ust-clock-override-example.c \
+ clock-override/run-clock-override \
+ clock-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
+SUBDIRS_PROXY = easy-ust demo hello-static-lib demo-tracef clock-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-clock-override-example.so
+
+lttng-ust-clock-override-example.o: lttng-ust-clock-override-example.c
+ $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(CFLAGS) $(AM_CPPFLAGS) \
+ $(AM_CFLAGS) -fpic -c -o $@ $<
+
+lttng-ust-clock-override-example.so: lttng-ust-clock-override-example.o
+ $(CC) -shared -Wl,--no-as-needed -o $@ $(LDFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(AM_CFLAGS) lttng-ust-clock-override-example.o
+
+.PHONY: clean
+clean:
+ rm -f *.o *.so
--- /dev/null
+This clock override example shows how to implement and load a clock
+override plugin for LTTng-UST. This can be useful in cases where direct
+hardware access is available for architecture-specific clocks, and where
+it should be used rather than the Linux kernel Monotonic clock.
--- /dev/null
+/*
+ * lttng-clock-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-clock.h>
+
+static
+uint64_t plugin_read64(void)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ /*
+ * This is a rather dumb example, but it illustrates the plugin
+ * mechanism: we take the monotonic clock, and transform it into
+ * a very coarse clock, which increment only at 1KHz frequency.
+ */
+ return ((uint64_t) ts.tv_sec * 1000ULL) + (ts.tv_nsec / 1000000ULL);
+}
+
+static
+uint64_t plugin_freq(void)
+{
+ return 1000; /* 1KHz clock (very coarse!) */
+}
+
+static
+int plugin_uuid(char *uuid)
+{
+ const char myuuid[] = "123456789012345678901234567890123456";
+
+ /*
+ * Should read some unique identifier for this clock shared
+ * across all components of the system using this clock for
+ * tracing.
+ */
+ memcpy(uuid, myuuid, LTTNG_UST_UUID_STR_LEN);
+ return 0;
+}
+
+static
+const char *plugin_name(void)
+{
+ return "my_example_clock";
+}
+
+static
+const char *plugin_description(void)
+{
+ return "Coarse monotonic clock at 1KHz";
+}
+
+void lttng_ust_clock_plugin_init(void)
+{
+ int ret;
+
+ ret = lttng_ust_trace_clock_set_read64_cb(plugin_read64);
+ if (ret) {
+ fprintf(stderr, "Error setting clock override read64 callback: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+ ret = lttng_ust_trace_clock_set_freq_cb(plugin_freq);
+ if (ret) {
+ fprintf(stderr, "Error setting clock override freq callback: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+ ret = lttng_ust_trace_clock_set_uuid_cb(plugin_uuid);
+ if (ret) {
+ fprintf(stderr, "Error setting clock override uuid callback: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+
+ ret = lttng_ust_trace_clock_set_name_cb(plugin_name);
+ if (ret) {
+ fprintf(stderr, "Error setting clock override name callback: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+
+ ret = lttng_ust_trace_clock_set_description_cb(plugin_description);
+ if (ret) {
+ fprintf(stderr, "Error setting clock override description callback: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+
+ ret = lttng_ust_enable_trace_clock_override();
+ if (ret) {
+ fprintf(stderr, "Error enabling clock override: %s\n",
+ strerror(-ret));
+ goto error;
+ }
+
+ return;
+
+error:
+ exit(EXIT_FAILURE);
+}
--- /dev/null
+#!/bin/sh
+
+# launch with: run-clock-override progname args
+
+DIR=$(dirname $0)
+DIR=$(readlink -f $DIR)
+
+LTTNG_UST_CLOCK_PLUGIN="$DIR/lttng-ust-clock-override-example.so" ${*}
lttng/bug.h \
lttng/ust-error.h \
lttng/tracef.h \
- lttng/lttng-ust-tracef.h
+ lttng/lttng-ust-tracef.h \
+ lttng/ust-clock.h
# note: usterr-signal-safe.h, core.h and share.h need namespace cleanup.
#include "../libringbuffer/frontend.h"
#include "../liblttng-ust/wait.h"
#include "../liblttng-ust/lttng-rb-clients.h"
+#include "../liblttng-ust/clock.h"
/*
* Number of milliseconds to retry before failing metadata writes on
void ustctl_init(void)
{
init_usterr();
+ lttng_ust_clock_init();
lttng_ring_buffer_metadata_client_init();
lttng_ring_buffer_client_overwrite_init();
lttng_ring_buffer_client_overwrite_rt_init();
lttng-ring-buffer-client-overwrite.c \
lttng-ring-buffer-client-overwrite-rt.c \
lttng-ring-buffer-metadata-client.h \
- lttng-ring-buffer-metadata-client.c
+ lttng-ring-buffer-metadata-client.c \
+ lttng-clock.c
liblttng_ust_la_SOURCES =
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
+#include <urcu/system.h>
+#include <urcu/arch.h>
+#include <lttng/ust-clock.h>
+
#include "lttng-ust-uuid.h"
-/* TRACE CLOCK */
+struct lttng_trace_clock {
+ uint64_t (*read64)(void);
+ uint64_t (*freq)(void);
+ int (*uuid)(char *uuid);
+ const char *(*name)(void);
+ const char *(*description)(void);
+};
-/*
- * Currently using the kernel MONOTONIC clock, waiting for kernel-side
- * LTTng to implement mmap'd trace clock.
- */
+extern struct lttng_trace_clock *lttng_trace_clock;
-/* Choosing correct trace clock */
+void lttng_ust_clock_init(void);
+
+/* Use the kernel MONOTONIC clock. */
static __inline__
-uint64_t trace_clock_read64(void)
+uint64_t trace_clock_read64_monotonic(void)
{
struct timespec ts;
}
static __inline__
-uint64_t trace_clock_freq(void)
+uint64_t trace_clock_freq_monotonic(void)
{
return 1000000000ULL;
}
static __inline__
-int trace_clock_uuid(char *uuid)
+int trace_clock_uuid_monotonic(char *uuid)
{
int ret = 0;
size_t len;
return ret;
}
+static __inline__
+const char *trace_clock_name_monotonic(void)
+{
+ return "monotonic";
+}
+
+static __inline__
+const char *trace_clock_description_monotonic(void)
+{
+ return "Monotonic Clock";
+}
+
+static __inline__
+uint64_t trace_clock_read64(void)
+{
+ struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
+
+ if (caa_likely(!ltc)) {
+ return trace_clock_read64_monotonic();
+ } else {
+ cmm_read_barrier_depends(); /* load ltc before content */
+ return ltc->read64();
+ }
+}
+
+static __inline__
+uint64_t trace_clock_freq(void)
+{
+ struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
+
+ if (!ltc) {
+ return trace_clock_freq_monotonic();
+ } else {
+ cmm_read_barrier_depends(); /* load ltc before content */
+ return ltc->freq();
+ }
+}
+
+static __inline__
+int trace_clock_uuid(char *uuid)
+{
+ struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
+
+ cmm_read_barrier_depends(); /* load ltc before content */
+ /* Use default UUID cb when NULL */
+ if (!ltc || !ltc->uuid) {
+ return trace_clock_uuid_monotonic(uuid);
+ } else {
+ return ltc->uuid(uuid);
+ }
+}
+
+static __inline__
+const char *trace_clock_name(void)
+{
+ struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
+
+ if (!ltc) {
+ return trace_clock_name_monotonic();
+ } else {
+ cmm_read_barrier_depends(); /* load ltc before content */
+ return ltc->name();
+ }
+}
+
+static __inline__
+const char *trace_clock_description(void)
+{
+ struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
+
+ if (!ltc) {
+ return trace_clock_description_monotonic();
+ } else {
+ cmm_read_barrier_depends(); /* load ltc before content */
+ return ltc->description();
+ }
+}
+
#endif /* _UST_CLOCK_H */
#include "compat.h"
#include "../libringbuffer/tlsfixup.h"
#include "lttng-ust-baddr.h"
+#include "clock.h"
/*
* Has lttng ust comm constructor been called ?
*/
init_usterr();
init_tracepoint();
+ lttng_ust_clock_init();
lttng_ust_baddr_statedump_init();
lttng_ring_buffer_metadata_client_init();
lttng_ring_buffer_client_overwrite_init();
*/
#include <lttng/ust-events.h> /* For LTTNG_UST_UUID_LEN */
-
-/*
- * Includes final \0.
- */
-#define LTTNG_UST_UUID_STR_LEN 37
+#include <lttng/ust-clock.h>
#endif /* _LTTNG_UST_UUID_H */