From: Michael Jeanson Date: Thu, 22 Apr 2021 18:07:20 +0000 (-0400) Subject: Move the clock plugin implementation to liblttng-ust-common X-Git-Tag: v2.13.0-rc1~10 X-Git-Url: http://git.lttng.org/?p=lttng-ust.git;a=commitdiff_plain;h=f41a6b5f307db311352f79d35f0656959db60891 Move the clock plugin implementation to liblttng-ust-common The clock plugin is used by both liblttng-ust and liblttng-ust-ctl, move it to liblttng-ust-common. Change-Id: Ie2fd6947b0531cb10f5de2f5aaf42a1701a44458 Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- diff --git a/src/common/clock.h b/src/common/clock.h index a0bf2499..e9407f26 100644 --- a/src/common/clock.h +++ b/src/common/clock.h @@ -7,9 +7,56 @@ #ifndef _UST_COMMON_CLOCK_H #define _UST_COMMON_CLOCK_H +#include +#include +#include +#include +#include + +#include +#include +#include + +struct lttng_ust_trace_clock { + uint64_t (*read64)(void); + uint64_t (*freq)(void); + int (*uuid)(char *uuid); + const char *(*name)(void); + const char *(*description)(void); +}; + /* - * Part of the private ABI between liblttng-ust and liblttng-ust-ctl. + * The trace clock is a public symbol of liblttng-ust-common accessed by other + * libraries through the trace_clock_read64 static inline function. It is + * initialised in the liblttng-ust-common constructor. */ -void lttng_ust_clock_init(void); +extern struct lttng_ust_trace_clock *lttng_ust_trace_clock; + +/* Use the kernel MONOTONIC clock. */ + +static __inline__ +uint64_t trace_clock_read64_monotonic(void) +{ + struct timespec ts; + + if (caa_unlikely(clock_gettime(CLOCK_MONOTONIC, &ts))) { + ts.tv_sec = 0; + ts.tv_nsec = 0; + } + return ((uint64_t) ts.tv_sec * 1000000000ULL) + ts.tv_nsec; +} + +static __inline__ +uint64_t trace_clock_read64(void) +{ + struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); + + if (caa_likely(!ltc)) { + return trace_clock_read64_monotonic(); + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + return ltc->read64(); + } +} #endif /* _UST_COMMON_CLOCK_H */ diff --git a/src/lib/lttng-ust-common/Makefile.am b/src/lib/lttng-ust-common/Makefile.am index 5d0b2242..334fc0d1 100644 --- a/src/lib/lttng-ust-common/Makefile.am +++ b/src/lib/lttng-ust-common/Makefile.am @@ -3,6 +3,8 @@ lib_LTLIBRARIES = liblttng-ust-common.la liblttng_ust_common_la_SOURCES = \ + clock.c \ + clock.h \ fd-tracker.c \ fd-tracker.h \ ust-common.c \ @@ -10,7 +12,8 @@ liblttng_ust_common_la_SOURCES = \ lttng-ust-urcu-pointer.c liblttng_ust_common_la_LIBADD = \ - $(top_builddir)/src/common/libcommon.la + $(top_builddir)/src/common/libcommon.la \ + $(DL_LIBS) liblttng_ust_common_la_LDFLAGS = -no-undefined -version-info $(LTTNG_UST_LIBRARY_VERSION) diff --git a/src/lib/lttng-ust-common/clock.c b/src/lib/lttng-ust-common/clock.c new file mode 100644 index 00000000..bf11f262 --- /dev/null +++ b/src/lib/lttng-ust-common/clock.c @@ -0,0 +1,224 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (C) 2014 Mathieu Desnoyers + */ + +#define _LGPL_SOURCE +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common/logging.h" +#include "common/getenv.h" + +#include "lib/lttng-ust-common/clock.h" + +struct lttng_ust_trace_clock *lttng_ust_trace_clock; + +static +struct lttng_ust_trace_clock user_tc; + +static +void *clock_handle; + +static +uint64_t trace_clock_freq_monotonic(void) +{ + return 1000000000ULL; +} + +static +int trace_clock_uuid_monotonic(char *uuid) +{ + int ret = 0; + size_t len; + FILE *fp; + + /* + * boot_id needs to be read once before being used concurrently + * to deal with a Linux kernel race. A fix is proposed for + * upstream, but the work-around is needed for older kernels. + */ + fp = fopen("/proc/sys/kernel/random/boot_id", "r"); + if (!fp) { + return -ENOENT; + } + len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp); + if (len < LTTNG_UST_UUID_STR_LEN - 1) { + ret = -EINVAL; + goto end; + } + uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0'; +end: + fclose(fp); + return ret; +} + +static +const char *trace_clock_name_monotonic(void) +{ + return "monotonic"; +} + +static +const char *trace_clock_description_monotonic(void) +{ + return "Monotonic Clock"; +} + +int lttng_ust_trace_clock_set_read64_cb(lttng_ust_clock_read64_function read64_cb) +{ + if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) + return -EBUSY; + user_tc.read64 = read64_cb; + return 0; +} + +int lttng_ust_trace_clock_get_read64_cb(lttng_ust_clock_read64_function *read64_cb) +{ + struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); + + if (caa_likely(!ltc)) { + *read64_cb = &trace_clock_read64_monotonic; + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + *read64_cb = ltc->read64; + } + return 0; +} + +int lttng_ust_trace_clock_set_freq_cb(lttng_ust_clock_freq_function freq_cb) +{ + if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) + return -EBUSY; + user_tc.freq = freq_cb; + return 0; +} + +int lttng_ust_trace_clock_get_freq_cb(lttng_ust_clock_freq_function *freq_cb) +{ + struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); + + if (caa_likely(!ltc)) { + *freq_cb = &trace_clock_freq_monotonic; + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + *freq_cb = ltc->freq; + } + return 0; +} + +int lttng_ust_trace_clock_set_uuid_cb(lttng_ust_clock_uuid_function uuid_cb) +{ + if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) + return -EBUSY; + user_tc.uuid = uuid_cb; + return 0; +} + +int lttng_ust_trace_clock_get_uuid_cb(lttng_ust_clock_uuid_function *uuid_cb) +{ + struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); + + if (caa_likely(!ltc)) { + *uuid_cb = &trace_clock_uuid_monotonic; + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + *uuid_cb = ltc->uuid; + } + return 0; +} + +int lttng_ust_trace_clock_set_name_cb(lttng_ust_clock_name_function name_cb) +{ + if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) + return -EBUSY; + user_tc.name = name_cb; + return 0; +} + +int lttng_ust_trace_clock_get_name_cb(lttng_ust_clock_name_function *name_cb) +{ + struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); + + if (caa_likely(!ltc)) { + *name_cb = &trace_clock_name_monotonic; + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + *name_cb = ltc->name; + } + return 0; +} + +int lttng_ust_trace_clock_set_description_cb(lttng_ust_clock_description_function description_cb) +{ + if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) + return -EBUSY; + user_tc.description = description_cb; + return 0; +} + +int lttng_ust_trace_clock_get_description_cb(lttng_ust_clock_description_function *description_cb) +{ + struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); + + if (caa_likely(!ltc)) { + *description_cb = &trace_clock_description_monotonic; + } else { + cmm_read_barrier_depends(); /* load ltc before content */ + *description_cb = ltc->description; + } + return 0; +} + +int lttng_ust_enable_trace_clock_override(void) +{ + if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) + return -EBUSY; + if (!user_tc.read64) + return -EINVAL; + if (!user_tc.freq) + return -EINVAL; + if (!user_tc.name) + return -EINVAL; + if (!user_tc.description) + return -EINVAL; + /* Use default uuid cb when NULL */ + cmm_smp_mb(); /* Store callbacks before trace clock */ + CMM_STORE_SHARED(lttng_ust_trace_clock, &user_tc); + return 0; +} + +void lttng_ust_clock_init(void) +{ + const char *libname; + void (*libinit)(void); + + if (clock_handle) + return; + libname = lttng_ust_getenv("LTTNG_UST_CLOCK_PLUGIN"); + if (!libname) + return; + clock_handle = dlopen(libname, RTLD_NOW); + if (!clock_handle) { + PERROR("Cannot load LTTng UST clock override library %s", + libname); + return; + } + dlerror(); + libinit = (void (*)(void)) dlsym(clock_handle, + "lttng_ust_clock_plugin_init"); + if (!libinit) { + PERROR("Cannot find LTTng UST clock override library %s initialization function lttng_ust_clock_plugin_init()", + libname); + return; + } + libinit(); +} diff --git a/src/lib/lttng-ust-common/clock.h b/src/lib/lttng-ust-common/clock.h new file mode 100644 index 00000000..5b1a1ab2 --- /dev/null +++ b/src/lib/lttng-ust-common/clock.h @@ -0,0 +1,16 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (C) 2010 Pierre-Marc Fournier + * Copyright (C) 2011 Mathieu Desnoyers + */ + +#ifndef _LTTNG_UST_COMMON_CLOCK_H +#define _LTTNG_UST_COMMON_CLOCK_H + +#include "common/clock.h" + +void lttng_ust_clock_init(void) + __attribute__((visibility("hidden"))); + +#endif /* _LTTNG_UST_COMMON_CLOCK_H */ diff --git a/src/lib/lttng-ust-common/ust-common.c b/src/lib/lttng-ust-common/ust-common.c index f444c97f..e6c81ba6 100644 --- a/src/lib/lttng-ust-common/ust-common.c +++ b/src/lib/lttng-ust-common/ust-common.c @@ -11,6 +11,7 @@ #include "common/getenv.h" #include "lib/lttng-ust-common/fd-tracker.h" +#include "lib/lttng-ust-common/clock.h" /* * The liblttng-ust-common constructor, initialize the internal shared state. @@ -24,6 +25,11 @@ void lttng_ust_common_ctor(void) * Initialize the shared state of the fd tracker. */ lttng_ust_fd_tracker_init(); + + /* + * Initialize the potential user-provided clock plugin. + */ + lttng_ust_clock_init(); } void lttng_ust_common_alloc_tls(void) diff --git a/src/lib/lttng-ust-ctl/ustctl.c b/src/lib/lttng-ust-ctl/ustctl.c index 429b693d..86e37f18 100644 --- a/src/lib/lttng-ust-ctl/ustctl.c +++ b/src/lib/lttng-ust-ctl/ustctl.c @@ -28,7 +28,6 @@ #include "common/events.h" #include "common/wait.h" #include "lib/lttng-ust/lttng-rb-clients.h" -#include "common/clock.h" #include "common/getenv.h" #include "lib/lttng-ust/lttng-tracer-core.h" #include "lib/lttng-ust/lttng-counter-client.h" @@ -2912,7 +2911,6 @@ void lttng_ust_ctl_ctor(void) */ lttng_ust_common_ctor(); - lttng_ust_clock_init(); lttng_ust_ring_buffer_clients_init(); lttng_ust_counter_clients_init(); lib_ringbuffer_signal_init(); diff --git a/src/lib/lttng-ust/Makefile.am b/src/lib/lttng-ust/Makefile.am index 73ceb438..752b5177 100644 --- a/src/lib/lttng-ust/Makefile.am +++ b/src/lib/lttng-ust/Makefile.am @@ -51,8 +51,6 @@ liblttng_ust_runtime_la_SOURCES = \ context-internal.h \ context-provider-internal.h \ events.h \ - clock.h \ - lttng-ust-uuid.h \ tracef.c \ lttng-ust-tracef-provider.h \ tracelog.c \ @@ -87,7 +85,6 @@ liblttng_ust_support_la_SOURCES = \ lttng-counter-client.h \ lttng-counter-client-percpu-32-modular.c \ lttng-counter-client-percpu-64-modular.c \ - lttng-clock.c \ getcpu.c getcpu.h liblttng_ust_la_SOURCES = diff --git a/src/lib/lttng-ust/clock.h b/src/lib/lttng-ust/clock.h deleted file mode 100644 index 22e82f4f..00000000 --- a/src/lib/lttng-ust/clock.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-only - * - * Copyright (C) 2010 Pierre-Marc Fournier - * Copyright (C) 2011 Mathieu Desnoyers - */ - -#ifndef _UST_CLOCK_H -#define _UST_CLOCK_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common/clock.h" -#include "lttng-ust-uuid.h" - -struct lttng_ust_trace_clock { - uint64_t (*read64)(void); - uint64_t (*freq)(void); - int (*uuid)(char *uuid); - const char *(*name)(void); - const char *(*description)(void); -}; - -extern struct lttng_ust_trace_clock *lttng_ust_trace_clock - __attribute__((visibility("hidden"))); - -/* Use the kernel MONOTONIC clock. */ - -static __inline__ -uint64_t trace_clock_read64_monotonic(void) -{ - struct timespec ts; - - if (caa_unlikely(clock_gettime(CLOCK_MONOTONIC, &ts))) { - ts.tv_sec = 0; - ts.tv_nsec = 0; - } - return ((uint64_t) ts.tv_sec * 1000000000ULL) + ts.tv_nsec; -} - -static __inline__ -uint64_t trace_clock_read64(void) -{ - struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); - - if (caa_likely(!ltc)) { - return trace_clock_read64_monotonic(); - } else { - cmm_read_barrier_depends(); /* load ltc before content */ - return ltc->read64(); - } -} - -#endif /* _UST_CLOCK_H */ diff --git a/src/lib/lttng-ust/lttng-clock.c b/src/lib/lttng-ust/lttng-clock.c deleted file mode 100644 index bc38850e..00000000 --- a/src/lib/lttng-ust/lttng-clock.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * SPDX-License-Identifier: LGPL-2.1-only - * - * Copyright (C) 2014 Mathieu Desnoyers - */ - -#define _LGPL_SOURCE -#include -#include -#include -#include - -#include -#include -#include - -#include "common/logging.h" - -#include "clock.h" -#include "common/getenv.h" - -struct lttng_ust_trace_clock *lttng_ust_trace_clock; - -static -struct lttng_ust_trace_clock user_tc; - -static -void *clock_handle; - -static -uint64_t trace_clock_freq_monotonic(void) -{ - return 1000000000ULL; -} - -static -int trace_clock_uuid_monotonic(char *uuid) -{ - int ret = 0; - size_t len; - FILE *fp; - - /* - * boot_id needs to be read once before being used concurrently - * to deal with a Linux kernel race. A fix is proposed for - * upstream, but the work-around is needed for older kernels. - */ - fp = fopen("/proc/sys/kernel/random/boot_id", "r"); - if (!fp) { - return -ENOENT; - } - len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp); - if (len < LTTNG_UST_UUID_STR_LEN - 1) { - ret = -EINVAL; - goto end; - } - uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0'; -end: - fclose(fp); - return ret; -} - -static -const char *trace_clock_name_monotonic(void) -{ - return "monotonic"; -} - -static -const char *trace_clock_description_monotonic(void) -{ - return "Monotonic Clock"; -} - -int lttng_ust_trace_clock_set_read64_cb(lttng_ust_clock_read64_function read64_cb) -{ - if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) - return -EBUSY; - user_tc.read64 = read64_cb; - return 0; -} - -int lttng_ust_trace_clock_get_read64_cb(lttng_ust_clock_read64_function *read64_cb) -{ - struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); - - if (caa_likely(!ltc)) { - *read64_cb = &trace_clock_read64_monotonic; - } else { - cmm_read_barrier_depends(); /* load ltc before content */ - *read64_cb = ltc->read64; - } - return 0; -} - -int lttng_ust_trace_clock_set_freq_cb(lttng_ust_clock_freq_function freq_cb) -{ - if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) - return -EBUSY; - user_tc.freq = freq_cb; - return 0; -} - -int lttng_ust_trace_clock_get_freq_cb(lttng_ust_clock_freq_function *freq_cb) -{ - struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); - - if (caa_likely(!ltc)) { - *freq_cb = &trace_clock_freq_monotonic; - } else { - cmm_read_barrier_depends(); /* load ltc before content */ - *freq_cb = ltc->freq; - } - return 0; -} - -int lttng_ust_trace_clock_set_uuid_cb(lttng_ust_clock_uuid_function uuid_cb) -{ - if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) - return -EBUSY; - user_tc.uuid = uuid_cb; - return 0; -} - -int lttng_ust_trace_clock_get_uuid_cb(lttng_ust_clock_uuid_function *uuid_cb) -{ - struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); - - if (caa_likely(!ltc)) { - *uuid_cb = &trace_clock_uuid_monotonic; - } else { - cmm_read_barrier_depends(); /* load ltc before content */ - *uuid_cb = ltc->uuid; - } - return 0; -} - -int lttng_ust_trace_clock_set_name_cb(lttng_ust_clock_name_function name_cb) -{ - if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) - return -EBUSY; - user_tc.name = name_cb; - return 0; -} - -int lttng_ust_trace_clock_get_name_cb(lttng_ust_clock_name_function *name_cb) -{ - struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); - - if (caa_likely(!ltc)) { - *name_cb = &trace_clock_name_monotonic; - } else { - cmm_read_barrier_depends(); /* load ltc before content */ - *name_cb = ltc->name; - } - return 0; -} - -int lttng_ust_trace_clock_set_description_cb(lttng_ust_clock_description_function description_cb) -{ - if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) - return -EBUSY; - user_tc.description = description_cb; - return 0; -} - -int lttng_ust_trace_clock_get_description_cb(lttng_ust_clock_description_function *description_cb) -{ - struct lttng_ust_trace_clock *ltc = CMM_LOAD_SHARED(lttng_ust_trace_clock); - - if (caa_likely(!ltc)) { - *description_cb = &trace_clock_description_monotonic; - } else { - cmm_read_barrier_depends(); /* load ltc before content */ - *description_cb = ltc->description; - } - return 0; -} - -int lttng_ust_enable_trace_clock_override(void) -{ - if (CMM_LOAD_SHARED(lttng_ust_trace_clock)) - return -EBUSY; - if (!user_tc.read64) - return -EINVAL; - if (!user_tc.freq) - return -EINVAL; - if (!user_tc.name) - return -EINVAL; - if (!user_tc.description) - return -EINVAL; - /* Use default uuid cb when NULL */ - cmm_smp_mb(); /* Store callbacks before trace clock */ - CMM_STORE_SHARED(lttng_ust_trace_clock, &user_tc); - return 0; -} - -void lttng_ust_clock_init(void) -{ - const char *libname; - void (*libinit)(void); - - if (clock_handle) - return; - libname = lttng_ust_getenv("LTTNG_UST_CLOCK_PLUGIN"); - if (!libname) - return; - clock_handle = dlopen(libname, RTLD_NOW); - if (!clock_handle) { - PERROR("Cannot load LTTng UST clock override library %s", - libname); - return; - } - dlerror(); - libinit = (void (*)(void)) dlsym(clock_handle, - "lttng_ust_clock_plugin_init"); - if (!libinit) { - PERROR("Cannot find LTTng UST clock override library %s initialization function lttng_ust_clock_plugin_init()", - libname); - return; - } - libinit(); -} diff --git a/src/lib/lttng-ust/lttng-events.c b/src/lib/lttng-ust/lttng-events.c index 4bacbb95..a8baff3a 100644 --- a/src/lib/lttng-ust/lttng-events.c +++ b/src/lib/lttng-ust/lttng-events.c @@ -39,7 +39,6 @@ #include "common/ust-fd.h" #include "common/dynamic-type.h" #include "common/ust-context-provider.h" -#include "lttng-ust-uuid.h" #include "common/tracepoint.h" #include "common/strutils.h" diff --git a/src/lib/lttng-ust/lttng-ring-buffer-client-template.h b/src/lib/lttng-ust/lttng-ring-buffer-client-template.h index 16c8895f..e4401c90 100644 --- a/src/lib/lttng-ust/lttng-ring-buffer-client-template.h +++ b/src/lib/lttng-ust/lttng-ring-buffer-client-template.h @@ -14,7 +14,7 @@ #include #include "common/bitfield.h" #include "common/align.h" -#include "clock.h" +#include "common/clock.h" #include "context-internal.h" #include "lttng-tracer.h" #include "common/ringbuffer/frontend_types.h" diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index 61f0b34a..db9fa8d9 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -50,7 +50,7 @@ #include "common/procname.h" #include "common/ringbuffer/rb-init.h" #include "lttng-ust-statedump.h" -#include "clock.h" +#include "common/clock.h" #include "lib/lttng-ust/getcpu.h" #include "common/getenv.h" #include "lib/lttng-ust/events.h" @@ -2118,7 +2118,6 @@ void lttng_ust_ctor(void) lttng_ust_common_ctor(); lttng_ust_tp_init(); - lttng_ust_clock_init(); lttng_ust_getcpu_plugin_init(); lttng_ust_statedump_init(); lttng_ust_ring_buffer_clients_init(); diff --git a/src/lib/lttng-ust/lttng-ust-uuid.h b/src/lib/lttng-ust/lttng-ust-uuid.h deleted file mode 100644 index b7d94e70..00000000 --- a/src/lib/lttng-ust/lttng-ust-uuid.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright (C) 2011 Mathieu Desnoyers - */ - -#ifndef _LTTNG_UST_UUID_H -#define _LTTNG_UST_UUID_H - -#include /* For LTTNG_UST_UUID_LEN */ -#include - -#endif /* _LTTNG_UST_UUID_H */