atomicops.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2012 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The routines exported by this module are subtle.  If you use them, even if
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// you get the code right, it will depend on careful reasoning about atomicity
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and memory ordering; it will be less readable, and harder to maintain.  If
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// you plan to use these routines, you should have a good reason, such as solid
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// evidence that performance would otherwise suffer, or there being no
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// alternative.  You should assume only properties explicitly guaranteed by the
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifications in this file.  You are almost certainly _not_ writing code
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just for the x86; if you assume x86 semantics, x86 hardware bugs and
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementations on other archtectures will cause your code to break.  If you
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do not know what you are doing, avoid these routines, and use a Mutex.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is incorrect to make direct assignments to/from an atomic variable.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You should use one of the Load or Store routines.  The NoBarrier
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// versions are provided when no barriers are needed:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   NoBarrier_Store()
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   NoBarrier_Load()
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Although there are currently no compiler enforcement, you are encouraged
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to use these.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This header and the implementations for each platform (located in
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// atomicops_internals_*) must be kept in sync with the upstream code (V8).
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_ATOMICOPS_H_
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't include this file for people not concerned about thread safety.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_PROTOBUF_NO_THREADSAFETY
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/platform_macros.h>
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int32 Atomic32;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We need to be able to go between Atomic64 and AtomicWord implicitly.  This
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// means Atomic64 and AtomicWord should be the same type on 64-bit.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_PROTOBUF_OS_NACL)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NaCl's intptr_t is not actually 64-bits on 64-bit!
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/nativeclient/issues/detail?id=1162
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int64 Atomic64;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef intptr_t Atomic64;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use AtomicWord for a machine-sized pointer.  It will use the Atomic32 or
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Atomic64 routines below, depending on your architecture.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef intptr_t AtomicWord;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Atomically execute:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      result = *ptr;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      if (*ptr == old_value)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        *ptr = new_value;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      return result;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Always return the old value of "*ptr"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This routine implies no memory barriers.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  Atomic32 old_value,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  Atomic32 new_value);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Atomically store new_value into *ptr, returning the previous value held in
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// *ptr.  This routine implies no memory barriers.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Atomically increment *ptr by "increment".  Returns the new value of
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// *ptr with the increment applied.  This routine implies no memory barriers.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 Atomic32 increment);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These following lower-level operations are typically useful only to people
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementing higher-level synchronization operations like spinlocks,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mutexes, and condition-variables.  They combine CompareAndSwap(), a load, or
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a store with appropriate memory-ordering instructions.  "Acquire" operations
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ensure that no later memory access can be reordered ahead of the operation.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Release" operations ensure that no previous memory access can be reordered
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// after the operation.  "Barrier" operations have both "Acquire" and "Release"
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// access.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic32 old_value,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic32 new_value);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic32 old_value,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic32 new_value);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryBarrier();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Release_Store(volatile Atomic32* ptr, Atomic32 value);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 Acquire_Load(volatile const Atomic32* ptr);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic32 Release_Load(volatile const Atomic32* ptr);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 64-bit atomic operations (only available on 64-bit processors).
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  Atomic64 old_value,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  Atomic64 new_value);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic64 old_value,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic64 new_value);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic64 old_value,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Atomic64 new_value);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Release_Store(volatile Atomic64* ptr, Atomic64 value);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 Acquire_Load(volatile const Atomic64* ptr);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Atomic64 Release_Load(volatile const Atomic64* ptr);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_ARCH_64_BIT
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include our platform specific implementation.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Atomic operations are not supported on your platform"
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GOOGLE_PROTOBUF_ATOMICOPS_ERROR
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Apple.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/atomicops_internals_macosx.h>
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GCC.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__GNUC__)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(GOOGLE_PROTOBUF_ARCH_ARM)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GOOGLE_PROTOBUF_ATOMICOPS_ERROR
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unknown.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GOOGLE_PROTOBUF_ATOMICOPS_ERROR
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On some platforms we need additional declarations to make AtomicWord
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compatible with our other Atomic* types.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_PROTOBUF_OS_APPLE)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/atomicops_internals_atomicword_compat.h>
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_NO_THREADSAFETY
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_ATOMICOPS_H_
203