NVIDIA DeepStream SDK API Reference

9.2 Release
includes/opentelemetry/common/macros.h
Go to the documentation of this file.
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 /*
7  OPENTELEMETRY_HAVE_BUILTIN&OPENTELEMETRY_HAVE_FEATURE
8 
9  Checks whether the compiler supports a Clang Feature Checking Macro, and if
10  so, checks whether it supports the provided builtin function "x" where x
11  is one of the functions noted in
12  https://clang.llvm.org/docs/LanguageExtensions.html
13 
14  Note: Use this macro to avoid an extra level of #ifdef __has_builtin check.
15  http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html
16 */
17 #if !defined(OPENTELEMETRY_HAVE_BUILTIN)
18 # ifdef __has_builtin
19 # define OPENTELEMETRY_HAVE_BUILTIN(x) __has_builtin(x)
20 # else
21 # define OPENTELEMETRY_HAVE_BUILTIN(x) 0
22 # endif
23 #endif
24 
25 #if !defined(OPENTELEMETRY_HAVE_FEATURE)
26 # ifdef __has_feature
27 # define OPENTELEMETRY_HAVE_FEATURE(f) __has_feature(f)
28 # else
29 # define OPENTELEMETRY_HAVE_FEATURE(f) 0
30 # endif
31 #endif
32 
33 /*
34  has feature
35 
36  OPENTELEMETRY_HAVE_ATTRIBUTE
37 
38  A function-like feature checking macro that is a wrapper around
39  `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
40  nonzero constant integer if the attribute is supported or 0 if not.
41 
42  It evaluates to zero if `__has_attribute` is not defined by the compiler.
43 
44  GCC: https://gcc.gnu.org/gcc-5/changes.html
45  Clang: https://clang.llvm.org/docs/LanguageExtensions.html
46 */
47 #if !defined(OPENTELEMETRY_HAVE_ATTRIBUTE)
48 # ifdef __has_attribute
49 # define OPENTELEMETRY_HAVE_ATTRIBUTE(x) __has_attribute(x)
50 # else
51 # define OPENTELEMETRY_HAVE_ATTRIBUTE(x) 0
52 # endif
53 #endif
54 
55 /*
56  OPENTELEMETRY_HAVE_CPP_ATTRIBUTE
57 
58  A function-like feature checking macro that accepts C++11 style attributes.
59  It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
60  (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
61  find `__has_cpp_attribute`, will evaluate to 0.
62 */
63 #if !defined(OPENTELEMETRY_HAVE_CPP_ATTRIBUTE)
64 # if defined(__cplusplus) && defined(__has_cpp_attribute)
65 // NOTE: requiring __cplusplus above should not be necessary, but
66 // works around https://bugs.llvm.org/show_bug.cgi?id=23435.
67 # define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
68 # else
69 # define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) 0
70 # endif
71 #endif
72 
73 /*
74  Expected usage pattern:
75 
76  if OPENTELEMETRY_LIKELY_CONDITION (ptr != nullptr)
77  {
78  do_something_likely();
79  } else {
80  do_something_unlikely();
81  }
82 
83  This pattern works with gcc/clang and __builtin_expect(),
84  as well as with C++20.
85  It is unclear if __builtin_expect() will be deprecated
86  in favor of C++20 [[likely]] or not.
87 
88  OPENTELEMETRY_LIKELY_CONDITION is preferred over OPENTELEMETRY_LIKELY,
89  to be revisited when C++20 is required.
90 */
91 
92 #if !defined(OPENTELEMETRY_LIKELY_CONDITION) && defined(__cplusplus)
93 // Only use likely with C++20
94 # if __cplusplus >= 202002L
95 // GCC 9 has likely attribute but do not support declare it at the beginning of statement
96 # if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
97 # if __has_cpp_attribute(likely)
98 # define OPENTELEMETRY_LIKELY_CONDITION(C) (C) [[likely]]
99 # endif
100 # endif
101 # endif
102 #endif
103 #if !defined(OPENTELEMETRY_LIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__))
104 // Only use if supported by the compiler
105 # define OPENTELEMETRY_LIKELY_CONDITION(C) (__builtin_expect(!!(C), true))
106 #endif
107 #ifndef OPENTELEMETRY_LIKELY_CONDITION
108 // Do not use likely annotations
109 # define OPENTELEMETRY_LIKELY_CONDITION(C) (C)
110 #endif
111 
112 #if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && defined(__cplusplus)
113 // Only use unlikely with C++20
114 # if __cplusplus >= 202002L
115 // GCC 9 has unlikely attribute but do not support declare it at the beginning of statement
116 # if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
117 # if __has_cpp_attribute(unlikely)
118 # define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) [[unlikely]]
119 # endif
120 # endif
121 # endif
122 #endif
123 #if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__))
124 // Only use if supported by the compiler
125 # define OPENTELEMETRY_UNLIKELY_CONDITION(C) (__builtin_expect(!!(C), false))
126 #endif
127 #ifndef OPENTELEMETRY_UNLIKELY_CONDITION
128 // Do not use unlikely annotations
129 # define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C)
130 #endif
131 
132 /*
133  Expected usage pattern:
134 
135  if (ptr != nullptr)
136  OPENTELEMETRY_LIKELY
137  {
138  do_something_likely();
139  } else {
140  do_something_unlikely();
141  }
142 
143  This pattern works starting with C++20.
144  See https://en.cppreference.com/w/cpp/language/attributes/likely
145 
146  Please use OPENTELEMETRY_LIKELY_CONDITION instead for now.
147 */
148 
149 #if !defined(OPENTELEMETRY_LIKELY) && defined(__cplusplus)
150 // Only use likely with C++20
151 # if __cplusplus >= 202002L
152 // GCC 9 has likely attribute but do not support declare it at the beginning of statement
153 # if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
154 # if __has_cpp_attribute(likely)
155 # define OPENTELEMETRY_LIKELY [[likely]]
156 # endif
157 # endif
158 # endif
159 #endif
160 
161 #ifndef OPENTELEMETRY_LIKELY
162 # define OPENTELEMETRY_LIKELY
163 #endif
164 
165 #if !defined(OPENTELEMETRY_UNLIKELY) && defined(__cplusplus)
166 // Only use unlikely with C++20
167 # if __cplusplus >= 202002L
168 // GCC 9 has unlikely attribute but do not support declare it at the beginning of statement
169 # if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
170 # if __has_cpp_attribute(unlikely)
171 # define OPENTELEMETRY_UNLIKELY [[unlikely]]
172 # endif
173 # endif
174 # endif
175 #endif
176 
177 #ifndef OPENTELEMETRY_UNLIKELY
178 # define OPENTELEMETRY_UNLIKELY
179 #endif
180 
187 #if defined(__cplusplus) && __cplusplus >= 201703L
188 # define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]]
189 #elif defined(__clang__)
190 # define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused))
191 #elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
192 # define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused))
193 #elif (defined(_MSC_VER) && _MSC_VER >= 1910) && (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
194 # define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]]
195 #else
196 # define OPENTELEMETRY_MAYBE_UNUSED
197 #endif
198 
199 #ifndef OPENTELEMETRY_RTTI_ENABLED
200 # if defined(__clang__)
201 # if __has_feature(cxx_rtti)
202 # define OPENTELEMETRY_RTTI_ENABLED
203 # endif
204 # elif defined(__GNUG__)
205 # if defined(__GXX_RTTI)
206 # define OPENTELEMETRY_RTTI_ENABLED
207 # endif
208 # elif defined(_MSC_VER)
209 # if defined(_CPPRTTI)
210 # define OPENTELEMETRY_RTTI_ENABLED
211 # endif
212 # endif
213 #endif
214 
215 #if defined(__cplusplus) && __cplusplus >= 201402L
216 # define OPENTELEMETRY_DEPRECATED [[deprecated]]
217 #elif defined(__clang__)
218 # define OPENTELEMETRY_DEPRECATED __attribute__((deprecated))
219 #elif defined(__GNUC__)
220 # define OPENTELEMETRY_DEPRECATED __attribute__((deprecated))
221 #elif defined(_MSC_VER)
222 # if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
223 # define OPENTELEMETRY_DEPRECATED [[deprecated]]
224 # else
225 # define OPENTELEMETRY_DEPRECATED __declspec(deprecated)
226 # endif
227 #else
228 # define OPENTELEMETRY_DEPRECATED
229 #endif
230 
231 #if defined(__cplusplus) && __cplusplus >= 201402L
232 # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]]
233 #elif defined(__clang__)
234 # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg)))
235 #elif defined(__GNUC__)
236 # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg)))
237 #elif defined(_MSC_VER)
238 # if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
239 # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]]
240 # else
241 # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __declspec(deprecated(msg))
242 # endif
243 #else
244 # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg)
245 #endif
246 
247 // Regex support
248 #if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9))
249 # define OPENTELEMETRY_HAVE_WORKING_REGEX 0
250 #else
251 # define OPENTELEMETRY_HAVE_WORKING_REGEX 1
252 #endif
253 
254 /* clang-format off */
255 
319 /* clang-format on */
320 
321 #if defined(__clang__)
322 
323 # define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default")))
324 # define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden")))
325 
326 #elif defined(__GNUC__)
327 
328 # define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default")))
329 # define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden")))
330 
331 #else
332 
333 /* Add support for other compilers here. */
334 
335 # define OPENTELEMETRY_API_SINGLETON
336 # define OPENTELEMETRY_LOCAL_SYMBOL
337 
338 #endif
339 
340 //
341 // Atomic wrappers based on compiler intrinsics for memory read/write.
342 // The tailing number is read/write length in bits.
343 //
344 // N.B. Compiler intrinsic is used because the usage of C++ standard library is restricted in the
345 // OpenTelemetry C++ API.
346 //
347 #if defined(__GNUC__)
348 
349 # define OPENTELEMETRY_ATOMIC_READ_8(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST)
350 # define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST)
351 
352 #elif defined(_MSC_VER)
353 
354 # include <intrin.h>
355 
356 # define OPENTELEMETRY_ATOMIC_READ_8(ptr) \
357  static_cast<uint8_t>(_InterlockedCompareExchange8(reinterpret_cast<char *>(ptr), 0, 0))
358 # define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) \
359  _InterlockedExchange8(reinterpret_cast<char *>(ptr), static_cast<char>(value))
360 
361 #else
362 # error port atomics read/write for the current platform
363 #endif
364 
365 /* clang-format on */
366 //
367 // The if/elif order matters here. If both OPENTELEMETRY_BUILD_IMPORT_DLL and
368 // OPENTELEMETRY_BUILD_EXPORT_DLL are defined, the former takes precedence.
369 //
370 // TODO: consider define OPENTELEMETRY_EXPORT for cygwin/gcc, see below link.
371 // https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support
372 //
373 #if defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_IMPORT_DLL)
374 
375 # define OPENTELEMETRY_EXPORT __declspec(dllimport)
376 
377 #elif defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_EXPORT_DLL)
378 
379 # define OPENTELEMETRY_EXPORT __declspec(dllexport)
380 
381 #else
382 
383 //
384 // build OpenTelemetry as static library or not on Windows.
385 //
386 # define OPENTELEMETRY_EXPORT
387 
388 #endif
389 
390 // OPENTELEMETRY_HAVE_EXCEPTIONS
391 //
392 // Checks whether the compiler both supports and enables exceptions. Many
393 // compilers support a "no exceptions" mode that disables exceptions.
394 //
395 // Generally, when OPENTELEMETRY_HAVE_EXCEPTIONS is not defined:
396 //
397 // * Code using `throw` and `try` may not compile.
398 // * The `noexcept` specifier will still compile and behave as normal.
399 // * The `noexcept` operator may still return `false`.
400 //
401 // For further details, consult the compiler's documentation.
402 #ifndef OPENTELEMETRY_HAVE_EXCEPTIONS
403 # if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__) < 306
404 // Clang < 3.6
405 // http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
406 # if defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)
407 # define OPENTELEMETRY_HAVE_EXCEPTIONS 1
408 # endif // defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)
409 # elif OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)
410 # define OPENTELEMETRY_HAVE_EXCEPTIONS 1
411 // Handle remaining special cases and default to exceptions being supported.
412 # elif !(defined(__GNUC__) && !defined(__EXCEPTIONS) && !defined(__cpp_exceptions)) && \
413  !(defined(_MSC_VER) && !defined(_CPPUNWIND))
414 # define OPENTELEMETRY_HAVE_EXCEPTIONS 1
415 # endif
416 #endif
417 #ifndef OPENTELEMETRY_HAVE_EXCEPTIONS
418 # define OPENTELEMETRY_HAVE_EXCEPTIONS 0
419 #endif
420 
421 /*
422  OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function
423  parameter or implicit object parameter is retained by the return value of the
424  annotated function (or, for a parameter of a constructor, in the value of the
425  constructed object). This attribute causes warnings to be produced if a
426  temporary object does not live long enough.
427 
428  When applied to a reference parameter, the referenced object is assumed to be
429  retained by the return value of the function. When applied to a non-reference
430  parameter (for example, a pointer or a class type), all temporaries
431  referenced by the parameter are assumed to be retained by the return value of
432  the function.
433 
434  See also the upstream documentation:
435  https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
436 */
437 #ifndef OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND
438 # if OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
439 # define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
440 # elif OPENTELEMETRY_HAVE_ATTRIBUTE(lifetimebound)
441 # define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
442 # else
443 # define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND
444 # endif
445 #endif
446 
447 // OPENTELEMETRY_HAVE_MEMORY_SANITIZER
448 //
449 // MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of
450 // a compiler instrumentation module and a run-time library.
451 #ifndef OPENTELEMETRY_HAVE_MEMORY_SANITIZER
452 # if !defined(__native_client__) && OPENTELEMETRY_HAVE_FEATURE(memory_sanitizer)
453 # define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 1
454 # else
455 # define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 0
456 # endif
457 #endif
458 
459 #if OPENTELEMETRY_HAVE_MEMORY_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_memory)
460 # define OPENTELEMETRY_SANITIZER_NO_MEMORY \
461  __attribute__((no_sanitize_memory)) // __attribute__((no_sanitize("memory")))
462 #else
463 # define OPENTELEMETRY_SANITIZER_NO_MEMORY
464 #endif
465 
466 // OPENTELEMETRY_HAVE_THREAD_SANITIZER
467 //
468 // ThreadSanitizer (TSan) is a fast data race detector.
469 #ifndef OPENTELEMETRY_HAVE_THREAD_SANITIZER
470 # if defined(__SANITIZE_THREAD__)
471 # define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1
472 # elif OPENTELEMETRY_HAVE_FEATURE(thread_sanitizer)
473 # define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1
474 # else
475 # define OPENTELEMETRY_HAVE_THREAD_SANITIZER 0
476 # endif
477 #endif
478 
479 #if OPENTELEMETRY_HAVE_THREAD_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_thread)
480 # define OPENTELEMETRY_SANITIZER_NO_THREAD \
481  __attribute__((no_sanitize_thread)) // __attribute__((no_sanitize("thread")))
482 #else
483 # define OPENTELEMETRY_SANITIZER_NO_THREAD
484 #endif
485 
486 // OPENTELEMETRY_HAVE_ADDRESS_SANITIZER
487 //
488 // AddressSanitizer (ASan) is a fast memory error detector.
489 #ifndef OPENTELEMETRY_HAVE_ADDRESS_SANITIZER
490 # if defined(__SANITIZE_ADDRESS__)
491 # define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1
492 # elif OPENTELEMETRY_HAVE_FEATURE(address_sanitizer)
493 # define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1
494 # else
495 # define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 0
496 # endif
497 #endif
498 
499 // OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER
500 //
501 // Hardware-Assisted AddressSanitizer (or HWASAN) is even faster than asan
502 // memory error detector which can use CPU features like ARM TBI, Intel LAM or
503 // AMD UAI.
504 #ifndef OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER
505 # if defined(__SANITIZE_HWADDRESS__)
506 # define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1
507 # elif OPENTELEMETRY_HAVE_FEATURE(hwaddress_sanitizer)
508 # define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1
509 # else
510 # define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 0
511 # endif
512 #endif
513 
514 #if OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_address)
515 # define OPENTELEMETRY_SANITIZER_NO_ADDRESS \
516  __attribute__((no_sanitize_address)) // __attribute__((no_sanitize("address")))
517 #elif OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && defined(_MSC_VER) && _MSC_VER >= 1928
518 # define OPENTELEMETRY_SANITIZER_NO_ADDRESS __declspec(no_sanitize_address)
519 #elif OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize)
520 # define OPENTELEMETRY_SANITIZER_NO_ADDRESS __attribute__((no_sanitize("hwaddress")))
521 #else
522 # define OPENTELEMETRY_SANITIZER_NO_ADDRESS
523 #endif