Fix: keep ust/kernel session items around for destroy notifier
[lttng-tools.git] / src / bin / lttng-sessiond / ust-clock.h
1 /*
2 * Copyright (C) 2010 Pierre-Marc Fournier
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; version 2.1 of
8 * the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef _UST_CLOCK_H
21 #define _UST_CLOCK_H
22
23 #include <common/compat/time.h>
24 #include <sys/time.h>
25 #include <stdint.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <urcu/system.h>
29 #include <urcu/arch.h>
30 #include <lttng/ust-clock.h>
31
32 #include <common/compat/uuid.h>
33
34 /* TRACE CLOCK */
35
36 struct lttng_trace_clock {
37 uint64_t (*read64)(void);
38 uint64_t (*freq)(void);
39 int (*uuid)(char *uuid);
40 const char *(*name)(void);
41 const char *(*description)(void);
42 };
43
44 extern struct lttng_trace_clock *lttng_trace_clock;
45
46 void lttng_ust_clock_init(void);
47
48 /*
49 * Currently using the kernel MONOTONIC clock, waiting for kernel-side
50 * LTTng to implement mmap'd trace clock.
51 */
52
53 /* Choosing correct trace clock */
54
55 static __inline__
56 uint64_t trace_clock_read64_monotonic(void)
57 {
58 struct timespec ts;
59
60 if (lttng_clock_gettime(CLOCK_MONOTONIC, &ts)) {
61 /* TODO Report error cleanly up the chain. */
62 PERROR("clock_gettime CLOCK_MONOTONIC");
63 ts.tv_sec = 0;
64 ts.tv_nsec = 0;
65 }
66 return ((uint64_t) ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
67 }
68
69 static __inline__
70 uint64_t trace_clock_freq_monotonic(void)
71 {
72 return 1000000000ULL;
73 }
74
75 static __inline__
76 int trace_clock_uuid_monotonic(char *uuid)
77 {
78 int ret = 0;
79 size_t len;
80 FILE *fp;
81
82 /*
83 * boot_id needs to be read once before being used concurrently
84 * to deal with a Linux kernel race. A fix is proposed for
85 * upstream, but the work-around is needed for older kernels.
86 */
87 fp = fopen("/proc/sys/kernel/random/boot_id", "r");
88 if (!fp) {
89 return -ENOENT;
90 }
91 len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp);
92 if (len < LTTNG_UST_UUID_STR_LEN - 1) {
93 ret = -EINVAL;
94 goto end;
95 }
96 uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0';
97 end:
98 fclose(fp);
99 return ret;
100 }
101
102 static __inline__
103 const char *trace_clock_name_monotonic(void)
104 {
105 return "monotonic";
106 }
107
108 static __inline__
109 const char *trace_clock_description_monotonic(void)
110 {
111 return "Monotonic Clock";
112 }
113
114 static __inline__
115 uint64_t trace_clock_read64(void)
116 {
117 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
118
119 if (caa_likely(!ltc)) {
120 return trace_clock_read64_monotonic();
121 } else {
122 cmm_read_barrier_depends(); /* load ltc before content */
123 return ltc->read64();
124 }
125 }
126
127 static __inline__
128 uint64_t trace_clock_freq(void)
129 {
130 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
131
132 if (!ltc) {
133 return trace_clock_freq_monotonic();
134 } else {
135 cmm_read_barrier_depends(); /* load ltc before content */
136 return ltc->freq();
137 }
138 }
139
140 static __inline__
141 int trace_clock_uuid(char *uuid)
142 {
143 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
144
145 cmm_read_barrier_depends(); /* load ltc before content */
146 /* Use default UUID cb when NULL */
147 if (!ltc || !ltc->uuid) {
148 return trace_clock_uuid_monotonic(uuid);
149 } else {
150 return ltc->uuid(uuid);
151 }
152 }
153
154 static __inline__
155 const char *trace_clock_name(void)
156 {
157 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
158
159 if (!ltc) {
160 return trace_clock_name_monotonic();
161 } else {
162 cmm_read_barrier_depends(); /* load ltc before content */
163 return ltc->name();
164 }
165 }
166
167 static __inline__
168 const char *trace_clock_description(void)
169 {
170 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
171
172 if (!ltc) {
173 return trace_clock_description_monotonic();
174 } else {
175 cmm_read_barrier_depends(); /* load ltc before content */
176 return ltc->description();
177 }
178 }
179
180 #endif /* _UST_CLOCK_H */
This page took 0.03281 seconds and 4 git commands to generate.