x
Yes
No
Do you want to visit DriveHQ English website?
首页
产品服务
价格
免费试用
下载客户端
关于我们
云文件服务
|
云备份服务
|
FTP服务
|
企业邮箱服务
|
网站托管
|
客户端软件
云文件服务
云备份服务
FTP服务
企业级邮箱服务
网站托管
客户端软件
atomic.hpp - Hosted on DriveHQ Cloud IT Platform
返回上层目录
上传
下载
共享
发布
新建文件夹
新建文件
复制
剪切
删除
粘贴
评论
升级服务
路径: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\boost_1_35_0\boost\interprocess\detail\atomic.hpp
旋转
特效
属性
历史版本
////////////////////////////////////////////////////////////////////////////// // // (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
#include
#include
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 mem inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem); //! Atomically read an boost::uint32_t from memory inline 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 assume inline 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 *mem inline 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
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 mem inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) { return winapi::interlocked_decrement((volatile long*)mem) + 1; } //! Atomically increment an apr_uint32_t by 1 //! "mem": pointer to the object //! Returns the old value pointed to by mem inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) { return winapi::interlocked_increment((volatile long*)mem)-1; } //! Atomically read an boost::uint32_t from memory inline 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 assume inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) { winapi::interlocked_exchange((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 *mem inline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) { return winapi::interlocked_compare_exchange((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 *mem inline 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 mem inline 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 mem inline 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 mem inline 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 memory inline 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 assume inline 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 mem inline 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 *mem inline 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 : "memory", "cc"); // clobbered return prev; } //! Atomically increment an apr_uint32_t by 1 //! "mem": pointer to the object //! Returns the old value pointed to by mem inline 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 mem inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) { return atomic_add32(mem, boost::uint32_t(-1u)); } //! Atomically read an boost::uint32_t from memory inline 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 assume inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) { *mem = val; } } //namespace detail{ } //namespace interprocess{ } //namespace boost{ #elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) 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 mem inline boost::uint32_t atomic_add32 (volatile boost::uint32_t *mem, boost::uint32_t val) { return __sync_fetch_and_add(const_cast
(mem), val); } //! Atomically increment an apr_uint32_t by 1 //! "mem": pointer to the object //! Returns the old value pointed to by mem inline 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 mem inline 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 memory inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) { return *mem; } //! 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 *mem inline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) { return __sync_val_compare_and_swap(const_cast
(mem), with, cmp); } //! Atomically set an boost::uint32_t in memory //! "mem": pointer to the object //! "param": val value that the object will assume inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) { *mem = val; } } //namespace detail{ } //namespace interprocess{ } //namespace boost{ #elif (defined(sun) || defined(__sun)) #include
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 mem inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val) { return atomic_add_32_nv(reinterpret_cast
(mem), (int32_t)val) - 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 *mem inline boost::uint32_t atomic_cas32 (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) { return atomic_cas_32(reinterpret_cast
(mem), cmp, with); } //! Atomically increment an apr_uint32_t by 1 //! "mem": pointer to the object //! Returns the old value pointed to by mem inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) { return atomic_add_32_nv(reinterpret_cast
(mem), 1) - 1; } //! Atomically decrement an boost::uint32_t by 1 //! "mem": pointer to the atomic value //! Returns the old value pointed to by mem inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) { return atomic_add_32_nv(reinterpret_cast
(mem), (boost::uint32_t)-1) + 1; } //! Atomically read an boost::uint32_t from memory inline 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 assume inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) { *mem = val; } } //namespace detail{ } //namespace interprocess{ } //namespace boost{ #elif defined(__osf__) && defined(__DECCXX) #include
#include
namespace boost{ namespace interprocess{ namespace detail{ //! Atomically decrement a uint32_t by 1 //! "mem": pointer to the atomic value //! Returns the old value pointed to by mem //! Acquire, memory barrier after decrement. inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) { boost::uint32_t old_val = __ATOMIC_DECREMENT_LONG(mem); __MB(); return old_val; } //! Atomically increment a uint32_t by 1 //! "mem": pointer to the object //! Returns the old value pointed to by mem //! Release, memory barrier before increment. inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) { __MB(); return __ATOMIC_INCREMENT_LONG(mem); } // Rational for the implementation of the atomic read and write functions. // // 1. The Alpha Architecture Handbook requires that access to a byte, // an aligned word, an aligned longword, or an aligned quadword is // atomic. (See 'Alpha Architecture Handbook', version 4, chapter 5.2.2.) // // 2. The CXX User's Guide states that volatile quantities are accessed // with single assembler instructions, and that a compilation error // occurs when declaring a quantity as volatile which is not properly // aligned. //! Atomically read an boost::uint32_t from memory //! Acquire, memory barrier after load. inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) { boost::uint32_t old_val = *mem; __MB(); return old_val; } //! Atomically set an boost::uint32_t in memory //! "mem": pointer to the object //! "param": val value that the object will assume //! Release, memory barrier before store. inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) { __MB(); *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 *mem //! Memory barrier between load and store. inline boost::uint32_t atomic_cas32( volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) { // Note: // // Branch prediction prefers backward branches, and the Alpha Architecture // Handbook explicitely states that the loop should not be implemented like // it is below. (See chapter 4.2.5.) Therefore the code should probably look // like this: // // return asm( // "10: ldl_l %v0,(%a0) ;" // " cmpeq %v0,%a2,%t0 ;" // " beq %t0,20f ;" // " mb ;" // " mov %a1,%t0 ;" // " stl_c %t0,(%a0) ;" // " beq %t0,30f ;" // "20: ret ;" // "30: br 10b;", // mem, with, cmp); // // But as the compiler always transforms this into the form where a backward // branch is taken on failure, we can as well implement it in the straight // forward form, as this is what it will end up in anyway. return asm( "10: ldl_l %v0,(%a0) ;" // load prev value from mem and lock mem " cmpeq %v0,%a2,%t0 ;" // compare with given value " beq %t0,20f ;" // if not equal, we're done " mb ;" // memory barrier " mov %a1,%t0 ;" // load new value into scratch register " stl_c %t0,(%a0) ;" // store new value to locked mem (overwriting scratch) " beq %t0,10b ;" // store failed because lock has been stolen, retry "20: ", mem, with, cmp); } } //namespace detail{ } //namespace interprocess{ } //namespace boost{ #else #error No atomic operations implemented for this platform, sorry! #endif #include
#endif //BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP
atomic.hpp
网页地址
文件地址
上一页
2/29
下一页
下载
( 16 KB )
Comments
Total ratings:
0
Average rating:
无评论
of 10
Would you like to comment?
Join now
, or
Logon
if you are already a member.