Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:18

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 Google LLC.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 #ifndef UPB_PORT_ATOMIC_H_
0009 #define UPB_PORT_ATOMIC_H_
0010 
0011 #include "upb/port/def.inc"
0012 
0013 #ifdef UPB_USE_C11_ATOMICS
0014 
0015 // IWYU pragma: begin_exports
0016 #include <stdatomic.h>
0017 #include <stdbool.h>
0018 // IWYU pragma: end_exports
0019 
0020 #define upb_Atomic_Init(addr, val) atomic_init(addr, val)
0021 #define upb_Atomic_Load(addr, order) atomic_load_explicit(addr, order)
0022 #define upb_Atomic_Store(addr, val, order) \
0023   atomic_store_explicit(addr, val, order)
0024 #define upb_Atomic_Add(addr, val, order) \
0025   atomic_fetch_add_explicit(addr, val, order)
0026 #define upb_Atomic_Sub(addr, val, order) \
0027   atomic_fetch_sub_explicit(addr, val, order)
0028 #define upb_Atomic_Exchange(addr, val, order) \
0029   atomic_exchange_explicit(addr, val, order)
0030 #define upb_Atomic_CompareExchangeStrong(addr, expected, desired,      \
0031                                          success_order, failure_order) \
0032   atomic_compare_exchange_strong_explicit(addr, expected, desired,     \
0033                                           success_order, failure_order)
0034 #define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \
0035                                        failure_order)                          \
0036   atomic_compare_exchange_weak_explicit(addr, expected, desired,               \
0037                                         success_order, failure_order)
0038 
0039 #else  // !UPB_USE_C11_ATOMICS
0040 
0041 #include <string.h>
0042 
0043 #define upb_Atomic_Init(addr, val) (*addr = val)
0044 #define upb_Atomic_Load(addr, order) (*addr)
0045 #define upb_Atomic_Store(addr, val, order) (*(addr) = val)
0046 #define upb_Atomic_Add(addr, val, order) (*(addr) += val)
0047 #define upb_Atomic_Sub(addr, val, order) (*(addr) -= val)
0048 
0049 UPB_INLINE void* _upb_NonAtomic_Exchange(void* addr, void* value) {
0050   void* old;
0051   memcpy(&old, addr, sizeof(value));
0052   memcpy(addr, &value, sizeof(value));
0053   return old;
0054 }
0055 
0056 #define upb_Atomic_Exchange(addr, val, order) _upb_NonAtomic_Exchange(addr, val)
0057 
0058 // `addr` and `expected` are logically double pointers.
0059 UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr,
0060                                                       void* expected,
0061                                                       void* desired) {
0062   if (memcmp(addr, expected, sizeof(desired)) == 0) {
0063     memcpy(addr, &desired, sizeof(desired));
0064     return true;
0065   } else {
0066     memcpy(expected, addr, sizeof(desired));
0067     return false;
0068   }
0069 }
0070 
0071 #define upb_Atomic_CompareExchangeStrong(addr, expected, desired,      \
0072                                          success_order, failure_order) \
0073   _upb_NonAtomic_CompareExchangeStrongP((void*)addr, (void*)expected,  \
0074                                         (void*)desired)
0075 #define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \
0076                                        failure_order)                          \
0077   upb_Atomic_CompareExchangeStrong(addr, expected, desired, 0, 0)
0078 
0079 #endif
0080 
0081 #include "upb/port/undef.inc"
0082 
0083 #endif  // UPB_PORT_ATOMIC_H_