ipc/chromium/src/base/atomicops_internals_mutex.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/atomicops_internals_mutex.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,252 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: sw=2 ts=8 et :
     1.6 + */
     1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.10 +
    1.11 +// This file is an internal atomic implementation, use
    1.12 +// base/atomicops.h instead.
    1.13 +//
    1.14 +// This is a very slow fallback implementation of atomic operations
    1.15 +// that uses a mutex instead of atomic instructions.
    1.16 +//
    1.17 +// (NB: a small "optimization" here would be using a spinlock instead
    1.18 +// of a blocking mutex, but it's probably not worth the time.)
    1.19 +
    1.20 +#ifndef base_atomicops_internals_mutex_h
    1.21 +#define base_atomicops_internals_mutex_h
    1.22 +
    1.23 +#include "base/lock.h"
    1.24 +
    1.25 +namespace base {
    1.26 +namespace subtle {
    1.27 +
    1.28 +extern Lock gAtomicsMutex;
    1.29 +
    1.30 +template<typename T>
    1.31 +T Locked_CAS(volatile T* ptr, T old_value, T new_value) {
    1.32 +  AutoLock _(gAtomicsMutex);
    1.33 +
    1.34 +  T current_value = *ptr;
    1.35 +  if (current_value == old_value)
    1.36 +    *ptr = new_value;
    1.37 +  
    1.38 +  return current_value;
    1.39 +}
    1.40 +
    1.41 +template<typename T>
    1.42 +T Locked_AtomicExchange(volatile T* ptr, T new_value) {
    1.43 +  AutoLock _(gAtomicsMutex);
    1.44 +
    1.45 +  T current_value = *ptr;
    1.46 +  *ptr = new_value;
    1.47 +  return current_value;
    1.48 +}
    1.49 +
    1.50 +template<typename T>
    1.51 +T Locked_AtomicIncrement(volatile T* ptr, T increment) {
    1.52 +  AutoLock _(gAtomicsMutex);
    1.53 +  return *ptr += increment;
    1.54 +}
    1.55 +
    1.56 +template<typename T>
    1.57 +void Locked_Store(volatile T* ptr, T value) {
    1.58 +  AutoLock _(gAtomicsMutex);
    1.59 +  *ptr = value;
    1.60 +}
    1.61 +
    1.62 +template<typename T>
    1.63 +T Locked_Load(volatile const T* ptr) {
    1.64 +  AutoLock _(gAtomicsMutex);
    1.65 +  return *ptr;
    1.66 +}
    1.67 +
    1.68 +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    1.69 +                                         Atomic32 old_value,
    1.70 +                                         Atomic32 new_value) {
    1.71 +  return Locked_CAS(ptr, old_value, new_value);
    1.72 +}
    1.73 +
    1.74 +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    1.75 +                                         Atomic32 new_value) {
    1.76 +  return Locked_AtomicExchange(ptr, new_value);
    1.77 +}
    1.78 +
    1.79 +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    1.80 +                                          Atomic32 increment) {
    1.81 +  return Locked_AtomicIncrement(ptr, increment);
    1.82 +}
    1.83 +
    1.84 +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    1.85 +                                        Atomic32 increment) {
    1.86 +  return Locked_AtomicIncrement(ptr, increment);
    1.87 +}
    1.88 +
    1.89 +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    1.90 +                                       Atomic32 old_value,
    1.91 +                                       Atomic32 new_value) {
    1.92 +  return Locked_CAS(ptr, old_value, new_value);
    1.93 +}
    1.94 +
    1.95 +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    1.96 +                                       Atomic32 old_value,
    1.97 +                                       Atomic32 new_value) {
    1.98 +  return Locked_CAS(ptr, old_value, new_value);
    1.99 +}
   1.100 +
   1.101 +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
   1.102 +  return Locked_Store(ptr, value);
   1.103 +}
   1.104 +
   1.105 +inline void MemoryBarrier() {
   1.106 +  AutoLock _(gAtomicsMutex);
   1.107 +  // lock/unlock work as a barrier here
   1.108 +}
   1.109 +
   1.110 +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
   1.111 +  return Locked_Store(ptr, value);
   1.112 +}
   1.113 +
   1.114 +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
   1.115 +  return Locked_Store(ptr, value);
   1.116 +}
   1.117 +
   1.118 +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
   1.119 +  return Locked_Load(ptr);
   1.120 +}
   1.121 +
   1.122 +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
   1.123 +  return NoBarrier_Load(ptr);
   1.124 +}
   1.125 +
   1.126 +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
   1.127 +  return Locked_Load(ptr);
   1.128 +}
   1.129 +
   1.130 +#ifdef ARCH_CPU_64_BITS
   1.131 +
   1.132 +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
   1.133 +                                         Atomic64 old_value,
   1.134 +                                         Atomic64 new_value) {
   1.135 +  return Locked_CAS(ptr, old_value, new_value);
   1.136 +}
   1.137 +
   1.138 +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
   1.139 +                                         Atomic64 new_value) {
   1.140 +  return Locked_AtomicExchange(ptr, new_value);
   1.141 +}
   1.142 +
   1.143 +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
   1.144 +                                          Atomic64 increment) {
   1.145 +  return Locked_AtomicIncrement(ptr, increment);
   1.146 +}
   1.147 +
   1.148 +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
   1.149 +                                        Atomic64 increment) {
   1.150 +  return Locked_AtomicIncrement(ptr, increment);
   1.151 +}
   1.152 +
   1.153 +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
   1.154 +  return Locked_Store(ptr, value);
   1.155 +}
   1.156 +
   1.157 +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
   1.158 +                                       Atomic64 old_value,
   1.159 +                                       Atomic64 new_value) {
   1.160 +  return Locked_CAS(ptr, old_value, new_value);
   1.161 +}
   1.162 +
   1.163 +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
   1.164 +  return Locked_Store(ptr, value);
   1.165 +}
   1.166 +
   1.167 +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
   1.168 +  return Locked_Store(ptr, value);
   1.169 +}
   1.170 +
   1.171 +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
   1.172 +  return Locked_Load(ptr);
   1.173 +}
   1.174 +
   1.175 +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
   1.176 +  return Locked_Load(ptr);
   1.177 +}
   1.178 +
   1.179 +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
   1.180 +  return Locked_Load(ptr);
   1.181 +}
   1.182 +
   1.183 +#endif  // ARCH_CPU_64_BITS
   1.184 +
   1.185 +#ifdef OS_MACOSX
   1.186 +// From atomicops_internals_x86_macosx.h:
   1.187 +//
   1.188 +//   MacOS uses long for intptr_t, AtomicWord and Atomic32 are always
   1.189 +//   different on the Mac, even when they are the same size.  We need
   1.190 +//   to explicitly cast from AtomicWord to Atomic32/64 to implement
   1.191 +//   the AtomicWord interface.
   1.192 +
   1.193 +inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
   1.194 +                                           AtomicWord old_value,
   1.195 +                                           AtomicWord new_value) {
   1.196 +  return Locked_CAS(ptr, old_value, new_value);
   1.197 +}
   1.198 +
   1.199 +inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
   1.200 +                                           AtomicWord new_value) {
   1.201 +  return Locked_AtomicExchange(ptr, new_value);
   1.202 +}
   1.203 +
   1.204 +inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
   1.205 +                                            AtomicWord increment) {
   1.206 +  return Locked_AtomicIncrement(ptr, increment);
   1.207 +}
   1.208 +
   1.209 +inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
   1.210 +                                          AtomicWord increment) {
   1.211 +  return Locked_AtomicIncrement(ptr, increment);
   1.212 +}
   1.213 +
   1.214 +inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
   1.215 +                                         AtomicWord old_value,
   1.216 +                                         AtomicWord new_value) {
   1.217 +  return Locked_CAS(ptr, old_value, new_value);
   1.218 +}
   1.219 +
   1.220 +inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
   1.221 +                                         AtomicWord old_value,
   1.222 +                                         AtomicWord new_value) {
   1.223 +  return Locked_CAS(ptr, old_value, new_value);
   1.224 +}
   1.225 +
   1.226 +inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
   1.227 +  return Locked_Store(ptr, value);
   1.228 +}
   1.229 +
   1.230 +inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
   1.231 +  return Locked_Store(ptr, value);
   1.232 +}
   1.233 +
   1.234 +inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
   1.235 +  return Locked_Store(ptr, value);
   1.236 +}
   1.237 +
   1.238 +inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
   1.239 +  return Locked_Load(ptr);
   1.240 +}
   1.241 +
   1.242 +inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
   1.243 +  return Locked_Load(ptr);
   1.244 +}
   1.245 +
   1.246 +inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
   1.247 +  return Locked_Load(ptr);
   1.248 +}
   1.249 +
   1.250 +#endif  // OS_MACOSX
   1.251 +
   1.252 +}  // namespace subtle
   1.253 +}  // namespace base
   1.254 +
   1.255 +#endif  // base_atomicops_internals_mutex_h

mercurial