Timed wait operations for spin-only Baton
[folly.git] / folly / Portability.h
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <cstddef>
20
21 #include <folly/portability/Config.h>
22
23 #include <folly/CPortability.h>
24
25 // Unaligned loads and stores
26 namespace folly {
27 #if FOLLY_HAVE_UNALIGNED_ACCESS
28 constexpr bool kHasUnalignedAccess = true;
29 #else
30 constexpr bool kHasUnalignedAccess = false;
31 #endif
32 } // namespace folly
33
34 // compiler specific attribute translation
35 // msvc should come first, so if clang is in msvc mode it gets the right defines
36
37 // NOTE: this will only do checking in msvc with versions that support /analyze
38 #if _MSC_VER
39 # ifdef _USE_ATTRIBUTES_FOR_SAL
40 #    undef _USE_ATTRIBUTES_FOR_SAL
41 # endif
42 /* nolint */
43 # define _USE_ATTRIBUTES_FOR_SAL 1
44 # include <sal.h> // @manual
45 # define FOLLY_PRINTF_FORMAT _Printf_format_string_
46 # define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/
47 #else
48 # define FOLLY_PRINTF_FORMAT /**/
49 # define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) \
50   __attribute__((__format__(__printf__, format_param, dots_param)))
51 #endif
52
53 // deprecated
54 #if defined(__clang__) || defined(__GNUC__)
55 # define FOLLY_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
56 #elif defined(_MSC_VER)
57 # define FOLLY_DEPRECATED(msg) __declspec(deprecated(msg))
58 #else
59 # define FOLLY_DEPRECATED(msg)
60 #endif
61
62 // warn unused result
63 #if defined(__has_cpp_attribute)
64 #if __has_cpp_attribute(nodiscard)
65 #define FOLLY_NODISCARD [[nodiscard]]
66 #endif
67 #endif
68 #if !defined FOLLY_NODISCARD
69 #if defined(_MSC_VER) && (_MSC_VER >= 1700)
70 #define FOLLY_NODISCARD _Check_return_
71 #elif defined(__clang__) || defined(__GNUC__)
72 #define FOLLY_NODISCARD __attribute__((__warn_unused_result__))
73 #else
74 #define FOLLY_NODISCARD
75 #endif
76 #endif
77
78 // target
79 #ifdef _MSC_VER
80 # define FOLLY_TARGET_ATTRIBUTE(target)
81 #else
82 # define FOLLY_TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
83 #endif
84
85 // detection for 64 bit
86 #if defined(__x86_64__) || defined(_M_X64)
87 # define FOLLY_X64 1
88 #else
89 # define FOLLY_X64 0
90 #endif
91
92 #if defined(__arm__)
93 #define FOLLY_ARM 1
94 #else
95 #define FOLLY_ARM 0
96 #endif
97
98 #if defined(__aarch64__)
99 # define FOLLY_AARCH64 1
100 #else
101 # define FOLLY_AARCH64 0
102 #endif
103
104 #if defined (__powerpc64__)
105 # define FOLLY_PPC64 1
106 #else
107 # define FOLLY_PPC64 0
108 #endif
109
110 namespace folly {
111 constexpr bool kIsArchArm = FOLLY_ARM == 1;
112 constexpr bool kIsArchAmd64 = FOLLY_X64 == 1;
113 constexpr bool kIsArchAArch64 = FOLLY_AARCH64 == 1;
114 constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1;
115 } // namespace folly
116
117 namespace folly {
118
119 #if FOLLY_SANITIZE_ADDRESS
120 constexpr bool kIsSanitizeAddress = true;
121 #else
122 constexpr bool kIsSanitizeAddress = false;
123 #endif
124
125 #if FOLLY_SANITIZE_THREAD
126 constexpr bool kIsSanitizeThread = true;
127 #else
128 constexpr bool kIsSanitizeThread = false;
129 #endif
130
131 #if FOLLY_SANITIZE
132 constexpr bool kIsSanitize = true;
133 #else
134 constexpr bool kIsSanitize = false;
135 #endif
136 } // namespace folly
137
138 // packing is very ugly in msvc
139 #ifdef _MSC_VER
140 # define FOLLY_PACK_ATTR /**/
141 # define FOLLY_PACK_PUSH __pragma(pack(push, 1))
142 # define FOLLY_PACK_POP __pragma(pack(pop))
143 #elif defined(__clang__) || defined(__GNUC__)
144 # define FOLLY_PACK_ATTR __attribute__((__packed__))
145 # define FOLLY_PACK_PUSH /**/
146 # define FOLLY_PACK_POP /**/
147 #else
148 # define FOLLY_PACK_ATTR /**/
149 # define FOLLY_PACK_PUSH /**/
150 # define FOLLY_PACK_POP /**/
151 #endif
152
153 // Generalize warning push/pop.
154 #if defined(_MSC_VER)
155 # define FOLLY_PUSH_WARNING __pragma(warning(push))
156 # define FOLLY_POP_WARNING __pragma(warning(pop))
157 // Disable the GCC warnings.
158 # define FOLLY_GCC_DISABLE_WARNING(warningName)
159 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) __pragma(warning(disable: warningNumber))
160 #elif defined(__clang__) || defined(__GNUC__)
161 # define FOLLY_PUSH_WARNING _Pragma("GCC diagnostic push")
162 # define FOLLY_POP_WARNING _Pragma("GCC diagnostic pop")
163 # define FOLLY_GCC_DISABLE_WARNING_INTERNAL2(warningName) #warningName
164 # define FOLLY_GCC_DISABLE_WARNING(warningName) \
165   _Pragma(                                      \
166   FOLLY_GCC_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName))
167 // Disable the MSVC warnings.
168 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
169 #else
170 # define FOLLY_PUSH_WARNING
171 # define FOLLY_POP_WARNING
172 # define FOLLY_GCC_DISABLE_WARNING(warningName)
173 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
174 #endif
175
176 #ifdef FOLLY_HAVE_SHADOW_LOCAL_WARNINGS
177 #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS        \
178   FOLLY_GCC_DISABLE_WARNING("-Wshadow-compatible-local") \
179   FOLLY_GCC_DISABLE_WARNING("-Wshadow-local")
180 #else
181 #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS /* empty */
182 #endif
183
184 /* Platform specific TLS support
185  * gcc implements __thread
186  * msvc implements __declspec(thread)
187  * the semantics are the same
188  * (but remember __thread has different semantics when using emutls (ex. apple))
189  */
190 #if defined(_MSC_VER)
191 # define FOLLY_TLS __declspec(thread)
192 #elif defined(__GNUC__) || defined(__clang__)
193 # define FOLLY_TLS __thread
194 #else
195 # error cannot define platform specific thread local storage
196 #endif
197
198 #if FOLLY_MOBILE
199 #undef FOLLY_TLS
200 #endif
201
202 // It turns out that GNU libstdc++ and LLVM libc++ differ on how they implement
203 // the 'std' namespace; the latter uses inline namespaces. Wrap this decision
204 // up in a macro to make forward-declarations easier.
205 #if FOLLY_USE_LIBCPP
206 #include <__config> // @manual
207 #define FOLLY_NAMESPACE_STD_BEGIN     _LIBCPP_BEGIN_NAMESPACE_STD
208 #define FOLLY_NAMESPACE_STD_END       _LIBCPP_END_NAMESPACE_STD
209 #else
210 #define FOLLY_NAMESPACE_STD_BEGIN     namespace std {
211 #define FOLLY_NAMESPACE_STD_END       }
212 #endif
213
214 // If the new c++ ABI is used, __cxx11 inline namespace needs to be added to
215 // some types, e.g. std::list.
216 #if _GLIBCXX_USE_CXX11_ABI
217 #define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN \
218   inline _GLIBCXX_BEGIN_NAMESPACE_CXX11
219 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_END   _GLIBCXX_END_NAMESPACE_CXX11
220 #else
221 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN
222 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_END
223 #endif
224
225 // MSVC specific defines
226 // mainly for posix compat
227 #ifdef _MSC_VER
228 #include <folly/portability/SysTypes.h>
229
230 // compiler specific to compiler specific
231 // nolint
232 # define __PRETTY_FUNCTION__ __FUNCSIG__
233
234 // Hide a GCC specific thing that breaks MSVC if left alone.
235 # define __extension__
236
237 // We have compiler support for the newest of the new, but
238 // MSVC doesn't tell us that.
239 #define __SSE4_2__ 1
240
241 #endif
242
243 // Debug
244 namespace folly {
245 #ifdef NDEBUG
246 constexpr auto kIsDebug = false;
247 #else
248 constexpr auto kIsDebug = true;
249 #endif
250 } // namespace folly
251
252 // Endianness
253 namespace folly {
254 #ifdef _MSC_VER
255 // It's MSVC, so we just have to guess ... and allow an override
256 #ifdef FOLLY_ENDIAN_BE
257 constexpr auto kIsLittleEndian = false;
258 #else
259 constexpr auto kIsLittleEndian = true;
260 #endif
261 #else
262 constexpr auto kIsLittleEndian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
263 #endif
264 constexpr auto kIsBigEndian = !kIsLittleEndian;
265 } // namespace folly
266
267 #ifndef FOLLY_SSE
268 # if defined(__SSE4_2__)
269 #  define FOLLY_SSE 4
270 #  define FOLLY_SSE_MINOR 2
271 # elif defined(__SSE4_1__)
272 #  define FOLLY_SSE 4
273 #  define FOLLY_SSE_MINOR 1
274 # elif defined(__SSE4__)
275 #  define FOLLY_SSE 4
276 #  define FOLLY_SSE_MINOR 0
277 # elif defined(__SSE3__)
278 #  define FOLLY_SSE 3
279 #  define FOLLY_SSE_MINOR 0
280 # elif defined(__SSE2__)
281 #  define FOLLY_SSE 2
282 #  define FOLLY_SSE_MINOR 0
283 # elif defined(__SSE__)
284 #  define FOLLY_SSE 1
285 #  define FOLLY_SSE_MINOR 0
286 # else
287 #  define FOLLY_SSE 0
288 #  define FOLLY_SSE_MINOR 0
289 # endif
290 #endif
291
292 #define FOLLY_SSE_PREREQ(major, minor) \
293   (FOLLY_SSE > major || FOLLY_SSE == major && FOLLY_SSE_MINOR >= minor)
294
295 #if FOLLY_UNUSUAL_GFLAGS_NAMESPACE
296 namespace FOLLY_GFLAGS_NAMESPACE { }
297 namespace gflags {
298 using namespace FOLLY_GFLAGS_NAMESPACE;
299 } // namespace gflags
300 #endif
301
302 // for TARGET_OS_IPHONE
303 #ifdef __APPLE__
304 #include <TargetConditionals.h> // @manual
305 #endif
306
307 // RTTI may not be enabled for this compilation unit.
308 #if defined(__GXX_RTTI) || defined(__cpp_rtti) || \
309     (defined(_MSC_VER) && defined(_CPPRTTI))
310 # define FOLLY_HAS_RTTI 1
311 #endif
312
313 #if defined(__APPLE__) || defined(_MSC_VER)
314 #define FOLLY_STATIC_CTOR_PRIORITY_MAX
315 #else
316 // 101 is the highest priority allowed by the init_priority attribute.
317 // This priority is already used by JEMalloc and other memory allocators so
318 // we will take the next one.
319 #define FOLLY_STATIC_CTOR_PRIORITY_MAX __attribute__((__init_priority__(102)))
320 #endif
321
322 namespace folly {
323
324 #if __OBJC__
325 constexpr auto kIsObjC = true;
326 #else
327 constexpr auto kIsObjC = false;
328 #endif
329
330 #if FOLLY_MOBILE
331 constexpr auto kIsMobile = true;
332 #else
333 constexpr auto kIsMobile = false;
334 #endif
335
336 #if defined(__linux__) && !FOLLY_MOBILE
337 constexpr auto kIsLinux = true;
338 #else
339 constexpr auto kIsLinux = false;
340 #endif
341
342 #if defined(_WIN32)
343 constexpr auto kIsWindows = true;
344 constexpr auto kMscVer = _MSC_VER;
345 #else
346 constexpr auto kIsWindows = false;
347 constexpr auto kMscVer = 0;
348 #endif
349 } // namespace folly
350
351 // Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14
352 // constexpr support is "good enough".
353 #ifndef FOLLY_USE_CPP14_CONSTEXPR
354 #if defined(__clang__)
355 #define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L
356 #elif defined(__GNUC__)
357 #define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L
358 #else
359 #define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC?
360 #endif
361 #endif
362
363 #if FOLLY_USE_CPP14_CONSTEXPR
364 #define FOLLY_CPP14_CONSTEXPR constexpr
365 #else
366 #define FOLLY_CPP14_CONSTEXPR inline
367 #endif
368
369 #if __cpp_coroutines >= 201703L && FOLLY_HAS_INCLUDE(<experimental/coroutine>)
370 #define FOLLY_HAS_COROUTINES 1
371 #elif _MSC_VER && _RESUMABLE_FUNCTIONS_SUPPORTED
372 #define FOLLY_HAS_COROUTINES 1
373 #endif
374
375 // MSVC 2017.5
376 #if __cpp_noexcept_function_type >= 201510 || _MSC_FULL_VER >= 191225816
377 #define FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE 1
378 #endif