Home | History | Annotate | Download | only in sdk_util
      1 /* Copyright 2013 The Chromium Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file. */
      4 
      5 #ifndef LIBRARIES_SDK_UTIL_ATOMICOPS_H_
      6 #define LIBRARIES_SDK_UTIL_ATOMICOPS_H_
      7 
      8 #ifndef WIN32
      9 
     10 #include <stdint.h>
     11 
     12 namespace sdk_util {
     13 
     14 typedef int32_t Atomic32;
     15 
     16 #ifndef __llvm__
     17 static inline void MemoryBarrier() {
     18   __sync_synchronize();
     19 }
     20 #endif
     21 
     22 inline Atomic32 AtomicCompareExchange(volatile Atomic32* ptr,
     23                                       Atomic32 new_value,
     24                                       Atomic32 old_value) {
     25   return __sync_val_compare_and_swap(ptr, new_value, old_value);
     26 }
     27 
     28 inline Atomic32 AtomicAddFetch(volatile Atomic32* ptr, Atomic32 value) {
     29   return __sync_add_and_fetch(ptr, value);
     30 }
     31 
     32 inline Atomic32 AtomicAndFetch(volatile Atomic32* ptr, Atomic32 value) {
     33   return __sync_and_and_fetch(ptr, value);
     34 }
     35 
     36 inline Atomic32 AtomicOrFetch(volatile Atomic32* ptr, Atomic32 value) {
     37   return __sync_or_and_fetch(ptr, value);
     38 }
     39 
     40 inline Atomic32 AtomicXorFetch(volatile Atomic32* ptr, Atomic32 value) {
     41   return __sync_xor_and_fetch(ptr, value);
     42 }
     43 
     44 }  // namespace sdk_util
     45 
     46 #else  // ifndef WIN32
     47 
     48 #include <windows.h>
     49 
     50 /* Undefine many Windows.h macros that we almost certainly do not want. */
     51 #undef min
     52 #undef max
     53 #undef PostMessage
     54 #undef interface
     55 
     56 namespace sdk_util {
     57 
     58 typedef long Atomic32;
     59 
     60 /* Windows.h already defines a MemoryBarrier macro. */
     61 
     62 inline Atomic32 AtomicCompareExchange(volatile Atomic32* ptr,
     63                                       Atomic32 newvalue,
     64                                       Atomic32 oldvalue) {
     65   return InterlockedCompareExchange(ptr, newvalue, oldvalue);
     66 }
     67 
     68 inline Atomic32 AtomicAddFetch(volatile Atomic32* ptr, Atomic32 value) {
     69   return InterlockedExchangeAdd(ptr, value);
     70 }
     71 
     72 inline Atomic32 AtomicAndFetch(volatile Atomic32* ptr, Atomic32 value) {
     73   Atomic32 oldval;
     74   Atomic32 newval;
     75   do {
     76     oldval = *ptr;
     77     newval = oldval & value;
     78   } while (InterlockedCompareExchange(ptr, newval, oldval) != oldval);
     79 
     80   return newval;
     81 }
     82 
     83 inline Atomic32 AtomicOrFetch(volatile Atomic32* ptr, Atomic32 value) {
     84   Atomic32 oldval;
     85   Atomic32 newval;
     86   do {
     87     oldval = *ptr;
     88     newval = oldval | value;
     89   } while (InterlockedCompareExchange(ptr,newval, oldval) != oldval);
     90 
     91   return newval;
     92 }
     93 
     94 inline Atomic32 AtomicXorFetch(volatile Atomic32* ptr, Atomic32 value) {
     95   Atomic32 oldval;
     96   Atomic32 newval;
     97   do {
     98     oldval = *ptr;
     99     newval = oldval ^ value;
    100   } while (InterlockedCompareExchange(ptr,newval, oldval) != oldval);
    101 
    102   return newval;
    103 }
    104 
    105 }  // namespace sdk_util
    106 
    107 #endif  // ifndef WIN32
    108 
    109 #endif  /* LIBRARIES_SDK_UTIL_ATOMICOPS_H_ */
    110