atomic_freestanding.c (1211B)
1 //===-- atomic_freestanding.c - lock fallbacks via C11 atomic spinlock ---===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 // Atomic fallback shim using a pointer-sized C11 atomic spinlock as the 8 // lock primitive. Has no OS or libc dependency. 9 //===----------------------------------------------------------------------===// 10 11 #include <stdbool.h> 12 #include <stddef.h> 13 #include <stdint.h> 14 15 enum { SPINLOCK_COUNT = 1 << 10 }; 16 static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1; 17 18 // HAS_INT128 is defined by the build system: -DHAS_INT128=1 on 64-bit targets, 19 // -DHAS_INT128=0 on 32-bit. atomic_common.inc keys 16-byte cases off it. 20 21 typedef _Atomic(uintptr_t) Lock; 22 23 #pragma clang diagnostic push 24 #pragma clang diagnostic ignored "-Watomic-alignment" 25 static inline void unlock(Lock* l) { 26 __atomic_store_n((uintptr_t*)l, 0, __ATOMIC_RELEASE); 27 } 28 29 static inline void lock(Lock* l) { 30 while (__atomic_exchange_n((uintptr_t*)l, 1, __ATOMIC_ACQUIRE)); 31 } 32 #pragma clang diagnostic pop 33 34 static Lock locks[SPINLOCK_COUNT]; 35 36 #include "atomic_common.inc"