Commit | Line | Data |
---|---|---|
2b2d6ff7 | 1 | /* |
c0c0989a | 2 | * SPDX-License-Identifier: LGPL-2.1-only |
2b2d6ff7 | 3 | * |
c0c0989a | 4 | * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
2b2d6ff7 MD |
5 | */ |
6 | ||
f73bcf5e MJ |
7 | #ifndef _UST_COMMON_GETCPU_H |
8 | #define _UST_COMMON_GETCPU_H | |
c0c0989a | 9 | |
2b2d6ff7 | 10 | #include <urcu/compiler.h> |
5e1b7b8b MD |
11 | #include <urcu/system.h> |
12 | #include <urcu/arch.h> | |
13 | ||
247c2ecd MJ |
14 | #include <lttng/ust-getcpu.h> |
15 | ||
247c2ecd MJ |
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. | |
f73bcf5e MJ |
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. | |
247c2ecd | 24 | */ |
f73bcf5e | 25 | extern int (*lttng_ust_get_cpu_sym)(void); |
2b2d6ff7 | 26 | |
fdb4af10 | 27 | #ifdef LTTNG_UST_DEBUG_VALGRIND |
2b2d6ff7 MD |
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 | |
5e1b7b8b | 35 | int lttng_ust_get_cpu_internal(void) |
2b2d6ff7 MD |
36 | { |
37 | return 0; | |
38 | } | |
39 | ||
40 | #else | |
41 | ||
08bf1cc1 MD |
42 | /* |
43 | * sched_getcpu. | |
44 | */ | |
45 | #ifdef __linux__ | |
46 | ||
787364e8 | 47 | #if !HAVE_SCHED_GETCPU |
08bf1cc1 MD |
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 | |
5e1b7b8b | 54 | int lttng_ust_get_cpu_internal(void) |
08bf1cc1 MD |
55 | { |
56 | int cpu, ret; | |
57 | ||
58 | ret = __getcpu(&cpu, NULL, NULL); | |
59 | if (caa_unlikely(ret < 0)) | |
60 | return 0; | |
787364e8 | 61 | return cpu; |
08bf1cc1 | 62 | } |
787364e8 | 63 | #else /* HAVE_SCHED_GETCPU */ |
08bf1cc1 MD |
64 | #include <sched.h> |
65 | ||
2b2d6ff7 MD |
66 | /* |
67 | * If getcpu is not implemented in the kernel, use cpu 0 as fallback. | |
68 | */ | |
69 | static inline | |
5e1b7b8b | 70 | int lttng_ust_get_cpu_internal(void) |
2b2d6ff7 MD |
71 | { |
72 | int cpu; | |
73 | ||
74 | cpu = sched_getcpu(); | |
75 | if (caa_unlikely(cpu < 0)) | |
76 | return 0; | |
77 | return cpu; | |
78 | } | |
787364e8 | 79 | #endif /* HAVE_SCHED_GETCPU */ |
08bf1cc1 | 80 | |
4327cb7d | 81 | #elif (defined(__FreeBSD__) || defined(__CYGWIN__)) |
08bf1cc1 MD |
82 | |
83 | /* | |
4327cb7d MD |
84 | * FreeBSD and Cygwin do not allow query of CPU ID. Always use CPU |
85 | * number 0, with the assocated performance degradation on SMP. | |
08bf1cc1 MD |
86 | */ |
87 | static inline | |
5e1b7b8b | 88 | int lttng_ust_get_cpu_internal(void) |
08bf1cc1 MD |
89 | { |
90 | return 0; | |
91 | } | |
92 | ||
93 | #else | |
94 | #error "Please add support for your OS into liblttng-ust/compat.h." | |
95 | #endif | |
2b2d6ff7 MD |
96 | |
97 | #endif | |
98 | ||
5e1b7b8b MD |
99 | static inline |
100 | int lttng_ust_get_cpu(void) | |
101 | { | |
247c2ecd | 102 | int (*lttng_ust_get_cpu_current)(void) = CMM_LOAD_SHARED(lttng_ust_get_cpu_sym); |
5e1b7b8b | 103 | |
247c2ecd MJ |
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)) { | |
5e1b7b8b MD |
109 | return lttng_ust_get_cpu_internal(); |
110 | } else { | |
247c2ecd | 111 | return lttng_ust_get_cpu_current(); |
5e1b7b8b MD |
112 | } |
113 | } | |
114 | ||
2b2d6ff7 | 115 | #endif /* _LTTNG_GETCPU_H */ |