| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Copyright 2014 Google Inc. All rights reserved. |
| 2 // Copyright 2012 Google Inc. All rights reserved. | 2 // https://developers.google.com/protocol-buffers/ |
| 3 // http://code.google.com/p/protobuf/ | |
| 4 // | 3 // |
| 5 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 7 // met: | 6 // met: |
| 8 // | 7 // |
| 9 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 11 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| 12 // copyright notice, this list of conditions and the following disclaimer | 11 // copyright notice, this list of conditions and the following disclaimer |
| 13 // in the documentation and/or other materials provided with the | 12 // in the documentation and/or other materials provided with the |
| 14 // distribution. | 13 // distribution. |
| 15 // * Neither the name of Google Inc. nor the names of its | 14 // * Neither the name of Google Inc. nor the names of its |
| 16 // contributors may be used to endorse or promote products derived from | 15 // contributors may be used to endorse or promote products derived from |
| 17 // this software without specific prior written permission. | 16 // this software without specific prior written permission. |
| 18 // | 17 // |
| 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 29 |
| 31 // This file is an internal atomic implementation, use atomicops.h instead. | 30 // This file is an internal atomic implementation, use atomicops.h instead. |
| 32 | 31 |
| 33 #ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ | 32 #ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ |
| 34 #define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ | 33 #define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ |
| 35 | 34 |
| 36 #include <libkern/OSAtomic.h> | 35 #include <atomic.h> |
| 37 | 36 |
| 38 namespace google { | 37 namespace google { |
| 39 namespace protobuf { | 38 namespace protobuf { |
| 40 namespace internal { | 39 namespace internal { |
| 41 | 40 |
| 42 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | 41 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, |
| 43 Atomic32 old_value, | 42 Atomic32 old_value, |
| 44 Atomic32 new_value) { | 43 Atomic32 new_value) { |
| 45 Atomic32 prev_value; | 44 return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (
uint32_t)new_value); |
| 46 do { | |
| 47 if (OSAtomicCompareAndSwap32(old_value, new_value, | |
| 48 const_cast<Atomic32*>(ptr))) { | |
| 49 return old_value; | |
| 50 } | |
| 51 prev_value = *ptr; | |
| 52 } while (prev_value == old_value); | |
| 53 return prev_value; | |
| 54 } | 45 } |
| 55 | 46 |
| 56 inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, | 47 inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, |
| 57 Atomic32 new_value) { | 48 Atomic32 new_value) { |
| 58 Atomic32 old_value; | 49 return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value); |
| 59 do { | |
| 60 old_value = *ptr; | |
| 61 } while (!OSAtomicCompareAndSwap32(old_value, new_value, | |
| 62 const_cast<Atomic32*>(ptr))); | |
| 63 return old_value; | |
| 64 } | 50 } |
| 65 | 51 |
| 66 inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, | 52 inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, |
| 67 Atomic32 increment) { | 53 Atomic32 increment) { |
| 68 return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr)); | 54 return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment
); |
| 55 } |
| 56 |
| 57 inline void MemoryBarrier(void) { |
| 58 » membar_producer(); |
| 59 » membar_consumer(); |
| 69 } | 60 } |
| 70 | 61 |
| 71 inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | 62 inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, |
| 72 Atomic32 increment) { | 63 Atomic32 increment) { |
| 73 return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr)); | 64 MemoryBarrier(); |
| 74 } | 65 Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment); |
| 66 MemoryBarrier(); |
| 75 | 67 |
| 76 inline void MemoryBarrier() { | 68 return ret; |
| 77 OSMemoryBarrier(); | |
| 78 } | 69 } |
| 79 | 70 |
| 80 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | 71 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, |
| 81 Atomic32 old_value, | 72 Atomic32 old_value, |
| 82 Atomic32 new_value) { | 73 Atomic32 new_value) { |
| 83 Atomic32 prev_value; | 74 Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value); |
| 84 do { | 75 MemoryBarrier(); |
| 85 if (OSAtomicCompareAndSwap32Barrier(old_value, new_value, | 76 |
| 86 const_cast<Atomic32*>(ptr))) { | 77 return ret; |
| 87 return old_value; | |
| 88 } | |
| 89 prev_value = *ptr; | |
| 90 } while (prev_value == old_value); | |
| 91 return prev_value; | |
| 92 } | 78 } |
| 93 | 79 |
| 94 inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | 80 inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, |
| 95 Atomic32 old_value, | 81 Atomic32 old_value, |
| 96 Atomic32 new_value) { | 82 Atomic32 new_value) { |
| 97 return Acquire_CompareAndSwap(ptr, old_value, new_value); | 83 MemoryBarrier(); |
| 84 return NoBarrier_CompareAndSwap(ptr, old_value, new_value); |
| 98 } | 85 } |
| 99 | 86 |
| 100 inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | 87 inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { |
| 101 *ptr = value; | 88 *ptr = value; |
| 102 } | 89 } |
| 103 | 90 |
| 104 inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | 91 inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { |
| 105 *ptr = value; | 92 *ptr = value; |
| 106 MemoryBarrier(); | 93 membar_producer(); |
| 107 } | 94 } |
| 108 | 95 |
| 109 inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { | 96 inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { |
| 110 MemoryBarrier(); | 97 membar_consumer(); |
| 111 *ptr = value; | 98 *ptr = value; |
| 112 } | 99 } |
| 113 | 100 |
| 114 inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | 101 inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { |
| 115 return *ptr; | 102 return *ptr; |
| 116 } | 103 } |
| 117 | 104 |
| 118 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { | 105 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { |
| 119 Atomic32 value = *ptr; | 106 Atomic32 val = *ptr; |
| 120 MemoryBarrier(); | 107 membar_consumer(); |
| 121 return value; | 108 return val; |
| 122 } | 109 } |
| 123 | 110 |
| 124 inline Atomic32 Release_Load(volatile const Atomic32* ptr) { | 111 inline Atomic32 Release_Load(volatile const Atomic32* ptr) { |
| 125 MemoryBarrier(); | 112 membar_producer(); |
| 126 return *ptr; | 113 return *ptr; |
| 127 } | 114 } |
| 128 | 115 |
| 129 #ifdef __LP64__ | 116 #ifdef GOOGLE_PROTOBUF_ARCH_64_BIT |
| 130 | |
| 131 // 64-bit implementation on 64-bit platform | |
| 132 | |
| 133 inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | 117 inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, |
| 134 Atomic64 old_value, | 118 Atomic64 old_value, |
| 135 Atomic64 new_value) { | 119 Atomic64 new_value) { |
| 136 Atomic64 prev_value; | 120 return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)n
ew_value); |
| 137 do { | |
| 138 if (OSAtomicCompareAndSwap64(old_value, new_value, | |
| 139 reinterpret_cast<volatile int64_t*>(ptr))) { | |
| 140 return old_value; | |
| 141 } | |
| 142 prev_value = *ptr; | |
| 143 } while (prev_value == old_value); | |
| 144 return prev_value; | |
| 145 } | 121 } |
| 146 | 122 |
| 147 inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, | 123 inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_va
lue) { |
| 148 Atomic64 new_value) { | 124 return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value); |
| 149 Atomic64 old_value; | |
| 150 do { | |
| 151 old_value = *ptr; | |
| 152 } while (!OSAtomicCompareAndSwap64(old_value, new_value, | |
| 153 reinterpret_cast<volatile int64_t*>(ptr))); | |
| 154 return old_value; | |
| 155 } | 125 } |
| 156 | 126 |
| 157 inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, | 127 inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 incre
ment) { |
| 158 Atomic64 increment) { | 128 return atomic_add_64_nv((volatile uint64_t*)ptr, increment); |
| 159 return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr)); | |
| 160 } | 129 } |
| 161 | 130 |
| 162 inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, | 131 inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increme
nt) { |
| 163 Atomic64 increment) { | 132 MemoryBarrier(); |
| 164 return OSAtomicAdd64Barrier(increment, | 133 Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment); |
| 165 reinterpret_cast<volatile int64_t*>(ptr)); | 134 MemoryBarrier(); |
| 135 return ret; |
| 166 } | 136 } |
| 167 | 137 |
| 168 inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | 138 inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, |
| 169 Atomic64 old_value, | 139 Atomic64 old_value, |
| 170 Atomic64 new_value) { | 140 Atomic64 new_value) { |
| 171 Atomic64 prev_value; | 141 Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value); |
| 172 do { | 142 MemoryBarrier(); |
| 173 if (OSAtomicCompareAndSwap64Barrier( | 143 return ret; |
| 174 old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) { | |
| 175 return old_value; | |
| 176 } | |
| 177 prev_value = *ptr; | |
| 178 } while (prev_value == old_value); | |
| 179 return prev_value; | |
| 180 } | 144 } |
| 181 | 145 |
| 182 inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | 146 inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, |
| 183 Atomic64 old_value, | 147 Atomic64 old_value, |
| 184 Atomic64 new_value) { | 148 Atomic64 new_value) { |
| 185 // The lib kern interface does not distinguish between | 149 MemoryBarrier(); |
| 186 // Acquire and Release memory barriers; they are equivalent. | 150 return NoBarrier_CompareAndSwap(ptr, old_value, new_value); |
| 187 return Acquire_CompareAndSwap(ptr, old_value, new_value); | |
| 188 } | 151 } |
| 189 | 152 |
| 190 inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { | 153 inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { |
| 191 *ptr = value; | 154 *ptr = value; |
| 192 } | 155 } |
| 193 | 156 |
| 194 inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { | 157 inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { |
| 195 *ptr = value; | 158 *ptr = value; |
| 196 MemoryBarrier(); | 159 membar_producer(); |
| 197 } | 160 } |
| 198 | 161 |
| 199 inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { | 162 inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { |
| 200 MemoryBarrier(); | 163 membar_consumer(); |
| 201 *ptr = value; | 164 *ptr = value; |
| 202 } | 165 } |
| 203 | 166 |
| 204 inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { | 167 inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { |
| 205 return *ptr; | 168 return *ptr; |
| 206 } | 169 } |
| 207 | 170 |
| 208 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { | 171 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { |
| 209 Atomic64 value = *ptr; | 172 Atomic64 ret = *ptr; |
| 210 MemoryBarrier(); | 173 membar_consumer(); |
| 211 return value; | 174 return ret; |
| 212 } | 175 } |
| 213 | 176 |
| 214 inline Atomic64 Release_Load(volatile const Atomic64* ptr) { | 177 inline Atomic64 Release_Load(volatile const Atomic64* ptr) { |
| 215 MemoryBarrier(); | 178 membar_producer(); |
| 216 return *ptr; | 179 return *ptr; |
| 217 } | 180 } |
| 218 | 181 #endif |
| 219 #endif // defined(__LP64__) | |
| 220 | 182 |
| 221 } // namespace internal | 183 } // namespace internal |
| 222 } // namespace protobuf | 184 } // namespace protobuf |
| 223 } // namespace google | 185 } // namespace google |
| 224 | 186 |
| 225 #endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ | 187 #endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ |
| 188 |
| OLD | NEW |