From: Mathieu Desnoyers Date: Wed, 1 Oct 2014 21:59:01 +0000 (-0400) Subject: Implement clock override plugin support X-Git-Tag: v2.7.0-rc1~49 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=f9364363c8982127d66c2a29cb1fa21760bd00e5;p=lttng-ust.git Implement clock override plugin support Signed-off-by: Mathieu Desnoyers --- diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index 6f0a31aa..328c6b0f 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -4,6 +4,7 @@ doc_examples_gen_tpdir = ${docdir}/examples/gen-tp 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 @@ -43,12 +44,17 @@ dist_doc_examples_demo_tracef_DATA = demo-tracef/Makefile \ 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 diff --git a/doc/examples/clock-override/Makefile b/doc/examples/clock-override/Makefile new file mode 100644 index 00000000..8f38c4fc --- /dev/null +++ b/doc/examples/clock-override/Makefile @@ -0,0 +1,38 @@ +# Copyright (C) 2013 Jérémie Galarneau +# Copyright (C) 2014 Mathieu Desnoyers +# +# 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 diff --git a/doc/examples/clock-override/README b/doc/examples/clock-override/README new file mode 100644 index 00000000..e3ddf22a --- /dev/null +++ b/doc/examples/clock-override/README @@ -0,0 +1,4 @@ +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. diff --git a/doc/examples/clock-override/lttng-ust-clock-override-example.c b/doc/examples/clock-override/lttng-ust-clock-override-example.c new file mode 100644 index 00000000..766e66c9 --- /dev/null +++ b/doc/examples/clock-override/lttng-ust-clock-override-example.c @@ -0,0 +1,125 @@ +/* + * lttng-clock-override-example.c + * + * Copyright (c) 2014 Mathieu Desnoyers + * + * 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 +#include +#include +#include +#include + +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); +} diff --git a/doc/examples/clock-override/run-clock-override b/doc/examples/clock-override/run-clock-override new file mode 100755 index 00000000..295b4839 --- /dev/null +++ b/doc/examples/clock-override/run-clock-override @@ -0,0 +1,8 @@ +#!/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" ${*} diff --git a/include/Makefile.am b/include/Makefile.am index 836cc9f3..b3598ffc 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -20,7 +20,8 @@ nobase_include_HEADERS = \ 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. diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index ca17255d..5801bc6b 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -32,6 +32,7 @@ #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 @@ -2003,6 +2004,7 @@ static __attribute__((constructor)) 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(); diff --git a/liblttng-ust/Makefile.am b/liblttng-ust/Makefile.am index e2e1baaa..796ce5b3 100644 --- a/liblttng-ust/Makefile.am +++ b/liblttng-ust/Makefile.am @@ -64,7 +64,8 @@ liblttng_ust_support_la_SOURCES = \ 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 = diff --git a/liblttng-ust/clock.h b/liblttng-ust/clock.h index 88eca432..388ed658 100644 --- a/liblttng-ust/clock.h +++ b/liblttng-ust/clock.h @@ -25,19 +25,28 @@ #include #include #include +#include +#include +#include + #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; @@ -46,13 +55,13 @@ uint64_t trace_clock_read64(void) } 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; @@ -78,4 +87,82 @@ end: 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 */ diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 378ca21c..97ecdf1e 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -52,6 +52,7 @@ #include "compat.h" #include "../libringbuffer/tlsfixup.h" #include "lttng-ust-baddr.h" +#include "clock.h" /* * Has lttng ust comm constructor been called ? @@ -1444,6 +1445,7 @@ void __attribute__((constructor)) lttng_ust_init(void) */ 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(); diff --git a/liblttng-ust/lttng-ust-uuid.h b/liblttng-ust/lttng-ust-uuid.h index add11e1f..3b05d178 100644 --- a/liblttng-ust/lttng-ust-uuid.h +++ b/liblttng-ust/lttng-ust-uuid.h @@ -24,10 +24,6 @@ */ #include /* For LTTNG_UST_UUID_LEN */ - -/* - * Includes final \0. - */ -#define LTTNG_UST_UUID_STR_LEN 37 +#include #endif /* _LTTNG_UST_UUID_H */