From 650208fd530a2299af5e3673362d16db2028a9c6 Mon Sep 17 00:00:00 2001 From: refactor Date: Fri, 19 Jul 2019 22:45:45 +0800 Subject: [PATCH] using , test on ARM64 CPU --- port/atomic_pointer.h | 79 +++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/port/atomic_pointer.h b/port/atomic_pointer.h index 2b485c7f..bb4e183c 100644 --- a/port/atomic_pointer.h +++ b/port/atomic_pointer.h @@ -5,14 +5,13 @@ // AtomicPointer provides storage for a lock-free pointer. // Platform-dependent implementation of AtomicPointer: // - If the platform provides a cheap barrier, we use it with raw pointers -// - If cstdatomic is present (on newer versions of gcc, it is), we use -// a cstdatomic-based AtomicPointer. However we prefer the memory +// - If is present (on newer versions of gcc, it is), we use +// a -based AtomicPointer. However we prefer the memory // barrier based version, because at least on a gcc 4.4 32-bit build -// on linux, we have encountered a buggy -// implementation. Also, some implementations are much -// slower than a memory-barrier based implementation (~16ns for -// based acquire-load vs. ~1ns for a barrier based -// acquire-load). +// on linux, we have encountered a buggy implementation. +// Also, some implementations are much slower than a memory-barrier +// based implementation (~16ns for based acquire-load vs. ~1ns for +// a barrier based acquire-load). // This code is based on atomicops-internals-* in Google's perftools: // http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase @@ -20,15 +19,12 @@ #define PORT_ATOMIC_POINTER_H_ #include -//#ifdef LEVELDB_CSTDATOMIC_PRESENT -//#include ... moved below -//#endif + +#include + #ifdef OS_WIN #include #endif -#ifdef OS_MACOSX -#include -#endif #if defined(_M_X64) || defined(__x86_64__) #define ARCH_CPU_X86_FAMILY 1 @@ -36,6 +32,12 @@ #define ARCH_CPU_X86_FAMILY 1 #elif defined(__ARMEL__) #define ARCH_CPU_ARM_FAMILY 1 +#elif defined(__aarch64__) +#define ARCH_CPU_ARM64_FAMILY 1 +#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) +#define ARCH_CPU_PPC_FAMILY 1 +#elif defined(__mips__) +#define ARCH_CPU_MIPS_FAMILY 1 #endif namespace leveldb { @@ -48,6 +50,13 @@ namespace port { // http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx #define LEVELDB_HAVE_MEMORY_BARRIER +// Mac OS +#elif defined(__APPLE__) +inline void MemoryBarrier() { + std::atomic_thread_fence(std::memory_order_seq_cst); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + // Gcc on x86 #elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__) inline void MemoryBarrier() { @@ -66,13 +75,6 @@ inline void MemoryBarrier() { } #define LEVELDB_HAVE_MEMORY_BARRIER -// Mac OS -#elif defined(OS_MACOSX) -inline void MemoryBarrier() { - OSMemoryBarrier(); -} -#define LEVELDB_HAVE_MEMORY_BARRIER - // ARM Linux #elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__) typedef void (*LinuxKernelMemoryBarrierFunc)(void); @@ -91,9 +93,32 @@ inline void MemoryBarrier() { } #define LEVELDB_HAVE_MEMORY_BARRIER +// ARM64 +#elif defined(ARCH_CPU_ARM64_FAMILY) +inline void MemoryBarrier() { + asm volatile("dmb sy" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// PPC +#elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__) +inline void MemoryBarrier() { + // TODO for some powerpc expert: is there a cheaper suitable variant? + // Perhaps by having separate barriers for acquire and release ops. + asm volatile("sync" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + +// MIPS +#elif defined(ARCH_CPU_MIPS_FAMILY) && defined(__GNUC__) +inline void MemoryBarrier() { + __asm__ __volatile__("sync" : : : "memory"); +} +#define LEVELDB_HAVE_MEMORY_BARRIER + #endif -// AtomicPointer built using platform-specific MemoryBarrier() +// AtomicPointer built using platform-specific MemoryBarrier(). #if defined(LEVELDB_HAVE_MEMORY_BARRIER) class AtomicPointer { private: @@ -114,10 +139,8 @@ class AtomicPointer { } }; -// AtomicPointer based on -#elif defined(LEVELDB_CSTDATOMIC_PRESENT) -#include - +// AtomicPointer based on C++11 . +#else class AtomicPointer { private: std::atomic rep_; @@ -138,15 +161,13 @@ class AtomicPointer { } }; -// We have neither MemoryBarrier(), nor -#else -#error Please implement AtomicPointer for this platform. - #endif #undef LEVELDB_HAVE_MEMORY_BARRIER #undef ARCH_CPU_X86_FAMILY #undef ARCH_CPU_ARM_FAMILY +#undef ARCH_CPU_ARM64_FAMILY +#undef ARCH_CPU_PPC_FAMILY } // namespace port } // namespace leveldb