Home | History | Annotate | Download | only in util
      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