atomic.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 473 行 · 第 1/2 页
HPP
473 行
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2006-2008// (C) Copyright Markus Schoepflin 2007//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/interprocess for documentation.////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP#define BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP#include <boost/interprocess/detail/config_begin.hpp>#include <boost/interprocess/detail/workaround.hpp>#include <boost/cstdint.hpp>namespace boost{namespace interprocess{namespace detail{//! Atomically increment an apr_uint32_t by 1//! "mem": pointer to the object//! Returns the old value pointed to by meminline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem);//! Atomically read an boost::uint32_t from memoryinline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem);//! Atomically set an boost::uint32_t in memory//! "mem": pointer to the object//! "param": val value that the object will assumeinline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val);//! Compare an boost::uint32_t's value with "cmp".//! If they are the same swap the value with "with"//! "mem": pointer to the value//! "with": what to swap it with//! "cmp": the value to compare it to//! Returns the old value of *meminline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp);} //namespace detail{} //namespace interprocess{} //namespace boost{#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)#include <boost/interprocess/detail/win32_api.hpp>namespace boost{namespace interprocess{namespace detail{//! Atomically decrement an boost::uint32_t by 1//! "mem": pointer to the atomic value//! Returns the old value pointed to by meminline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem){ return winapi::interlocked_decrement(reinterpret_cast<volatile long*>(mem)) + 1; }//! Atomically increment an apr_uint32_t by 1//! "mem": pointer to the object//! Returns the old value pointed to by meminline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem){ return winapi::interlocked_increment(reinterpret_cast<volatile long*>(mem))-1; }//! Atomically read an boost::uint32_t from memoryinline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem){ return *mem; }//! Atomically set an boost::uint32_t in memory//! "mem": pointer to the object//! "param": val value that the object will assumeinline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val){ winapi::interlocked_exchange(reinterpret_cast<volatile long*>(mem), val); }//! Compare an boost::uint32_t's value with "cmp".//! If they are the same swap the value with "with"//! "mem": pointer to the value//! "with": what to swap it with//! "cmp": the value to compare it to//! Returns the old value of *meminline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp){ return winapi::interlocked_compare_exchange(reinterpret_cast<volatile long*>(mem), with, cmp); }} //namespace detail{} //namespace interprocess{} //namespace boost{#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))namespace boost {namespace interprocess {namespace detail{//! Compare an boost::uint32_t's value with "cmp".//! If they are the same swap the value with "with"//! "mem": pointer to the value//! "with" what to swap it with//! "cmp": the value to compare it to//! Returns the old value of *meminline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp){ boost::uint32_t prev = cmp; asm volatile( "lock\n\t" "cmpxchg %3,%1" : "=a" (prev), "=m" (*(mem)) : "0" (prev), "r" (with) : "memory", "cc"); return prev;/* boost::uint32_t prev; asm volatile ("lock; cmpxchgl %1, %2" : "=a" (prev) : "r" (with), "m" (*(mem)), "0"(cmp)); asm volatile("" : : : "memory"); return prev;*/}//! Atomically add 'val' to an boost::uint32_t//! "mem": pointer to the object//! "val": amount to add//! Returns the old value pointed to by meminline boost::uint32_t atomic_add32 (volatile boost::uint32_t *mem, boost::uint32_t val){ // int r = *pw; // *mem += val; // return r; int r; asm volatile ( "lock\n\t" "xadd %1, %0": "+m"( *mem ), "=r"( r ): // outputs (%0, %1) "1"( val ): // inputs (%2 == %1) "memory", "cc" // clobbers ); return r;/* asm volatile( "lock\n\t; xaddl %0,%1" : "=r"(val), "=m"(*mem) : "0"(val), "m"(*mem)); asm volatile("" : : : "memory"); return val;*/}//! Atomically increment an apr_uint32_t by 1//! "mem": pointer to the object//! Returns the old value pointed to by meminline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem){ return atomic_add32(mem, 1); }//! Atomically decrement an boost::uint32_t by 1//! "mem": pointer to the atomic value//! Returns the old value pointed to by meminline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem){ return atomic_add32(mem, (boost::uint32_t)-1); }//! Atomically read an boost::uint32_t from memoryinline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem){ return *mem; }//! Atomically set an boost::uint32_t in memory//! "mem": pointer to the object//! "param": val value that the object will assumeinline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val){ *mem = val; }} //namespace detail{} //namespace interprocess{} //namespace boost{#elif defined(__GNUC__) && (defined(__PPC__) || defined(__ppc__))namespace boost {namespace interprocess {namespace detail{//! Atomically add 'val' to an boost::uint32_t//! "mem": pointer to the object//! "val": amount to add//! Returns the old value pointed to by meminline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val){ boost::uint32_t prev, temp; asm volatile ("0:\n\t" // retry local label "lwarx %0,0,%2\n\t" // load prev and reserve "add %1,%0,%3\n\t" // temp = prev + val "stwcx. %1,0,%2\n\t" // conditionally store "bne- 0b" // start over if we lost // the reservation //XXX find a cleaner way to define the temp //it's not an output : "=&r" (prev), "=&r" (temp) // output, temp : "b" (mem), "r" (val) // inputs : "memory", "cc"); // clobbered return prev;}//! Compare an boost::uint32_t's value with "cmp".//! If they are the same swap the value with "with"//! "mem": pointer to the value//! "with" what to swap it with//! "cmp": the value to compare it to//! Returns the old value of *meminline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp){ boost::uint32_t prev; asm volatile ("0:\n\t" // retry local label "lwarx %0,0,%1\n\t" // load prev and reserve "cmpw %0,%3\n\t" // does it match cmp? "bne- 1f\n\t" // ...no, bail out "stwcx. %2,0,%1\n\t" // ...yes, conditionally // store with "bne- 0b\n\t" // start over if we lost // the reservation "1:" // exit local label : "=&r"(prev) // output : "b" (mem), "r" (with), "r"(cmp) // inputs
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?