3 #ifndef INCLUDE_NN_NLIB_PLATFORM_UNIX_H_ 4 #define INCLUDE_NN_NLIB_PLATFORM_UNIX_H_ 5 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_ 6 # error do not include directly 9 #if defined(__linux__) || \ 10 defined(__FreeBSD__) || \ 11 defined(__CYGWIN__) || \ 12 (defined(__APPLE__) && defined(__MACH__)) 14 #if defined(__APPLE__) && defined(__MACH__) 15 #define _DARWIN_UNLIMITED_SELECT 16 #include <libkern/OSAtomic.h> 18 #if __has_include( <os/lock.h> ) 32 #if !defined(__GNUC__) && !defined(__clang__) 36 #define NLIB_HAS_STDHEADER_STDINT 37 #define NLIB_HAS_STDHEADER_INTTYPES 39 #if !defined(__FreeBSD__) && !defined(__APPLE__) 45 #include <sys/types.h> 48 #include <sys/socket.h> 50 #include <netinet/in.h> 51 #include <arpa/inet.h> 55 #if defined(__i386__) || defined(__x86_64__) 56 # include <x86intrin.h> 60 # define NLIB_VIS_HIDDEN __attribute__((visibility("hidden"))) 61 # define NLIB_VIS_PUBLIC __attribute__((visibility("default"))) 62 # define NLIB_WEAKSYMBOL __attribute__((weak)) 64 # define NLIB_VIS_HIDDEN 65 # define NLIB_VIS_PUBLIC 66 # define NLIB_WEAKSYMBOL 69 #define NLIB_ALWAYS_INLINE inline __attribute__((always_inline)) 70 #define NLIB_NEVER_INLINE __attribute__((__noinline__)) 71 #define NLIB_LIKELY(x) __builtin_expect(!!(x), 1) 72 #define NLIB_UNLIKELY(x) __builtin_expect(!!(x), 0) 73 #define NLIB_EXPECT(var, exp_value) __builtin_expect((var), (exp_value)) 74 #define NLIB_CHECK_RESULT __attribute__((warn_unused_result)) 75 #define NLIB_NORETURN __attribute__((noreturn)) 76 #define NLIB_NONNULL __attribute__((nonnull)) 77 #define NLIB_NONNULL_1 __attribute__((nonnull (1))) 78 #define NLIB_NONNULL_2 __attribute__((nonnull (2))) 79 #define NLIB_NONNULL_3 __attribute__((nonnull (3))) 80 #define NLIB_NONNULL_4 __attribute__((nonnull (4))) 81 #define NLIB_NONNULL_5 __attribute__((nonnull (5))) 82 #define NLIB_NONNULL_ENABLED 83 #define NLIB_ATTRIBUTE_MALLOC __attribute__((malloc)) 84 #define NLIB_ATTRIBUTE_PURE __attribute__((pure)) 85 #define NLIB_ATTRIBUTE_CONST __attribute__((const)) 88 # if __has_attribute(alloc_size) 89 # define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) __attribute__((alloc_size(n))) 90 # define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) __attribute__((alloc_size(n0, n1))) 92 # define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) 93 # define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) 95 # if __has_attribute(alloc_align) 96 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) __attribute__((alloc_align(algn))) 98 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) 100 # if __has_attribute(assume_aligned) 101 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) __attribute__((assume_aligned(n))) 103 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) 106 # define NLIB_ATTRIBUTE_ALLOC_SIZE1(n) __attribute__((alloc_size(n))) 107 # define NLIB_ATTRIBUTE_ALLOC_SIZE2(n0, n1) __attribute__((alloc_size(n0, n1))) 108 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) 109 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) __attribute__((alloc_align(algn))) 110 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) __attribute__((assume_aligned(n))) 112 # define NLIB_ATTRIBUTE_ALLOC_ALIGN(algn) 113 # define NLIB_ATTRIBUTE_ASSUME_ALIGNED(n) 117 #ifndef NLIB_DEPRECATED 118 #define NLIB_DEPRECATED __attribute__((deprecated)) 120 #ifndef NLIB_DEPRECATED_MSG 121 #define NLIB_DEPRECATED_MSG(msg) __attribute__((deprecated)) 124 #if defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) 125 # define NLIB_LITTLE_ENDIAN 126 #elif defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) 127 # undef NLIB_LITTLE_ENDIAN 129 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 130 # define NLIB_LITTLE_ENDIAN 132 # undef NLIB_LITTLE_ENDIAN 135 #if defined(__x86_64__) || defined(__aarch64__) 139 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 140 # if !defined(__i386__) && !defined(__x86_64__) 143 #define NLIB_MEMORY_ORDER_RELEASE __asm__ __volatile__("sfence": : :"memory") 144 #define NLIB_MEMORY_ORDER_ACQUIRE __asm__ __volatile__("lfence": : :"memory") 145 #define NLIB_MEMORY_ORDER_ACQ_REL __asm__ __volatile__("mfence": : :"memory") 146 #define NLIB_MEMORY_ORDER_SEQ_CST __sync_synchronize() 148 #define NLIB_MEMORY_ORDER_RELEASE __atomic_thread_fence(__ATOMIC_RELEASE) 149 #define NLIB_MEMORY_ORDER_ACQUIRE __atomic_thread_fence(__ATOMIC_ACQUIRE) 150 #define NLIB_MEMORY_ORDER_ACQ_REL __atomic_thread_fence(__ATOMIC_ACQ_REL) 151 #define NLIB_MEMORY_ORDER_SEQ_CST __atomic_thread_fence(__ATOMIC_SEQ_CST) 155 #define NLIB_PTHREAD_nlib_tls_alloc 156 #define NLIB_PTHREAD_nlib_tls_free 157 #define NLIB_PTHREAD_nlib_tls_setvalue 158 #define NLIB_PTHREAD_nlib_tls_getvalue 160 #ifndef _LIBCPP_VERSION 161 NLIB_CAPABILITY(
"mutex")
165 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 169 # define NLIB_MUTEX_INITIALIZER (__builtin_constant_p(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) ? \ 170 PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP : \ 171 PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) 173 # define NLIB_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 176 # define NLIB_PTHREAD_nlib_mutex_init 177 # define NLIB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 181 #define NLIB_PTHREAD_nlib_mutex_lock 182 #define NLIB_PTHREAD_nlib_mutex_unlock 183 #define NLIB_PTHREAD_nlib_mutex_trylock 184 #define NLIB_PTHREAD_nlib_mutex_destroy 187 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 188 # define NLIB_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 189 # define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 190 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 191 # define NLIB_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER 192 # define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER 193 #elif defined(__FreeBSD__) 196 # define NLIB_RECURSIVE_MUTEX_INITIALIZER (__builtin_constant_p((pthread_mutex_t)255) ? \ 197 (pthread_mutex_t)255 : (pthread_mutex_t)255) 198 # define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER (__builtin_constant_p((pthread_mutex_t)255) ? \ 199 (pthread_mutex_t)255 : (pthread_mutex_t)255) 200 #elif defined(NLIB_ALPINE) 202 #define NLIB_RECURSIVE_MUTEX_INITIALIZER {{{1}}} 203 #define NLIB_RECURSIVE_TIMED_MUTEX_INITIALIZER {{{1}}} 208 #if defined(__APPLE__) 215 #define NLIB_COND_INITIALIZER PTHREAD_COND_INITIALIZER 217 #define NLIB_PTHREAD_nlib_cond_init 218 #define NLIB_PTHREAD_nlib_cond_signal 219 #define NLIB_PTHREAD_nlib_cond_broadcast 220 #define NLIB_PTHREAD_nlib_cond_wait 221 #define NLIB_PTHREAD_nlib_cond_destroy 225 #define NLIB_PTHREAD_nlib_thread_join 226 #define NLIB_PTHREAD_nlib_thread_detach 227 #define NLIB_PTHREAD_nlib_thread_equal 228 #define NLIB_PTHREAD_nlib_thread_self 230 #if defined(__APPLE__) 231 #define NLIB_SPINLOCK_HAS_NATIVE 232 #if 0 && __has_include( <os/lock.h> ) && (MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) 234 #define NLIB_SPINLOCK_INITIALIZER OS_UNFAIR_LOCK_INIT 236 *lock = OS_UNFAIR_LOCK_INIT;
239 os_unfair_lock_lock(*lock);
242 return os_unfair_lock_trylock(*lock) ? 0 : EBUSY;
245 os_unfair_lock_unlock(*lock);
249 #define NLIB_SPINLOCK_INITIALIZER (0) 254 OSSpinLockLock(lock);
257 return OSSpinLockTry(lock) ? 0 : EBUSY;
260 OSSpinLockUnlock(lock);
269 #if defined(__clang__) 270 # if __has_feature(cxx_unicode_literals) 271 # define NLIB_CXX11_NEW_CHARACTER_TYPES 273 # if __has_feature(cxx_exceptions) 274 # if __has_feature(cxx_noexcept) 275 # define NLIB_CXX11_NOEXCEPT 278 # define NLIB_NOEXCEPT 282 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) 283 # define NLIB_CXX11_NEW_CHARACTER_TYPES 285 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 286 # define NLIB_CXX11_NOEXCEPT 293 #define NLIB_TIMESPEC_HAS_NATIVE 294 #define NLIB_IOVEC_HAS_NATIVE 296 #ifdef PTHREAD_RWLOCK_INITIALIZER 297 # define NLIB_RWLOCK_HAS_NATIVE 299 #ifdef NLIB_RWLOCK_HAS_NATIVE 300 #ifndef _LIBCPP_VERSION 301 NLIB_CAPABILITY(
"mutex")
304 #define NLIB_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER 306 #define NLIB_PTHREAD_nlib_rwlock_init 307 #define NLIB_PTHREAD_nlib_rwlock_destroy 308 #define NLIB_PTHREAD_nlib_rwlock_tryrdlock 309 #define NLIB_PTHREAD_nlib_rwlock_trywrlock 310 #define NLIB_PTHREAD_nlib_rwlock_rdlock 311 #define NLIB_PTHREAD_nlib_rwlock_rdunlock 312 #define NLIB_PTHREAD_nlib_rwlock_wrlock 313 #define NLIB_PTHREAD_nlib_rwlock_wrunlock 316 #ifdef PTHREAD_BARRIER_SERIAL_THREAD 317 # define NLIB_BARRIER_HAS_NATIVE 319 #ifdef NLIB_BARRIER_HAS_NATIVE 321 #define NLIB_PTHREAD_nlib_barrier_init 322 #define NLIB_PTHREAD_nlib_barrier_destroy 325 #define NLIB_THREAD_ATTR_HAS_NATIVE 327 #ifndef pthread_cleanup_push 328 # error pthread_cleanup_push must be a macro 331 #ifndef pthread_cleanup_pop 332 # error pthread_cleanup_pop must be a macro 335 #define NLIB_LIBC_nlib_memcmp 336 #define NLIB_LIBC_nlib_strlen 337 #define NLIB_LIBC_nlib_strnlen 338 #if defined(__STDC_LIB_EXT1__) 339 # define NLIB_LIBC_nlib_wcslen 340 # define NLIB_LIBC_nlib_wcsnlen 341 # define NLIB_LIBC_nlib_strncpy 342 # define NLIB_LIBC_nlib_strcpy 343 # define NLIB_LIBC_nlib_wcsncpy 344 # define NLIB_LIBC_nlib_wcscpy 346 #define NLIB_LIBC_nlib_strchr 347 #define NLIB_LIBC_nlib_strrchr 353 #if (defined(__clang__) && defined(NLIB_64BIT)) || \ 354 (defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) 356 #define NLIB_ATOMIC_RELAXED __ATOMIC_RELAXED 357 #define NLIB_ATOMIC_ACQUIRE __ATOMIC_ACQUIRE 358 #define NLIB_ATOMIC_RELEASE __ATOMIC_RELEASE 359 #define NLIB_ATOMIC_ACQ_REL __ATOMIC_ACQ_REL 360 #define NLIB_ATOMIC_SEQ_CST __ATOMIC_SEQ_CST 362 #if defined(NLIB_DOXYGEN) 367 int32_t desired,
int weak,
368 int success_memorder,
int failure_memorder);
384 int64_t desired,
int weak,
385 int success_memorder,
int failure_memorder);
400 void* desired,
int weak,
401 int success_memorder,
int failure_memorder);
406 #if defined(__has_feature) && __has_feature(thread_sanitizer) 407 #define NLIB_TSAN_LOCK pthread_mutex_lock(&nlib_tsan_lock); 408 #define NLIB_TSAN_UNLOCK pthread_mutex_unlock(&nlib_tsan_lock); 410 #define NLIB_TSAN_LOCK 411 #define NLIB_TSAN_UNLOCK 417 rval = __atomic_load_n(ptr, memorder);
424 __atomic_store_n(ptr, val, memorder);
432 rval = __atomic_exchange_n(ptr, val, memorder);
438 int32_t desired,
int weak,
439 int success_memorder,
int failure_memorder) {
442 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak,
443 success_memorder, failure_memorder);
452 rval = __atomic_add_fetch(ptr, val, memorder);
461 rval = __atomic_sub_fetch(ptr, val, memorder);
470 rval = __atomic_and_fetch(ptr, val, memorder);
479 rval = __atomic_xor_fetch(ptr, val, memorder);
488 rval = __atomic_or_fetch(ptr, val, memorder);
497 rval = __atomic_fetch_add(ptr, val, memorder);
506 rval = __atomic_fetch_sub(ptr, val, memorder);
515 rval = __atomic_fetch_and(ptr, val, memorder);
524 rval = __atomic_fetch_xor(ptr, val, memorder);
533 rval = __atomic_fetch_or(ptr, val, memorder);
541 rval = __atomic_load_n(ptr, memorder);
548 __atomic_store_n(ptr, val, memorder);
556 rval = __atomic_exchange_n(ptr, val, memorder);
562 int64_t desired,
int weak,
563 int success_memorder,
int failure_memorder) {
566 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak,
567 success_memorder, failure_memorder);
576 rval = __atomic_add_fetch(ptr, val, memorder);
585 rval = __atomic_sub_fetch(ptr, val, memorder);
594 rval = __atomic_and_fetch(ptr, val, memorder);
603 rval = __atomic_xor_fetch(ptr, val, memorder);
612 rval = __atomic_or_fetch(ptr, val, memorder);
621 rval = __atomic_fetch_add(ptr, val, memorder);
630 rval = __atomic_fetch_sub(ptr, val, memorder);
639 rval = __atomic_fetch_and(ptr, val, memorder);
648 rval = __atomic_fetch_xor(ptr, val, memorder);
657 rval = __atomic_fetch_or(ptr, val, memorder);
665 rval = __atomic_load_n(ptr, memorder);
672 __atomic_store_n(ptr, val, memorder);
677 void* desired,
int weak,
678 int success_memorder,
int failure_memorder) {
681 rval = __atomic_compare_exchange_n(ptr, expected, desired, weak,
682 success_memorder, failure_memorder);
688 __atomic_thread_fence(memorder);
692 #define NLIB_ATOMIC_RELAXED 0 693 #define NLIB_ATOMIC_ACQUIRE 1 694 #define NLIB_ATOMIC_RELEASE 2 695 #define NLIB_ATOMIC_ACQ_REL 3 696 #define NLIB_ATOMIC_SEQ_CST 7 699 int32_t rval = *(
volatile int32_t*)ptr;
701 #if !defined(__i386__) && !defined(__x86_64__) 711 __sync_synchronize();
714 __sync_lock_test_and_set(ptr, val);
720 __sync_synchronize();
723 return __sync_lock_test_and_set(ptr, val);
727 int32_t desired,
int weak,
728 int success_memorder,
int failure_memorder) {
729 int32_t old = __sync_val_compare_and_swap(ptr, *expected, desired);
730 if (old == *expected)
return 1;
734 (void)success_memorder;
735 (void)failure_memorder;
742 return __sync_add_and_fetch(ptr, val);
748 return __sync_sub_and_fetch(ptr, val);
754 return __sync_and_and_fetch(ptr, val);
760 return __sync_xor_and_fetch(ptr, val);
766 return __sync_or_and_fetch(ptr, val);
772 return __sync_fetch_and_add(ptr, val);
778 return __sync_fetch_and_sub(ptr, val);
784 return __sync_fetch_and_and(ptr, val);
790 return __sync_fetch_and_xor(ptr, val);
796 return __sync_fetch_and_or(ptr, val);
800 int64_t rval = *(
volatile int64_t*)ptr;
802 #if !defined(__i386__) && !defined(__x86_64__) 812 __sync_synchronize();
815 __sync_lock_test_and_set(ptr, val);
821 __sync_synchronize();
824 return __sync_lock_test_and_set(ptr, val);
828 int64_t desired,
int weak,
829 int success_memorder,
int failure_memorder) {
830 int64_t old = __sync_val_compare_and_swap(ptr, *expected, desired);
831 if (old == *expected)
return 1;
835 (void)success_memorder;
836 (void)failure_memorder;
843 return __sync_add_and_fetch(ptr, val);
849 return __sync_sub_and_fetch(ptr, val);
855 return __sync_and_and_fetch(ptr, val);
861 return __sync_xor_and_fetch(ptr, val);
867 return __sync_or_and_fetch(ptr, val);
873 return __sync_fetch_and_add(ptr, val);
879 return __sync_fetch_and_sub(ptr, val);
885 return __sync_fetch_and_and(ptr, val);
891 return __sync_fetch_and_xor(ptr, val);
897 return __sync_fetch_and_or(ptr, val);
901 void* rval = *(
void*
volatile *)ptr;
903 #if !defined(__i386__) && !defined(__x86_64__) 912 __sync_synchronize();
915 void* tmp = __sync_lock_test_and_set(ptr, val);
920 void* desired,
int weak,
921 int success_memorder,
int failure_memorder) {
922 void* old = __sync_val_compare_and_swap(ptr, *expected, desired);
923 if (old == *expected)
return 1;
927 (void)success_memorder;
928 (void)failure_memorder;
958 #endif // INCLUDE_NN_NLIB_PLATFORM_UNIX_H_