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 // Mac implementation. 13 #ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_ 14 #define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_ 15 16 #include <stdlib.h> 17 #include <libkern/OSAtomic.h> 18 19 #include "common_types.h" 20 21 namespace webrtc { 22 class Atomic32Impl 23 { 24 public: 25 inline Atomic32Impl(WebRtc_Word32 initialValue); 26 inline ~Atomic32Impl(); 27 28 inline WebRtc_Word32 operator++(); 29 inline WebRtc_Word32 operator--(); 30 31 inline Atomic32Impl& operator=(const Atomic32Impl& rhs); 32 inline Atomic32Impl& operator=(WebRtc_Word32 rhs); 33 inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs); 34 inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs); 35 36 inline bool CompareExchange(WebRtc_Word32 newValue, 37 WebRtc_Word32 compareValue); 38 39 inline WebRtc_Word32 Value() const; 40 private: 41 void* _ptrMemory; 42 // Volatile ensures full memory barriers. 43 volatile WebRtc_Word32* _value; 44 }; 45 46 // TODO (hellner) use aligned_malloc instead of doing it manually. 47 inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue) 48 : 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 Mac 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 return OSAtomicIncrement32Barrier( 70 reinterpret_cast<volatile int32_t*>(_value)); 71 } 72 73 inline WebRtc_Word32 Atomic32Impl::operator--() 74 { 75 return OSAtomicDecrement32Barrier( 76 reinterpret_cast<volatile int32_t*>(_value)); 77 } 78 79 inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs) 80 { 81 *_value = *rhs._value; 82 return *this; 83 } 84 85 inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs) 86 { 87 *_value = rhs; 88 return *this; 89 } 90 91 inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs) 92 { 93 return OSAtomicAdd32Barrier(rhs, 94 reinterpret_cast<volatile int32_t*>(_value)); 95 } 96 97 inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs) 98 { 99 return OSAtomicAdd32Barrier(-rhs, 100 reinterpret_cast<volatile int32_t*>(_value)); 101 } 102 103 inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue, 104 WebRtc_Word32 compareValue) 105 { 106 return OSAtomicCompareAndSwap32Barrier( 107 compareValue, 108 newValue, 109 reinterpret_cast<volatile int32_t*>(_value)); 110 } 111 112 inline WebRtc_Word32 Atomic32Impl::Value() const 113 { 114 return *_value; 115 } 116 } // namespace webrtc 117 #endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_ 118