Copyright ownership transfer
[lttng-ust.git] / src / common / getcpu.h
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
4 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 */
6
7 #ifndef _UST_COMMON_GETCPU_H
8 #define _UST_COMMON_GETCPU_H
9
10 #include <urcu/compiler.h>
11 #include <urcu/system.h>
12 #include <urcu/arch.h>
13
14 #include <lttng/ust-getcpu.h>
15
16 /*
17 * Function pointer to the user provided getcpu callback, can be set at library
18 * initialization by a dlopened plugin or at runtime by a user by calling
19 * lttng_ust_getcpu_override() from the public API.
20 *
21 * This is an ABI symbol of liblttng-ust-common accessed by other libraries
22 * through the static inline function in this file. It is initialised in the
23 * liblttng-ust-common constructor.
24 */
25 extern int (*lttng_ust_get_cpu_sym)(void);
26
27 #ifdef LTTNG_UST_DEBUG_VALGRIND
28
29 /*
30 * Fallback on cpu 0 if liblttng-ust is build with Valgrind support.
31 * get_cpu() returns the current CPU number. It may change due to
32 * migration, so it is only statistically accurate.
33 */
34 static inline
35 int lttng_ust_get_cpu_internal(void)
36 {
37 return 0;
38 }
39
40 #else
41
42 /*
43 * sched_getcpu.
44 */
45 #ifdef __linux__
46
47 #if !HAVE_SCHED_GETCPU
48 #include <sys/syscall.h>
49 #define __getcpu(cpu, node, cache) syscall(__NR_getcpu, cpu, node, cache)
50 /*
51 * If getcpu is not implemented in the kernel, use cpu 0 as fallback.
52 */
53 static inline
54 int lttng_ust_get_cpu_internal(void)
55 {
56 int cpu, ret;
57
58 ret = __getcpu(&cpu, NULL, NULL);
59 if (caa_unlikely(ret < 0))
60 return 0;
61 return cpu;
62 }
63 #else /* HAVE_SCHED_GETCPU */
64 #include <sched.h>
65
66 /*
67 * If getcpu is not implemented in the kernel, use cpu 0 as fallback.
68 */
69 static inline
70 int lttng_ust_get_cpu_internal(void)
71 {
72 int cpu;
73
74 cpu = sched_getcpu();
75 if (caa_unlikely(cpu < 0))
76 return 0;
77 return cpu;
78 }
79 #endif /* HAVE_SCHED_GETCPU */
80
81 #elif (defined(__FreeBSD__) || defined(__CYGWIN__))
82
83 /*
84 * FreeBSD and Cygwin do not allow query of CPU ID. Always use CPU
85 * number 0, with the assocated performance degradation on SMP.
86 */
87 static inline
88 int lttng_ust_get_cpu_internal(void)
89 {
90 return 0;
91 }
92
93 #else
94 #error "Please add support for your OS into liblttng-ust/compat.h."
95 #endif
96
97 #endif
98
99 static inline
100 int lttng_ust_get_cpu(void)
101 {
102 int (*lttng_ust_get_cpu_current)(void) = CMM_LOAD_SHARED(lttng_ust_get_cpu_sym);
103
104 /*
105 * Fallback to the internal getcpu implementation if no override was
106 * provided the user.
107 */
108 if (caa_likely(!lttng_ust_get_cpu_current)) {
109 return lttng_ust_get_cpu_internal();
110 } else {
111 return lttng_ust_get_cpu_current();
112 }
113 }
114
115 #endif /* _LTTNG_GETCPU_H */
This page took 0.035231 seconds and 4 git commands to generate.