16 #ifndef INCLUDE_NN_NLIB_PLATFORM_UNIX_H_ 17 #define INCLUDE_NN_NLIB_PLATFORM_UNIX_H_ 18 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_ 19 #error do not include directly 22 #if defined(__linux__) || defined(__FreeBSD__) || defined(__CYGWIN__) || \ 23 (defined(__APPLE__) && defined(__MACH__)) 28 #ifndef __STDC_LIMIT_MACROS 29 #warning __STDC_LIMIT_MACROS not defined, compile may fail 30 #define __STDC_LIMIT_MACROS 32 #ifndef __STDC_CONSTANT_MACROS 33 #warning __STDC_CONSTANT_MACROS not defined, compile may fail 34 #define __STDC_CONSTANT_MACROS 38 #if defined(__APPLE__) && defined(__MACH__) 39 #define _DARWIN_UNLIMITED_SELECT 40 #include <libkern/OSAtomic.h> 42 #if __has_include(<os/lock.h> ) 56 #if !defined(__GNUC__) && !defined(__clang__) 60 #if !defined(__FreeBSD__) && !defined(__APPLE__) 66 #include <sys/types.h> 69 #include <sys/socket.h> 70 #include <netinet/tcp.h> 72 #include <netinet/in.h> 73 #include <arpa/inet.h> 77 #if defined(__FreeBSD__) || defined(__APPLE__) 78 #include <dispatch/dispatch.h> 81 #if defined(__i386__) || defined(__x86_64__) 82 #include <x86intrin.h> 86 #define NLIB_VIS_HIDDEN __attribute__((visibility("hidden"))) 87 #define NLIB_VIS_PUBLIC __attribute__((visibility("default"))) 88 #define NLIB_WEAKSYMBOL __attribute__((weak)) 90 #define NLIB_VIS_HIDDEN 91 #define NLIB_VIS_PUBLIC 92 #define NLIB_WEAKSYMBOL 95 #define NLIB_ALWAYS_INLINE inline __attribute__((always_inline)) 96 #define NLIB_NEVER_INLINE __attribute__((__noinline__)) 97 #define NLIB_LIKELY(x) __builtin_expect(!!(x), 1) 98 #define NLIB_UNLIKELY(x) __builtin_expect(!!(x), 0) 99 #define NLIB_EXPECT(var, exp_value) __builtin_expect((var), (exp_value)) 100 #if defined(__cplusplus) && __has_cpp_attribute(nodiscard) 101 #define NLIB_CHECK_RESULT [[nodiscard]] 103 #define NLIB_CHECK_RESULT __attribute__((warn_unused_result)) 105 #if defined(__cplusplus) && __has_cpp_attribute(noreturn) 106 #define NLIB_NORETURN [[noreturn]] 108 #define NLIB_NORETURN __attribute__((noreturn)) 110 #if defined(__cplusplus) && __has_cpp_attribute(fallthrough) 111 #define NLIB_FALLTHROUGH [[fallthrough]] 113 #define NLIB_FALLTHROUGH 115 #define NLIB_NONNULL __attribute__((nonnull)) 116 #define NLIB_NONNULL_1 __attribute__((nonnull(1))) 117 #define NLIB_NONNULL_2 __attribute__((nonnull(2))) 118 #define NLIB_NONNULL_3 __attribute__((nonnull(3))) 119 #define NLIB_NONNULL_4 __attribute__((nonnull(4))) 120 #define NLIB_NONNULL_5 __attribute__((nonnull(5))) 121 #define NLIB_NONNULL_ENABLED 122 #define NLIB_ATTRIBUTE_MALLOC __attribute__((malloc)) 123 #define NLIB_ATTRIBUTE_PURE __attribute__((pure)) 124 #define NLIB_ATTRIBUTE_CONST __attribute__((const)) 127 #if __has_attribute(alloc_size) 128 #define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) __attribute__((alloc_size(n))) 129 #define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) __attribute__((alloc_size(n0, n1))) 131 #define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) 132 #define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) 134 #if __has_attribute(alloc_align) 135 #define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) __attribute__((alloc_align(algn))) 137 #define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) 139 #if __has_attribute(assume_aligned) 140 #define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) __attribute__((assume_aligned(n))) 142 #define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) 145 #define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) __attribute__((alloc_size(n))) 146 #define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) __attribute__((alloc_size(n0, n1))) 147 #define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) __attribute__((alloc_align(algn))) 148 #define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) __attribute__((assume_aligned(n))) 151 #ifndef NLIB_DEPRECATED 152 #if defined(__cplusplus) && __has_cpp_attribute(deprecated) 153 #define NLIB_DEPRECATED [[deprecated]] 155 #define NLIB_DEPRECATED __attribute__((deprecated)) 158 #ifndef NLIB_DEPRECATED_MSG 159 #if defined(__cplusplus) && __has_cpp_attribute(deprecated) 160 #define NLIB_DEPRECATED_MSG(msg) [[deprecated(msg)]] 162 #define NLIB_DEPRECATED_MSG(msg) __attribute__((deprecated)) 166 #if defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) 167 #define NLIB_LITTLE_ENDIAN 168 #elif defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) 169 #undef NLIB_LITTLE_ENDIAN 171 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 172 #define NLIB_LITTLE_ENDIAN 174 #undef NLIB_LITTLE_ENDIAN 177 #if defined(__x86_64__) || defined(__aarch64__) 181 #define NLIB_MEMORY_ORDER_RELEASE __atomic_thread_fence(__ATOMIC_RELEASE) 182 #define NLIB_MEMORY_ORDER_ACQUIRE __atomic_thread_fence(__ATOMIC_ACQUIRE) 183 #define NLIB_MEMORY_ORDER_ACQ_REL __atomic_thread_fence(__ATOMIC_ACQ_REL) 184 #define NLIB_MEMORY_ORDER_SEQ_CST __atomic_thread_fence(__ATOMIC_SEQ_CST) 187 #define NLIB_PTHREAD_nlib_tls_alloc 188 #define NLIB_PTHREAD_nlib_tls_free 189 #define NLIB_PTHREAD_nlib_tls_setvalue 190 #define NLIB_PTHREAD_nlib_tls_getvalue 192 #ifndef _LIBCPP_VERSION 193 NLIB_CAPABILITY(
"mutex")
197 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 201 #define NLIB_MUTEX_INITIALIZER \ 202 (__builtin_constant_p(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) \ 203 ? PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ 204 : PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) 206 #define NLIB_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 209 #define NLIB_PTHREAD_nlib_mutex_init 210 #define NLIB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 214 #define NLIB_PTHREAD_nlib_mutex_lock 215 #define NLIB_PTHREAD_nlib_mutex_unlock 216 #define NLIB_PTHREAD_nlib_mutex_trylock 217 #define NLIB_PTHREAD_nlib_mutex_destroy 220 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 221 #define NLIB_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 222 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 223 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 224 #define NLIB_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER 225 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER 226 #elif defined(__FreeBSD__) 229 #define NLIB_RECURSIVE_MUTEX_INITIALIZER \ 230 (__builtin_constant_p((pthread_mutex_t)255) ? (pthread_mutex_t)255 : (pthread_mutex_t)255) 231 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER \ 232 (__builtin_constant_p((pthread_mutex_t)255) ? (pthread_mutex_t)255 : (pthread_mutex_t)255) 233 #elif defined(NLIB_ALPINE) 235 #define NLIB_RECURSIVE_MUTEX_INITIALIZER \ 241 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER \ 251 #if defined(__APPLE__) 258 #define NLIB_COND_INITIALIZER PTHREAD_COND_INITIALIZER 260 #define NLIB_PTHREAD_nlib_cond_init 261 #define NLIB_PTHREAD_nlib_cond_signal 262 #define NLIB_PTHREAD_nlib_cond_broadcast 263 #define NLIB_PTHREAD_nlib_cond_wait 264 #define NLIB_PTHREAD_nlib_cond_destroy 268 #define NLIB_PTHREAD_nlib_thread_join 269 #define NLIB_PTHREAD_nlib_thread_detach 270 #define NLIB_PTHREAD_nlib_thread_equal 271 #define NLIB_PTHREAD_nlib_thread_self 273 #if defined(__APPLE__) 274 #define NLIB_SPINLOCK_HAS_NATIVE 275 #if __has_include(<os/lock.h> ) 277 #define NLIB_SPINLOCK_INITIALIZER OS_UNFAIR_LOCK_INIT 279 *lock = OS_UNFAIR_LOCK_INIT;
282 os_unfair_lock_lock(lock);
285 return os_unfair_lock_trylock(lock) ? 0 : EBUSY;
288 os_unfair_lock_unlock(lock);
292 #define NLIB_SPINLOCK_INITIALIZER (0) 297 OSSpinLockLock(lock);
300 return OSSpinLockTry(lock) ? 0 : EBUSY;
303 OSSpinLockUnlock(lock);
312 #if defined(__clang__) 313 #if __has_feature(cxx_unicode_literals) 314 #ifndef __cpp_unicode_characters 315 #define __cpp_unicode_characters 200704L // N2249 318 #if __has_feature(cxx_exceptions) 319 #if __has_feature(cxx_noexcept) 320 #define NLIB_CXX11_NOEXCEPT 323 #define NLIB_NOEXCEPT 327 #ifndef __cpp_unicode_characters 328 #define __cpp_unicode_characters 200704L // N2249 330 #define NLIB_CXX11_NOEXCEPT 336 #define NLIB_ONCE_HAS_NATIVE 337 #define NLIB_TIMESPEC_HAS_NATIVE 338 #define NLIB_IOVEC_HAS_NATIVE 340 #ifdef PTHREAD_RWLOCK_INITIALIZER 341 #define NLIB_RWLOCK_HAS_NATIVE 343 #ifdef NLIB_RWLOCK_HAS_NATIVE 344 #ifndef _LIBCPP_VERSION 345 NLIB_CAPABILITY(
"mutex")
348 #define NLIB_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER 350 #define NLIB_PTHREAD_nlib_rwlock_init 351 #define NLIB_PTHREAD_nlib_rwlock_destroy 352 #define NLIB_PTHREAD_nlib_rwlock_tryrdlock 353 #define NLIB_PTHREAD_nlib_rwlock_trywrlock 354 #define NLIB_PTHREAD_nlib_rwlock_rdlock 355 #define NLIB_PTHREAD_nlib_rwlock_rdunlock 356 #define NLIB_PTHREAD_nlib_rwlock_wrlock 357 #define NLIB_PTHREAD_nlib_rwlock_wrunlock 360 #ifdef PTHREAD_BARRIER_SERIAL_THREAD 361 #define NLIB_BARRIER_HAS_NATIVE 363 #ifdef NLIB_BARRIER_HAS_NATIVE 365 #define NLIB_PTHREAD_nlib_barrier_init 366 #define NLIB_PTHREAD_nlib_barrier_destroy 369 #define NLIB_THREAD_ATTR_HAS_NATIVE 371 #ifndef pthread_cleanup_push 372 #error pthread_cleanup_push must be a macro 375 #ifndef pthread_cleanup_pop 376 #error pthread_cleanup_pop must be a macro 387 #define NLIB_LIBC_nlib_memcmp 388 #define NLIB_LIBC_nlib_strlen 389 #define NLIB_LIBC_nlib_strnlen 390 #if defined(__STDC_LIB_EXT1__) 391 #define NLIB_LIBC_nlib_wcslen 392 #define NLIB_LIBC_nlib_wcsnlen 393 #define NLIB_LIBC_nlib_strncpy 394 #define NLIB_LIBC_nlib_strcpy 395 #define NLIB_LIBC_nlib_wcsncpy 396 #define NLIB_LIBC_nlib_wcscpy 398 #define NLIB_LIBC_nlib_strchr 399 #define NLIB_LIBC_nlib_strrchr 405 #define NLIB_ATOMIC_RELAXED __ATOMIC_RELAXED 406 #define NLIB_ATOMIC_ACQUIRE __ATOMIC_ACQUIRE 407 #define NLIB_ATOMIC_RELEASE __ATOMIC_RELEASE 408 #define NLIB_ATOMIC_ACQ_REL __ATOMIC_ACQ_REL 409 #define NLIB_ATOMIC_SEQ_CST __ATOMIC_SEQ_CST 411 #if defined(NLIB_DOXYGEN) 416 int success_memorder,
int failure_memorder);
432 int success_memorder,
int failure_memorder);
448 int success_memorder,
int failure_memorder);
453 #if defined(__has_feature) && __has_feature(thread_sanitizer) 454 #define NLIB_TSAN_LOCK pthread_mutex_lock(&nlib_tsan_lock); 455 #define NLIB_TSAN_UNLOCK pthread_mutex_unlock(&nlib_tsan_lock); 457 #define NLIB_TSAN_LOCK 458 #define NLIB_TSAN_UNLOCK 464 rval = __atomic_load_n(ptr, memorder);
471 __atomic_store_n(ptr, val, memorder);
478 rval = __atomic_exchange_n(ptr, val, memorder);
485 int success_memorder,
int failure_memorder) {
488 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak, success_memorder,
497 rval = __atomic_add_fetch(ptr, val, memorder);
505 rval = __atomic_sub_fetch(ptr, val, memorder);
513 rval = __atomic_and_fetch(ptr, val, memorder);
521 rval = __atomic_xor_fetch(ptr, val, memorder);
529 rval = __atomic_or_fetch(ptr, val, memorder);
537 rval = __atomic_fetch_add(ptr, val, memorder);
545 rval = __atomic_fetch_sub(ptr, val, memorder);
553 rval = __atomic_fetch_and(ptr, val, memorder);
561 rval = __atomic_fetch_xor(ptr, val, memorder);
569 rval = __atomic_fetch_or(ptr, val, memorder);
577 rval = __atomic_load_n(ptr, memorder);
584 __atomic_store_n(ptr, val, memorder);
591 rval = __atomic_exchange_n(ptr, val, memorder);
599 rval = __atomic_exchange_n(ptr, val, memorder);
606 int success_memorder,
int failure_memorder) {
609 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak, success_memorder,
618 rval = __atomic_add_fetch(ptr, val, memorder);
626 rval = __atomic_sub_fetch(ptr, val, memorder);
634 rval = __atomic_and_fetch(ptr, val, memorder);
642 rval = __atomic_xor_fetch(ptr, val, memorder);
650 rval = __atomic_or_fetch(ptr, val, memorder);
658 rval = __atomic_fetch_add(ptr, val, memorder);
666 rval = __atomic_fetch_sub(ptr, val, memorder);
674 rval = __atomic_fetch_and(ptr, val, memorder);
682 rval = __atomic_fetch_xor(ptr, val, memorder);
690 rval = __atomic_fetch_or(ptr, val, memorder);
698 rval = __atomic_load_n(ptr, memorder);
705 __atomic_store_n(ptr, val, memorder);
711 int success_memorder,
int failure_memorder) {
714 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak, success_memorder,
721 __atomic_thread_fence(memorder);
729 #endif // INCLUDE_NN_NLIB_PLATFORM_UNIX_H_