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__) || \ 23 defined(__FreeBSD__) || \ 24 defined(__CYGWIN__) || \ 25 (defined(__APPLE__) && defined(__MACH__)) 30 #ifndef __STDC_LIMIT_MACROS 31 #warning __STDC_LIMIT_MACROS not defined, compile may fail 32 #define __STDC_LIMIT_MACROS 34 #ifndef __STDC_CONSTANT_MACROS 35 #warning __STDC_CONSTANT_MACROS not defined, compile may fail 36 #define __STDC_CONSTANT_MACROS 40 #if defined(__APPLE__) && defined(__MACH__) 41 #define _DARWIN_UNLIMITED_SELECT 42 #include <libkern/OSAtomic.h> 44 #if __has_include( <os/lock.h> ) 58 #if !defined(__GNUC__) && !defined(__clang__) 62 #if !defined(__FreeBSD__) && !defined(__APPLE__) 68 #include <sys/types.h> 71 #include <sys/socket.h> 72 #include <netinet/tcp.h> 74 #include <netinet/in.h> 75 #include <arpa/inet.h> 79 #if defined(__FreeBSD__) || defined(__APPLE__) 80 #include <dispatch/dispatch.h> 83 #if defined(__i386__) || defined(__x86_64__) 84 # include <x86intrin.h> 88 # define NLIB_VIS_HIDDEN __attribute__((visibility("hidden"))) 89 # define NLIB_VIS_PUBLIC __attribute__((visibility("default"))) 90 # define NLIB_WEAKSYMBOL __attribute__((weak)) 92 # define NLIB_VIS_HIDDEN 93 # define NLIB_VIS_PUBLIC 94 # define NLIB_WEAKSYMBOL 97 #define NLIB_ALWAYS_INLINE inline __attribute__((always_inline)) 98 #define NLIB_NEVER_INLINE __attribute__((__noinline__)) 99 #define NLIB_LIKELY(x) __builtin_expect(!!(x), 1) 100 #define NLIB_UNLIKELY(x) __builtin_expect(!!(x), 0) 101 #define NLIB_EXPECT(var, exp_value) __builtin_expect((var), (exp_value)) 102 #if defined(__cplusplus) && __has_cpp_attribute(nodiscard) 103 #define NLIB_CHECK_RESULT [[nodiscard]] // NOLINT 105 #define NLIB_CHECK_RESULT __attribute__((warn_unused_result)) 107 #if defined(__cplusplus) && __has_cpp_attribute(noreturn) 108 #define NLIB_NORETURN [[noreturn]] // NOLINT 110 #define NLIB_NORETURN __attribute__((noreturn)) 112 #if defined(__cplusplus) && __has_cpp_attribute(fallthrough) 113 #define NLIB_FALLTHROUGH [[fallthrough]] // NOLINT 115 #define NLIB_FALLTHROUGH 117 #define NLIB_NONNULL __attribute__((nonnull)) 118 #define NLIB_NONNULL_1 __attribute__((nonnull (1))) 119 #define NLIB_NONNULL_2 __attribute__((nonnull (2))) 120 #define NLIB_NONNULL_3 __attribute__((nonnull (3))) 121 #define NLIB_NONNULL_4 __attribute__((nonnull (4))) 122 #define NLIB_NONNULL_5 __attribute__((nonnull (5))) 123 #define NLIB_NONNULL_ENABLED 124 #define NLIB_ATTRIBUTE_MALLOC __attribute__((malloc)) 125 #define NLIB_ATTRIBUTE_PURE __attribute__((pure)) 126 #define NLIB_ATTRIBUTE_CONST __attribute__((const)) 129 # if __has_attribute(alloc_size) 130 # define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) __attribute__((alloc_size(n))) 131 # define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) __attribute__((alloc_size(n0, n1))) 133 # define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) 134 # define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) 136 # if __has_attribute(alloc_align) 137 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) __attribute__((alloc_align(algn))) 139 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) 141 # if __has_attribute(assume_aligned) 142 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) __attribute__((assume_aligned(n))) 144 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) 147 # define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) __attribute__((alloc_size(n))) 148 # define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) __attribute__((alloc_size(n0, n1))) 149 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) 150 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) __attribute__((alloc_align(algn))) 151 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) __attribute__((assume_aligned(n))) 153 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) 154 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) 158 #ifndef NLIB_DEPRECATED 159 #if defined(__cplusplus) && __has_cpp_attribute(deprecated) 160 #define NLIB_DEPRECATED [[deprecated]] // NOLINT 162 #define NLIB_DEPRECATED __attribute__((deprecated)) 165 #ifndef NLIB_DEPRECATED_MSG 166 #if defined(__cplusplus) && __has_cpp_attribute(deprecated) 167 #define NLIB_DEPRECATED_MSG(msg) [[deprecated(msg)]] // NOLINT 169 #define NLIB_DEPRECATED_MSG(msg) __attribute__((deprecated)) 173 #if defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) 174 # define NLIB_LITTLE_ENDIAN 175 #elif defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) 176 # undef NLIB_LITTLE_ENDIAN 178 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 179 # define NLIB_LITTLE_ENDIAN 181 # undef NLIB_LITTLE_ENDIAN 184 #if defined(__x86_64__) || defined(__aarch64__) 188 #define NLIB_MEMORY_ORDER_RELEASE __atomic_thread_fence(__ATOMIC_RELEASE) 189 #define NLIB_MEMORY_ORDER_ACQUIRE __atomic_thread_fence(__ATOMIC_ACQUIRE) 190 #define NLIB_MEMORY_ORDER_ACQ_REL __atomic_thread_fence(__ATOMIC_ACQ_REL) 191 #define NLIB_MEMORY_ORDER_SEQ_CST __atomic_thread_fence(__ATOMIC_SEQ_CST) 194 #define NLIB_PTHREAD_nlib_tls_alloc 195 #define NLIB_PTHREAD_nlib_tls_free 196 #define NLIB_PTHREAD_nlib_tls_setvalue 197 #define NLIB_PTHREAD_nlib_tls_getvalue 199 #ifndef _LIBCPP_VERSION 200 NLIB_CAPABILITY(
"mutex")
204 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 208 # define NLIB_MUTEX_INITIALIZER (__builtin_constant_p(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) ? \ 209 PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP : \ 210 PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) 212 # define NLIB_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 215 # define NLIB_PTHREAD_nlib_mutex_init 216 # define NLIB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 220 #define NLIB_PTHREAD_nlib_mutex_lock 221 #define NLIB_PTHREAD_nlib_mutex_unlock 222 #define NLIB_PTHREAD_nlib_mutex_trylock 223 #define NLIB_PTHREAD_nlib_mutex_destroy 226 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 227 # define NLIB_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 228 # define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 229 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 230 # define NLIB_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER 231 # define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER 232 #elif defined(__FreeBSD__) 235 # define NLIB_RECURSIVE_MUTEX_INITIALIZER (__builtin_constant_p((pthread_mutex_t)255) ? \ 236 (pthread_mutex_t)255 : (pthread_mutex_t)255) 237 # define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER (__builtin_constant_p((pthread_mutex_t)255) ? \ 238 (pthread_mutex_t)255 : (pthread_mutex_t)255) 239 #elif defined(NLIB_ALPINE) 241 #define NLIB_RECURSIVE_MUTEX_INITIALIZER {{{1}}} 242 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER {{{1}}} 247 #if defined(__APPLE__) 254 #define NLIB_COND_INITIALIZER PTHREAD_COND_INITIALIZER 256 #define NLIB_PTHREAD_nlib_cond_init 257 #define NLIB_PTHREAD_nlib_cond_signal 258 #define NLIB_PTHREAD_nlib_cond_broadcast 259 #define NLIB_PTHREAD_nlib_cond_wait 260 #define NLIB_PTHREAD_nlib_cond_destroy 264 #define NLIB_PTHREAD_nlib_thread_join 265 #define NLIB_PTHREAD_nlib_thread_detach 266 #define NLIB_PTHREAD_nlib_thread_equal 267 #define NLIB_PTHREAD_nlib_thread_self 269 #if defined(__APPLE__) 270 #define NLIB_SPINLOCK_HAS_NATIVE 271 #if __has_include( <os/lock.h> ) 273 #define NLIB_SPINLOCK_INITIALIZER OS_UNFAIR_LOCK_INIT 275 *lock = OS_UNFAIR_LOCK_INIT;
278 os_unfair_lock_lock(lock);
281 return os_unfair_lock_trylock(lock) ? 0 : EBUSY;
284 os_unfair_lock_unlock(lock);
288 #define NLIB_SPINLOCK_INITIALIZER (0) 293 OSSpinLockLock(lock);
296 return OSSpinLockTry(lock) ? 0 : EBUSY;
299 OSSpinLockUnlock(lock);
308 #if defined(__clang__) 309 # if __has_feature(cxx_unicode_literals) 310 # define NLIB_CXX11_NEW_CHARACTER_TYPES 312 # if __has_feature(cxx_exceptions) 313 # if __has_feature(cxx_noexcept) 314 # define NLIB_CXX11_NOEXCEPT 317 # define NLIB_NOEXCEPT 321 # define NLIB_CXX11_NEW_CHARACTER_TYPES 322 # ifndef __cpp_unicode_characters 323 # define __cpp_unicode_characters 200704L // N2249 325 # define NLIB_CXX11_NOEXCEPT 331 #define NLIB_ONCE_HAS_NATIVE 332 #define NLIB_TIMESPEC_HAS_NATIVE 333 #define NLIB_IOVEC_HAS_NATIVE 335 #ifdef PTHREAD_RWLOCK_INITIALIZER 336 # define NLIB_RWLOCK_HAS_NATIVE 338 #ifdef NLIB_RWLOCK_HAS_NATIVE 339 #ifndef _LIBCPP_VERSION 340 NLIB_CAPABILITY(
"mutex")
343 #define NLIB_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER 345 #define NLIB_PTHREAD_nlib_rwlock_init 346 #define NLIB_PTHREAD_nlib_rwlock_destroy 347 #define NLIB_PTHREAD_nlib_rwlock_tryrdlock 348 #define NLIB_PTHREAD_nlib_rwlock_trywrlock 349 #define NLIB_PTHREAD_nlib_rwlock_rdlock 350 #define NLIB_PTHREAD_nlib_rwlock_rdunlock 351 #define NLIB_PTHREAD_nlib_rwlock_wrlock 352 #define NLIB_PTHREAD_nlib_rwlock_wrunlock 355 #ifdef PTHREAD_BARRIER_SERIAL_THREAD 356 # define NLIB_BARRIER_HAS_NATIVE 358 #ifdef NLIB_BARRIER_HAS_NATIVE 360 #define NLIB_PTHREAD_nlib_barrier_init 361 #define NLIB_PTHREAD_nlib_barrier_destroy 364 #define NLIB_THREAD_ATTR_HAS_NATIVE 366 #ifndef pthread_cleanup_push 367 # error pthread_cleanup_push must be a macro 370 #ifndef pthread_cleanup_pop 371 # error pthread_cleanup_pop must be a macro 382 #define NLIB_LIBC_nlib_memcmp 383 #define NLIB_LIBC_nlib_strlen 384 #define NLIB_LIBC_nlib_strnlen 385 #if defined(__STDC_LIB_EXT1__) 386 # define NLIB_LIBC_nlib_wcslen 387 # define NLIB_LIBC_nlib_wcsnlen 388 # define NLIB_LIBC_nlib_strncpy 389 # define NLIB_LIBC_nlib_strcpy 390 # define NLIB_LIBC_nlib_wcsncpy 391 # define NLIB_LIBC_nlib_wcscpy 393 #define NLIB_LIBC_nlib_strchr 394 #define NLIB_LIBC_nlib_strrchr 400 #if (defined(__clang__) && defined(NLIB_64BIT)) || \ 401 (defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) 403 #define NLIB_ATOMIC_RELAXED __ATOMIC_RELAXED 404 #define NLIB_ATOMIC_ACQUIRE __ATOMIC_ACQUIRE 405 #define NLIB_ATOMIC_RELEASE __ATOMIC_RELEASE 406 #define NLIB_ATOMIC_ACQ_REL __ATOMIC_ACQ_REL 407 #define NLIB_ATOMIC_SEQ_CST __ATOMIC_SEQ_CST 409 #if defined(NLIB_DOXYGEN) 414 int32_t desired,
int weak,
415 int success_memorder,
int failure_memorder);
431 int64_t desired,
int weak,
432 int success_memorder,
int failure_memorder);
448 void* desired,
int weak,
449 int success_memorder,
int failure_memorder);
454 #if defined(__has_feature) && __has_feature(thread_sanitizer) 455 #define NLIB_TSAN_LOCK pthread_mutex_lock(&nlib_tsan_lock); 456 #define NLIB_TSAN_UNLOCK pthread_mutex_unlock(&nlib_tsan_lock); 458 #define NLIB_TSAN_LOCK 459 #define NLIB_TSAN_UNLOCK 465 rval = __atomic_load_n(ptr, memorder);
472 __atomic_store_n(ptr, val, memorder);
480 rval = __atomic_exchange_n(ptr, val, memorder);
486 int32_t desired,
int weak,
487 int success_memorder,
int failure_memorder) {
490 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak,
491 success_memorder, failure_memorder);
500 rval = __atomic_add_fetch(ptr, val, memorder);
509 rval = __atomic_sub_fetch(ptr, val, memorder);
518 rval = __atomic_and_fetch(ptr, val, memorder);
527 rval = __atomic_xor_fetch(ptr, val, memorder);
536 rval = __atomic_or_fetch(ptr, val, memorder);
545 rval = __atomic_fetch_add(ptr, val, memorder);
554 rval = __atomic_fetch_sub(ptr, val, memorder);
563 rval = __atomic_fetch_and(ptr, val, memorder);
572 rval = __atomic_fetch_xor(ptr, val, memorder);
581 rval = __atomic_fetch_or(ptr, val, memorder);
589 rval = __atomic_load_n(ptr, memorder);
596 __atomic_store_n(ptr, val, memorder);
604 rval = __atomic_exchange_n(ptr, val, memorder);
612 rval = __atomic_exchange_n(ptr, val, memorder);
618 int64_t desired,
int weak,
619 int success_memorder,
int failure_memorder) {
622 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak,
623 success_memorder, failure_memorder);
632 rval = __atomic_add_fetch(ptr, val, memorder);
641 rval = __atomic_sub_fetch(ptr, val, memorder);
650 rval = __atomic_and_fetch(ptr, val, memorder);
659 rval = __atomic_xor_fetch(ptr, val, memorder);
668 rval = __atomic_or_fetch(ptr, val, memorder);
677 rval = __atomic_fetch_add(ptr, val, memorder);
686 rval = __atomic_fetch_sub(ptr, val, memorder);
695 rval = __atomic_fetch_and(ptr, val, memorder);
704 rval = __atomic_fetch_xor(ptr, val, memorder);
713 rval = __atomic_fetch_or(ptr, val, memorder);
721 rval = __atomic_load_n(ptr, memorder);
728 __atomic_store_n(ptr, val, memorder);
733 void* desired,
int weak,
734 int success_memorder,
int failure_memorder) {
737 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak,
738 success_memorder, failure_memorder);
744 __atomic_thread_fence(memorder);
748 #define NLIB_ATOMIC_RELAXED 0 749 #define NLIB_ATOMIC_ACQUIRE 1 750 #define NLIB_ATOMIC_RELEASE 2 751 #define NLIB_ATOMIC_ACQ_REL 3 752 #define NLIB_ATOMIC_SEQ_CST 7 755 int32_t rval = *(
volatile int32_t*)ptr;
757 #if !defined(__i386__) && !defined(__x86_64__) 767 __sync_synchronize();
770 __sync_lock_test_and_set(ptr, val);
776 __sync_synchronize();
779 return __sync_lock_test_and_set(ptr, val);
783 int32_t desired,
int weak,
784 int success_memorder,
int failure_memorder) {
785 int32_t old = __sync_val_compare_and_swap(ptr, *expected, desired);
786 if (old == *expected)
return 1;
790 (void)success_memorder;
791 (void)failure_memorder;
798 return __sync_add_and_fetch(ptr, val);
804 return __sync_sub_and_fetch(ptr, val);
810 return __sync_and_and_fetch(ptr, val);
816 return __sync_xor_and_fetch(ptr, val);
822 return __sync_or_and_fetch(ptr, val);
828 return __sync_fetch_and_add(ptr, val);
834 return __sync_fetch_and_sub(ptr, val);
840 return __sync_fetch_and_and(ptr, val);
846 return __sync_fetch_and_xor(ptr, val);
852 return __sync_fetch_and_or(ptr, val);
856 int64_t rval = *(
volatile int64_t*)ptr;
858 #if !defined(__i386__) && !defined(__x86_64__) 868 __sync_synchronize();
871 __sync_lock_test_and_set(ptr, val);
877 __sync_synchronize();
880 return __sync_lock_test_and_set(ptr, val);
885 __sync_synchronize();
888 return __sync_lock_test_and_set(ptr, val);
892 int64_t desired,
int weak,
893 int success_memorder,
int failure_memorder) {
894 int64_t old = __sync_val_compare_and_swap(ptr, *expected, desired);
895 if (old == *expected)
return 1;
899 (void)success_memorder;
900 (void)failure_memorder;
907 return __sync_add_and_fetch(ptr, val);
913 return __sync_sub_and_fetch(ptr, val);
919 return __sync_and_and_fetch(ptr, val);
925 return __sync_xor_and_fetch(ptr, val);
931 return __sync_or_and_fetch(ptr, val);
937 return __sync_fetch_and_add(ptr, val);
943 return __sync_fetch_and_sub(ptr, val);
949 return __sync_fetch_and_and(ptr, val);
955 return __sync_fetch_and_xor(ptr, val);
961 return __sync_fetch_and_or(ptr, val);
965 void* rval = *(
void*
volatile *)ptr;
967 #if !defined(__i386__) && !defined(__x86_64__) 976 __sync_synchronize();
979 void* tmp = __sync_lock_test_and_set(ptr, val);
984 void* desired,
int weak,
985 int success_memorder,
int failure_memorder) {
986 void* old = __sync_val_compare_and_swap(ptr, *expected, desired);
987 if (old == *expected)
return 1;
991 (void)success_memorder;
992 (void)failure_memorder;
1022 #endif // INCLUDE_NN_NLIB_PLATFORM_UNIX_H_