Commit | Line | Data |
---|---|---|
e11fcffc | 1 | /* |
c0c0989a | 2 | * SPDX-License-Identifier: LGPL-2.1-only |
e11fcffc | 3 | * |
c0c0989a | 4 | * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
e11fcffc MD |
5 | */ |
6 | ||
3fbec7dc | 7 | #define _LGPL_SOURCE |
e11fcffc MD |
8 | #include <error.h> |
9 | #include <dlfcn.h> | |
10 | #include <stdlib.h> | |
fb31eb73 | 11 | #include <stdint.h> |
e11fcffc MD |
12 | #include <usterr-signal-safe.h> |
13 | #include <lttng/ust-clock.h> | |
14 | #include <urcu/system.h> | |
15 | #include <urcu/arch.h> | |
16 | ||
17 | #include "clock.h" | |
730bf2af | 18 | #include "getenv.h" |
e11fcffc MD |
19 | |
20 | struct lttng_trace_clock *lttng_trace_clock; | |
21 | ||
22 | static | |
23 | struct lttng_trace_clock user_tc; | |
24 | ||
4bc1ccd7 MD |
25 | static |
26 | void *clock_handle; | |
27 | ||
e11fcffc MD |
28 | int lttng_ust_trace_clock_set_read64_cb(uint64_t (*read64)(void)) |
29 | { | |
30 | if (CMM_LOAD_SHARED(lttng_trace_clock)) | |
31 | return -EBUSY; | |
32 | user_tc.read64 = read64; | |
33 | return 0; | |
34 | } | |
35 | ||
36 | int lttng_ust_trace_clock_set_freq_cb(uint64_t (*freq)(void)) | |
37 | { | |
38 | if (CMM_LOAD_SHARED(lttng_trace_clock)) | |
39 | return -EBUSY; | |
40 | user_tc.freq = freq; | |
41 | return 0; | |
42 | } | |
43 | ||
44 | int lttng_ust_trace_clock_set_uuid_cb(int (*uuid)(char *uuid)) | |
45 | { | |
46 | if (CMM_LOAD_SHARED(lttng_trace_clock)) | |
47 | return -EBUSY; | |
48 | user_tc.uuid = uuid; | |
49 | return 0; | |
50 | } | |
51 | ||
52 | int lttng_ust_trace_clock_set_name_cb(const char *(*name)(void)) | |
53 | { | |
54 | if (CMM_LOAD_SHARED(lttng_trace_clock)) | |
55 | return -EBUSY; | |
56 | user_tc.name = name; | |
57 | return 0; | |
58 | } | |
59 | ||
60 | int lttng_ust_trace_clock_set_description_cb(const char *(*description)(void)) | |
61 | { | |
62 | if (CMM_LOAD_SHARED(lttng_trace_clock)) | |
63 | return -EBUSY; | |
64 | user_tc.description = description; | |
65 | return 0; | |
66 | } | |
67 | ||
68 | int lttng_ust_enable_trace_clock_override(void) | |
69 | { | |
70 | if (CMM_LOAD_SHARED(lttng_trace_clock)) | |
71 | return -EBUSY; | |
72 | if (!user_tc.read64) | |
73 | return -EINVAL; | |
74 | if (!user_tc.freq) | |
75 | return -EINVAL; | |
76 | if (!user_tc.name) | |
77 | return -EINVAL; | |
78 | if (!user_tc.description) | |
79 | return -EINVAL; | |
80 | /* Use default uuid cb when NULL */ | |
81 | cmm_smp_mb(); /* Store callbacks before trace clock */ | |
82 | CMM_STORE_SHARED(lttng_trace_clock, &user_tc); | |
83 | return 0; | |
84 | } | |
85 | ||
86 | void lttng_ust_clock_init(void) | |
87 | { | |
88 | const char *libname; | |
e11fcffc MD |
89 | void (*libinit)(void); |
90 | ||
4bc1ccd7 MD |
91 | if (clock_handle) |
92 | return; | |
4c41b460 | 93 | libname = lttng_ust_getenv("LTTNG_UST_CLOCK_PLUGIN"); |
e11fcffc MD |
94 | if (!libname) |
95 | return; | |
4bc1ccd7 MD |
96 | clock_handle = dlopen(libname, RTLD_NOW); |
97 | if (!clock_handle) { | |
e11fcffc MD |
98 | PERROR("Cannot load LTTng UST clock override library %s", |
99 | libname); | |
100 | return; | |
101 | } | |
102 | dlerror(); | |
4bc1ccd7 | 103 | libinit = (void (*)(void)) dlsym(clock_handle, |
e11fcffc MD |
104 | "lttng_ust_clock_plugin_init"); |
105 | if (!libinit) { | |
106 | PERROR("Cannot find LTTng UST clock override library %s initialization function lttng_ust_clock_plugin_init()", | |
107 | libname); | |
108 | return; | |
109 | } | |
110 | libinit(); | |
111 | } |