Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:10:03

0001 #ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
0002 #define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
0003 
0004 //  interlocked_read_win32.hpp
0005 //
0006 //  (C) Copyright 2005-8 Anthony Williams
0007 //  (C) Copyright 2012 Vicente J. Botet Escriba
0008 //  (C) Copyright 2017 Andrey Semashev
0009 //
0010 //  Distributed under the Boost Software License, Version 1.0. (See
0011 //  accompanying file LICENSE_1_0.txt or copy at
0012 //  http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #include <boost/detail/interlocked.hpp>
0015 #include <boost/thread/detail/config.hpp>
0016 
0017 #include <boost/config/abi_prefix.hpp>
0018 
0019 // Define compiler barriers
0020 #if defined(__INTEL_COMPILER)
0021 #define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __memory_barrier()
0022 #elif defined(__clang__)
0023 #define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __atomic_signal_fence(__ATOMIC_SEQ_CST)
0024 #elif defined(_MSC_VER) && !defined(_WIN32_WCE)
0025 extern "C" void _ReadWriteBarrier(void);
0026 #pragma intrinsic(_ReadWriteBarrier)
0027 #define BOOST_THREAD_DETAIL_COMPILER_BARRIER() _ReadWriteBarrier()
0028 #endif
0029 
0030 #ifndef BOOST_THREAD_DETAIL_COMPILER_BARRIER
0031 #define BOOST_THREAD_DETAIL_COMPILER_BARRIER()
0032 #endif
0033 
0034 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
0035 
0036 // Since VS2005 and until VS2012 volatile reads always acquire and volatile writes are always release.
0037 // But VS2012 adds a compiler switch that can change behavior to the standard. On x86 though
0038 // the compiler generates a single instruction for the load/store, which is enough synchronization
0039 // as far as uarch is concerned. To prevent compiler reordering code around the load/store we add
0040 // compiler barriers.
0041 
0042 namespace boost
0043 {
0044     namespace detail
0045     {
0046         inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
0047         {
0048             long const res=*x;
0049             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0050             return res;
0051         }
0052         inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
0053         {
0054             void* const res=*x;
0055             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0056             return res;
0057         }
0058 
0059         inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
0060         {
0061             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0062             *x=value;
0063         }
0064         inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
0065         {
0066             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0067             *x=value;
0068         }
0069     }
0070 }
0071 
0072 #elif defined(_MSC_VER) && _MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64))
0073 
0074 #include <intrin.h>
0075 
0076 namespace boost
0077 {
0078     namespace detail
0079     {
0080         inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
0081         {
0082             long const res=__iso_volatile_load32((const volatile __int32*)x);
0083             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0084             __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
0085             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0086             return res;
0087         }
0088         inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
0089         {
0090             void* const res=
0091 #if defined(_M_ARM64)
0092                 (void*)__iso_volatile_load64((const volatile __int64*)x);
0093 #else
0094                 (void*)__iso_volatile_load32((const volatile __int32*)x);
0095 #endif
0096             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0097             __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
0098             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0099             return res;
0100         }
0101 
0102         inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
0103         {
0104             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0105             __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
0106             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0107             __iso_volatile_store32((volatile __int32*)x, (__int32)value);
0108         }
0109         inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
0110         {
0111             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0112             __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
0113             BOOST_THREAD_DETAIL_COMPILER_BARRIER();
0114 #if defined(_M_ARM64)
0115             __iso_volatile_store64((volatile __int64*)x, (__int64)value);
0116 #else
0117             __iso_volatile_store32((volatile __int32*)x, (__int32)value);
0118 #endif
0119         }
0120     }
0121 }
0122 
0123 #elif defined(__GNUC__) && (((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) || (defined(__clang__) && (__clang_major__ * 100 + __clang_minor__) >= 302))
0124 
0125 namespace boost
0126 {
0127     namespace detail
0128     {
0129         inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
0130         {
0131             return __atomic_load_n((long*)x, __ATOMIC_ACQUIRE);
0132         }
0133         inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
0134         {
0135             return __atomic_load_n((void**)x, __ATOMIC_ACQUIRE);
0136         }
0137 
0138         inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
0139         {
0140             __atomic_store_n((long*)x, value, __ATOMIC_RELEASE);
0141         }
0142         inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
0143         {
0144             __atomic_store_n((void**)x, value, __ATOMIC_RELEASE);
0145         }
0146     }
0147 }
0148 
0149 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
0150 
0151 namespace boost
0152 {
0153     namespace detail
0154     {
0155         inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
0156         {
0157             long res;
0158             __asm__ __volatile__ ("movl %1, %0" : "=r" (res) : "m" (*x) : "memory");
0159             return res;
0160         }
0161         inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
0162         {
0163             void* res;
0164 #if defined(__x86_64__)
0165             __asm__ __volatile__ ("movq %1, %0" : "=r" (res) : "m" (*x) : "memory");
0166 #else
0167             __asm__ __volatile__ ("movl %1, %0" : "=r" (res) : "m" (*x) : "memory");
0168 #endif
0169             return res;
0170         }
0171 
0172         inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
0173         {
0174             __asm__ __volatile__ ("movl %1, %0" : "=m" (*x) : "r" (value) : "memory");
0175         }
0176         inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
0177         {
0178 #if defined(__x86_64__)
0179             __asm__ __volatile__ ("movq %1, %0" : "=m" (*x) : "r" (value) : "memory");
0180 #else
0181             __asm__ __volatile__ ("movl %1, %0" : "=m" (*x) : "r" (value) : "memory");
0182 #endif
0183         }
0184     }
0185 }
0186 
0187 #else
0188 
0189 namespace boost
0190 {
0191     namespace detail
0192     {
0193         inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
0194         {
0195             return BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)x,0,0);
0196         }
0197         inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
0198         {
0199             return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER((void**)x,0,0);
0200         }
0201         inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
0202         {
0203             BOOST_INTERLOCKED_EXCHANGE((long*)x,value);
0204         }
0205         inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
0206         {
0207             BOOST_INTERLOCKED_EXCHANGE_POINTER((void**)x,value);
0208         }
0209     }
0210 }
0211 
0212 #endif
0213 
0214 #include <boost/config/abi_suffix.hpp>
0215 
0216 #endif