19cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
29cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// Use of this source code is governed by a BSD-style license that can be
39cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// found in the LICENSE file. See the AUTHORS file for names of contributors.
49cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
59cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// AtomicPointer provides storage for a lock-free pointer.
69cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// Platform-dependent implementation of AtomicPointer:
7e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com// - If the platform provides a cheap barrier, we use it with raw pointers
89cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// - If cstdatomic is present (on newer versions of gcc, it is), we use
9e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   a cstdatomic-based AtomicPointer.  However we prefer the memory
10e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   barrier based version, because at least on a gcc 4.4 32-bit build
11e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   on linux, we have encountered a buggy <cstdatomic>
12e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   implementation.  Also, some <cstdatomic> implementations are much
13e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   slower than a memory-barrier based implementation (~16ns for
14e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   <cstdatomic> based acquire-load vs. ~1ns for a barrier based
15e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com//   acquire-load).
169cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// This code is based on atomicops-internals-* in Google's perftools:
179cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase
189cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
199cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#ifndef PORT_ATOMIC_POINTER_H_
209cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#define PORT_ATOMIC_POINTER_H_
219cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
22e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#include <stdint.h>
239cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#ifdef LEVELDB_CSTDATOMIC_PRESENT
249cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#include <cstdatomic>
25e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#endif
26e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#ifdef OS_WIN
27e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#include <windows.h>
28e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#endif
29e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#ifdef OS_MACOSX
30e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#include <libkern/OSAtomic.h>
31e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#endif
329cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
339cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#if defined(_M_X64) || defined(__x86_64__)
349cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#define ARCH_CPU_X86_FAMILY 1
359cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
369cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#define ARCH_CPU_X86_FAMILY 1
379cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#elif defined(__ARMEL__)
389cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#define ARCH_CPU_ARM_FAMILY 1
3929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
4029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#define ARCH_CPU_PPC_FAMILY 1
419cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#endif
429cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
439cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.comnamespace leveldb {
449cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.comnamespace port {
459cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
46e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com// Define MemoryBarrier() if available
479cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// Windows on x86
489cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY)
49e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com// windows.h already provides a MemoryBarrier(void) macro
509cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com// http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx
51e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#define LEVELDB_HAVE_MEMORY_BARRIER
529cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
534935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org// Mac OS
544935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org#elif defined(OS_MACOSX)
554935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.orginline void MemoryBarrier() {
564935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org  OSMemoryBarrier();
574935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org}
584935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org#define LEVELDB_HAVE_MEMORY_BARRIER
594935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org
60f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// Gcc on x86
61f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com#elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__)
629cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.cominline void MemoryBarrier() {
639cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on
649cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.
659cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  __asm__ __volatile__("" : : : "memory");
669cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com}
67e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#define LEVELDB_HAVE_MEMORY_BARRIER
689cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
69f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com// Sun Studio
70f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com#elif defined(ARCH_CPU_X86_FAMILY) && defined(__SUNPRO_CC)
71f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.cominline void MemoryBarrier() {
72f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com  // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on
73f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com  // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering.
74f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com  asm volatile("" : : : "memory");
75f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com}
76f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com#define LEVELDB_HAVE_MEMORY_BARRIER
77f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com
78158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// ARM Linux
79158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com#elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__)
809cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.comtypedef void (*LinuxKernelMemoryBarrierFunc)(void);
81158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// The Linux ARM kernel provides a highly optimized device-specific memory
82158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// barrier function at a fixed memory address that is mapped in every
83158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// user-level process.
84158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com//
85158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// This beats using CPU-specific instructions which are, on single-core
86158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// devices, un-necessary and very costly (e.g. ARMv7-A "dmb" takes more
87158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// than 180ns on a Cortex-A8 like the one on a Nexus One). Benchmarking
88158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// shows that the extra function call cost is completely negligible on
89158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// multi-core devices.
90158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com//
919cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.cominline void MemoryBarrier() {
92158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  (*(LinuxKernelMemoryBarrierFunc)0xffff0fa0)();
939cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com}
94e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#define LEVELDB_HAVE_MEMORY_BARRIER
959cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
9629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org// PPC
9729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__)
9829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.orginline void MemoryBarrier() {
9929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  // TODO for some powerpc expert: is there a cheaper suitable variant?
10029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  // Perhaps by having separate barriers for acquire and release ops.
10129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  asm volatile("sync" : : : "memory");
10229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org}
10329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#define LEVELDB_HAVE_MEMORY_BARRIER
10429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org
1059cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#endif
1069cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
107e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com// AtomicPointer built using platform-specific MemoryBarrier()
108e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#if defined(LEVELDB_HAVE_MEMORY_BARRIER)
109e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.comclass AtomicPointer {
110e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com private:
111e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  void* rep_;
112e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com public:
113e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  AtomicPointer() { }
114e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  explicit AtomicPointer(void* p) : rep_(p) {}
115e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  inline void* NoBarrier_Load() const { return rep_; }
116e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  inline void NoBarrier_Store(void* v) { rep_ = v; }
117e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  inline void* Acquire_Load() const {
118e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    void* result = rep_;
119e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    MemoryBarrier();
120e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    return result;
121e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  }
122e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  inline void Release_Store(void* v) {
123e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    MemoryBarrier();
124e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    rep_ = v;
125e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  }
126e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com};
1279cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
128e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com// AtomicPointer based on <cstdatomic>
129e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#elif defined(LEVELDB_CSTDATOMIC_PRESENT)
1309cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.comclass AtomicPointer {
1319cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com private:
132e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  std::atomic<void*> rep_;
1339cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com public:
1349cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  AtomicPointer() { }
135e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com  explicit AtomicPointer(void* v) : rep_(v) { }
1369cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  inline void* Acquire_Load() const {
137e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    return rep_.load(std::memory_order_acquire);
1389cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  }
1399cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  inline void Release_Store(void* v) {
140e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    rep_.store(v, std::memory_order_release);
1419cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  }
1429cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  inline void* NoBarrier_Load() const {
143e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    return rep_.load(std::memory_order_relaxed);
1449cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  }
1459cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  inline void NoBarrier_Store(void* v) {
146e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com    rep_.store(v, std::memory_order_relaxed);
1479cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com  }
1489cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com};
1499cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
15029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org// Atomic pointer based on sparc memory barriers
15129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#elif defined(__sparcv9) && defined(__GNUC__)
15229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.orgclass AtomicPointer {
15329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org private:
15429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  void* rep_;
15529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org public:
15629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  AtomicPointer() { }
15729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  explicit AtomicPointer(void* v) : rep_(v) { }
15829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void* Acquire_Load() const {
15929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    void* val;
16029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    __asm__ __volatile__ (
16129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        "ldx [%[rep_]], %[val] \n\t"
16229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org         "membar #LoadLoad|#LoadStore \n\t"
16329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : [val] "=r" (val)
16429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : [rep_] "r" (&rep_)
16529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : "memory");
16629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    return val;
16729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  }
16829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void Release_Store(void* v) {
16929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    __asm__ __volatile__ (
17029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        "membar #LoadStore|#StoreStore \n\t"
17129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        "stx %[v], [%[rep_]] \n\t"
17229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        :
17329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : [rep_] "r" (&rep_), [v] "r" (v)
17429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : "memory");
17529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  }
17629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void* NoBarrier_Load() const { return rep_; }
17729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void NoBarrier_Store(void* v) { rep_ = v; }
17829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org};
17929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org
18029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org// Atomic pointer based on ia64 acq/rel
18129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#elif defined(__ia64) && defined(__GNUC__)
18229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.orgclass AtomicPointer {
18329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org private:
18429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  void* rep_;
18529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org public:
18629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  AtomicPointer() { }
18729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  explicit AtomicPointer(void* v) : rep_(v) { }
18829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void* Acquire_Load() const {
18929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    void* val    ;
19029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    __asm__ __volatile__ (
19129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        "ld8.acq %[val] = [%[rep_]] \n\t"
19229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : [val] "=r" (val)
19329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : [rep_] "r" (&rep_)
19429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : "memory"
19529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        );
19629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    return val;
19729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  }
19829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void Release_Store(void* v) {
19929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org    __asm__ __volatile__ (
20029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        "st8.rel [%[rep_]] = %[v]  \n\t"
20129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        :
20229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : [rep_] "r" (&rep_), [v] "r" (v)
20329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        : "memory"
20429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org        );
20529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  }
20629c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void* NoBarrier_Load() const { return rep_; }
20729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org  inline void NoBarrier_Store(void* v) { rep_ = v; }
20829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org};
20929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org
210e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com// We have neither MemoryBarrier(), nor <cstdatomic>
211e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#else
212e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#error Please implement AtomicPointer for this platform.
213e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com
214e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#endif
215e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com
216e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#undef LEVELDB_HAVE_MEMORY_BARRIER
217e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#undef ARCH_CPU_X86_FAMILY
218e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com#undef ARCH_CPU_ARM_FAMILY
21929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org#undef ARCH_CPU_PPC_FAMILY
220e67cd63d8a779971247078b2715b6ae7b37dbc2egabor@google.com
22145b9940be332834440bd5299419f396e38085ebehans@chromium.org}  // namespace port
22245b9940be332834440bd5299419f396e38085ebehans@chromium.org}  // namespace leveldb
2239cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com
2249cb7b73e2668626608a4a8706d69d3e7000cebfcgabor@google.com#endif  // PORT_ATOMIC_POINTER_H_
225