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 10static 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. 20static inline void WriteMemoryBarrier() { 21 __asm__ __volatile__("sfence" : : : "memory"); 22} 23 24#elif defined(__ppc__) 25 26static inline void WriteMemoryBarrier() { 27 __asm__ __volatile__("eieio" : : : "memory"); 28} 29 30#elif defined(__alpha__) 31 32static inline void WriteMemoryBarrier() { 33 __asm__ __volatile__("wmb" : : : "memory"); 34} 35 36#else 37 38#include "util/mutex.h" 39 40static 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 57inline 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 69static inline void MaybeReadMemoryBarrier() { 70 __asm__ __volatile__("mb" : : : "memory"); 71} 72 73#else 74 75static inline void MaybeReadMemoryBarrier() {} 76 77#endif // __alpha__ 78 79#endif // RE2_UTIL_ATOMICOPS_H__ 80