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 + -
显示快捷键?