Fix: lttng-sessiond: cpu hotplug: send channel to consumer only once
[lttng-tools.git] / src / bin / lttng-sessiond / ust-clock.h
CommitLineData
d0b96690
DG
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
389fbf04 23#include <common/compat/time.h>
d0b96690
DG
24#include <sys/time.h>
25#include <stdint.h>
26#include <stddef.h>
27#include <stdio.h>
fc0bb9fa
MD
28#include <urcu/system.h>
29#include <urcu/arch.h>
30#include <lttng/ust-clock.h>
d0b96690
DG
31
32#include <common/compat/uuid.h>
33
34/* TRACE CLOCK */
35
fc0bb9fa
MD
36struct 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
44extern struct lttng_trace_clock *lttng_trace_clock;
45
46void lttng_ust_clock_init(void);
47
d0b96690
DG
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
55static __inline__
fc0bb9fa 56uint64_t trace_clock_read64_monotonic(void)
d0b96690
DG
57{
58 struct timespec ts;
59
389fbf04 60 if (lttng_clock_gettime(CLOCK_MONOTONIC, &ts)) {
1cf9656c
MD
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 }
d0b96690
DG
66 return ((uint64_t) ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
67}
68
69static __inline__
fc0bb9fa 70uint64_t trace_clock_freq_monotonic(void)
d0b96690
DG
71{
72 return 1000000000ULL;
73}
74
75static __inline__
fc0bb9fa 76int trace_clock_uuid_monotonic(char *uuid)
d0b96690
DG
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 }
fc0bb9fa
MD
91 len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp);
92 if (len < LTTNG_UST_UUID_STR_LEN - 1) {
d0b96690
DG
93 ret = -EINVAL;
94 goto end;
95 }
fc0bb9fa 96 uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0';
d0b96690
DG
97end:
98 fclose(fp);
99 return ret;
100}
101
fc0bb9fa
MD
102static __inline__
103const char *trace_clock_name_monotonic(void)
104{
105 return "monotonic";
106}
107
108static __inline__
109const char *trace_clock_description_monotonic(void)
110{
111 return "Monotonic Clock";
112}
113
114static __inline__
115uint64_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
127static __inline__
128uint64_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
140static __inline__
141int 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
154static __inline__
155const 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
167static __inline__
168const 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
d0b96690 180#endif /* _UST_CLOCK_H */
This page took 0.045092 seconds and 4 git commands to generate.