diff options
Diffstat (limited to 'util/atomicops.h')
-rw-r--r-- | util/atomicops.h | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/util/atomicops.h b/util/atomicops.h new file mode 100644 index 0000000..11c1196 --- /dev/null +++ b/util/atomicops.h @@ -0,0 +1,79 @@ +// Copyright 2006-2008 The RE2 Authors. All Rights Reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#ifndef RE2_UTIL_ATOMICOPS_H__ +#define RE2_UTIL_ATOMICOPS_H__ + +#if defined(__i386__) + +static inline void WriteMemoryBarrier() { + int x; + __asm__ __volatile__("xchgl (%0),%0" // The lock prefix is implicit for xchg. + :: "r" (&x)); +} + +#elif defined(__x86_64__) + +// 64-bit implementations of memory barrier can be simpler, because +// "sfence" is guaranteed to exist. +static inline void WriteMemoryBarrier() { + __asm__ __volatile__("sfence" : : : "memory"); +} + +#elif defined(__ppc__) + +static inline void WriteMemoryBarrier() { + __asm__ __volatile__("eieio" : : : "memory"); +} + +#elif defined(__alpha__) + +static inline void WriteMemoryBarrier() { + __asm__ __volatile__("wmb" : : : "memory"); +} + +#else + +#include "util/mutex.h" + +static inline void WriteMemoryBarrier() { + // Slight overkill, but good enough: + // any mutex implementation must have + // a read barrier after the lock operation and + // a write barrier before the unlock operation. + // + // It may be worthwhile to write architecture-specific + // barriers for the common platforms, as above, but + // this is a correct fallback. + re2::Mutex mu; + re2::MutexLock l(&mu); +} + +/* +#error Need WriteMemoryBarrier for architecture. + +// Windows +inline void WriteMemoryBarrier() { + LONG x; + ::InterlockedExchange(&x, 0); +} +*/ + +#endif + +// Alpha has very weak memory ordering. If relying on WriteBarriers, must one +// use read barriers for the readers too. +#if defined(__alpha__) + +static inline void MaybeReadMemoryBarrier() { + __asm__ __volatile__("mb" : : : "memory"); +} + +#else + +static inline void MaybeReadMemoryBarrier() {} + +#endif // __alpha__ + +#endif // RE2_UTIL_ATOMICOPS_H__ |