Fix: Integer overflowed argument
[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 <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 clock_gettime(CLOCK_MONOTONIC, &ts);
61 return ((uint64_t) ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
62 }
63
64 static __inline__
65 uint64_t trace_clock_freq_monotonic(void)
66 {
67 return 1000000000ULL;
68 }
69
70 static __inline__
71 int trace_clock_uuid_monotonic(char *uuid)
72 {
73 int ret = 0;
74 size_t len;
75 FILE *fp;
76
77 /*
78 * boot_id needs to be read once before being used concurrently
79 * to deal with a Linux kernel race. A fix is proposed for
80 * upstream, but the work-around is needed for older kernels.
81 */
82 fp = fopen("/proc/sys/kernel/random/boot_id", "r");
83 if (!fp) {
84 return -ENOENT;
85 }
86 len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp);
87 if (len < LTTNG_UST_UUID_STR_LEN - 1) {
88 ret = -EINVAL;
89 goto end;
90 }
91 uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0';
92 end:
93 fclose(fp);
94 return ret;
95 }
96
97 static __inline__
98 const char *trace_clock_name_monotonic(void)
99 {
100 return "monotonic";
101 }
102
103 static __inline__
104 const char *trace_clock_description_monotonic(void)
105 {
106 return "Monotonic Clock";
107 }
108
109 static __inline__
110 uint64_t trace_clock_read64(void)
111 {
112 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
113
114 if (caa_likely(!ltc)) {
115 return trace_clock_read64_monotonic();
116 } else {
117 cmm_read_barrier_depends(); /* load ltc before content */
118 return ltc->read64();
119 }
120 }
121
122 static __inline__
123 uint64_t trace_clock_freq(void)
124 {
125 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
126
127 if (!ltc) {
128 return trace_clock_freq_monotonic();
129 } else {
130 cmm_read_barrier_depends(); /* load ltc before content */
131 return ltc->freq();
132 }
133 }
134
135 static __inline__
136 int trace_clock_uuid(char *uuid)
137 {
138 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
139
140 cmm_read_barrier_depends(); /* load ltc before content */
141 /* Use default UUID cb when NULL */
142 if (!ltc || !ltc->uuid) {
143 return trace_clock_uuid_monotonic(uuid);
144 } else {
145 return ltc->uuid(uuid);
146 }
147 }
148
149 static __inline__
150 const char *trace_clock_name(void)
151 {
152 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
153
154 if (!ltc) {
155 return trace_clock_name_monotonic();
156 } else {
157 cmm_read_barrier_depends(); /* load ltc before content */
158 return ltc->name();
159 }
160 }
161
162 static __inline__
163 const char *trace_clock_description(void)
164 {
165 struct lttng_trace_clock *ltc = CMM_LOAD_SHARED(lttng_trace_clock);
166
167 if (!ltc) {
168 return trace_clock_description_monotonic();
169 } else {
170 cmm_read_barrier_depends(); /* load ltc before content */
171 return ltc->description();
172 }
173 }
174
175 #endif /* _UST_CLOCK_H */
This page took 0.032319 seconds and 4 git commands to generate.