xref: /freebsd/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_atomic.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- sanitizer_atomic.h --------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef SANITIZER_ATOMIC_H
140b57cec5SDimitry Andric #define SANITIZER_ATOMIC_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "sanitizer_internal_defs.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric namespace __sanitizer {
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric enum memory_order {
21*0fca6ea1SDimitry Andric // If the __atomic atomic builtins are supported (Clang/GCC), use the
22*0fca6ea1SDimitry Andric // compiler provided macro values so that we can map the atomic operations
23*0fca6ea1SDimitry Andric // to __atomic_* directly.
24*0fca6ea1SDimitry Andric #ifdef __ATOMIC_SEQ_CST
25*0fca6ea1SDimitry Andric   memory_order_relaxed = __ATOMIC_RELAXED,
26*0fca6ea1SDimitry Andric   memory_order_consume = __ATOMIC_CONSUME,
27*0fca6ea1SDimitry Andric   memory_order_acquire = __ATOMIC_ACQUIRE,
28*0fca6ea1SDimitry Andric   memory_order_release = __ATOMIC_RELEASE,
29*0fca6ea1SDimitry Andric   memory_order_acq_rel = __ATOMIC_ACQ_REL,
30*0fca6ea1SDimitry Andric   memory_order_seq_cst = __ATOMIC_SEQ_CST
31*0fca6ea1SDimitry Andric #else
320b57cec5SDimitry Andric   memory_order_relaxed = 1 << 0,
330b57cec5SDimitry Andric   memory_order_consume = 1 << 1,
340b57cec5SDimitry Andric   memory_order_acquire = 1 << 2,
350b57cec5SDimitry Andric   memory_order_release = 1 << 3,
360b57cec5SDimitry Andric   memory_order_acq_rel = 1 << 4,
370b57cec5SDimitry Andric   memory_order_seq_cst = 1 << 5
38*0fca6ea1SDimitry Andric #endif
390b57cec5SDimitry Andric };
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric struct atomic_uint8_t {
420b57cec5SDimitry Andric   typedef u8 Type;
430b57cec5SDimitry Andric   volatile Type val_dont_use;
440b57cec5SDimitry Andric };
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric struct atomic_uint16_t {
470b57cec5SDimitry Andric   typedef u16 Type;
480b57cec5SDimitry Andric   volatile Type val_dont_use;
490b57cec5SDimitry Andric };
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric struct atomic_sint32_t {
520b57cec5SDimitry Andric   typedef s32 Type;
530b57cec5SDimitry Andric   volatile Type val_dont_use;
540b57cec5SDimitry Andric };
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric struct atomic_uint32_t {
570b57cec5SDimitry Andric   typedef u32 Type;
580b57cec5SDimitry Andric   volatile Type val_dont_use;
590b57cec5SDimitry Andric };
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric struct atomic_uint64_t {
620b57cec5SDimitry Andric   typedef u64 Type;
630b57cec5SDimitry Andric   // On 32-bit platforms u64 is not necessary aligned on 8 bytes.
64*0fca6ea1SDimitry Andric   alignas(8) volatile Type val_dont_use;
650b57cec5SDimitry Andric };
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric struct atomic_uintptr_t {
680b57cec5SDimitry Andric   typedef uptr Type;
690b57cec5SDimitry Andric   volatile Type val_dont_use;
700b57cec5SDimitry Andric };
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric }  // namespace __sanitizer
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric #if defined(__clang__) || defined(__GNUC__)
750b57cec5SDimitry Andric # include "sanitizer_atomic_clang.h"
760b57cec5SDimitry Andric #elif defined(_MSC_VER)
770b57cec5SDimitry Andric # include "sanitizer_atomic_msvc.h"
780b57cec5SDimitry Andric #else
790b57cec5SDimitry Andric # error "Unsupported compiler"
800b57cec5SDimitry Andric #endif
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric namespace __sanitizer {
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric // Clutter-reducing helpers.
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric template<typename T>
atomic_load_relaxed(const volatile T * a)87e8d8bef9SDimitry Andric inline typename T::Type atomic_load_relaxed(const volatile T *a) {
880b57cec5SDimitry Andric   return atomic_load(a, memory_order_relaxed);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric template<typename T>
atomic_store_relaxed(volatile T * a,typename T::Type v)92e8d8bef9SDimitry Andric inline void atomic_store_relaxed(volatile T *a, typename T::Type v) {
930b57cec5SDimitry Andric   atomic_store(a, v, memory_order_relaxed);
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric }  // namespace __sanitizer
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric #endif  // SANITIZER_ATOMIC_H
99