1 // Copyright 2006-2008 The RE2 Authors. All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #ifndef RE2_UTIL_ATOMICOPS_H__ 6 #define RE2_UTIL_ATOMICOPS_H__ 7 8 #if defined(__i386__) 9 10 static inline void WriteMemoryBarrier() { 11 int x; 12 __asm__ __volatile__("xchgl (%0),%0" // The lock prefix is implicit for xchg. 13 :: "r" (&x)); 14 } 15 16 #elif defined(__x86_64__) 17 18 // 64-bit implementations of memory barrier can be simpler, because 19 // "sfence" is guaranteed to exist. 20 static inline void WriteMemoryBarrier() { 21 __asm__ __volatile__("sfence" : : : "memory"); 22 } 23 24 #elif defined(__ppc__) 25 26 static inline void WriteMemoryBarrier() { 27 __asm__ __volatile__("eieio" : : : "memory"); 28 } 29 30 #elif defined(__alpha__) 31 32 static inline void WriteMemoryBarrier() { 33 __asm__ __volatile__("wmb" : : : "memory"); 34 } 35 36 #else 37 38 #include "util/mutex.h" 39 40 static inline void WriteMemoryBarrier() { 41 // Slight overkill, but good enough: 42 // any mutex implementation must have 43 // a read barrier after the lock operation and 44 // a write barrier before the unlock operation. 45 // 46 // It may be worthwhile to write architecture-specific 47 // barriers for the common platforms, as above, but 48 // this is a correct fallback. 49 re2::Mutex mu; 50 re2::MutexLock l(&mu); 51 } 52 53 /* 54 #error Need WriteMemoryBarrier for architecture. 55 56 // Windows 57 inline void WriteMemoryBarrier() { 58 LONG x; 59 ::InterlockedExchange(&x, 0); 60 } 61 */ 62 63 #endif 64 65 // Alpha has very weak memory ordering. If relying on WriteBarriers, must one 66 // use read barriers for the readers too. 67 #if defined(__alpha__) 68 69 static inline void MaybeReadMemoryBarrier() { 70 __asm__ __volatile__("mb" : : : "memory"); 71 } 72 73 #else 74 75 static inline void MaybeReadMemoryBarrier() {} 76 77 #endif // __alpha__ 78 79 #endif // RE2_UTIL_ATOMICOPS_H__ 80