Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 // Atomic system independant 32-bit signed integer.
     12 // Linux implementation.
     13 // Note: Requires gcc 4.1.2 or later.
     14 #ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_
     15 #define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_
     16 
     17 #include <inttypes.h>
     18 #include <malloc.h>
     19 
     20 #include "common_types.h"
     21 
     22 namespace webrtc {
     23 class Atomic32Impl
     24 {
     25 public:
     26     inline Atomic32Impl(WebRtc_Word32 initialValue);
     27     inline ~Atomic32Impl();
     28 
     29     inline WebRtc_Word32 operator++();
     30     inline WebRtc_Word32 operator--();
     31 
     32     inline Atomic32Impl& operator=(const Atomic32Impl& rhs);
     33     inline Atomic32Impl& operator=(WebRtc_Word32 rhs);
     34     inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs);
     35     inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs);
     36 
     37     inline bool CompareExchange(WebRtc_Word32 newValue,
     38                                 WebRtc_Word32 compareValue);
     39 
     40     inline WebRtc_Word32 Value() const;
     41 private:
     42     void*        _ptrMemory;
     43     // Volatile ensures full memory barriers.
     44     volatile WebRtc_Word32* _value;
     45 };
     46 
     47 // TODO (hellner) use aligned_malloc instead of doing it manually.
     48 inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue)
     49     : _ptrMemory(NULL),
     50       _value(NULL)
     51 {   // Align the memory associated with _value on a 32-bit boundary. This is a
     52     // requirement for the used Linux APIs to be atomic.
     53     // Keep _ptrMemory to be able to reclaim memory.
     54     _ptrMemory = malloc(sizeof(WebRtc_Word32)*2);
     55     _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3));
     56     *_value = initialValue;
     57 }
     58 
     59 inline Atomic32Impl::~Atomic32Impl()
     60 {
     61     if(_ptrMemory != NULL)
     62     {
     63         free(_ptrMemory);
     64     }
     65 }
     66 
     67 inline WebRtc_Word32 Atomic32Impl::operator++()
     68 {
     69     WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,1);
     70     returnValue++;
     71     return returnValue;
     72 }
     73 
     74 inline WebRtc_Word32 Atomic32Impl::operator--()
     75 {
     76     WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,1);
     77     returnValue--;
     78     return returnValue;
     79 }
     80 
     81 inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs)
     82 {
     83     *_value = *rhs._value;
     84     return *this;
     85 }
     86 
     87 inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs)
     88 {
     89     *_value = rhs;
     90     return *this;
     91 }
     92 
     93 inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs)
     94 {
     95     WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,rhs);
     96     returnValue += rhs;
     97     return returnValue;
     98 }
     99 
    100 inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs)
    101 {
    102     WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,rhs);
    103     returnValue -= rhs;
    104     return returnValue;
    105 }
    106 
    107 inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue,
    108                                           WebRtc_Word32 compareValue)
    109 {
    110     return __sync_bool_compare_and_swap(_value,compareValue,newValue);
    111 }
    112 
    113 inline WebRtc_Word32 Atomic32Impl::Value() const
    114 {
    115     return *_value;
    116 }
    117 } // namespace webrtc
    118 
    119 #endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_
    120