1//===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of ThreadSanitizer/AddressSanitizer runtime. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef SANITIZER_MUTEX_H 15#define SANITIZER_MUTEX_H 16 17#include "sanitizer_atomic.h" 18#include "sanitizer_internal_defs.h" 19#include "sanitizer_libc.h" 20 21namespace __sanitizer { 22 23class StaticSpinMutex { 24 public: 25 void Init() { 26 atomic_store(&state_, 0, memory_order_relaxed); 27 } 28 29 void Lock() { 30 if (atomic_exchange(&state_, 1, memory_order_acquire) == 0) 31 return; 32 LockSlow(); 33 } 34 35 void Unlock() { 36 atomic_store(&state_, 0, memory_order_release); 37 } 38 39 private: 40 atomic_uint8_t state_; 41 42 void NOINLINE LockSlow() { 43 for (int i = 0;; i++) { 44 if (i < 10) 45 proc_yield(10); 46 else 47 internal_sched_yield(); 48 if (atomic_load(&state_, memory_order_relaxed) == 0 49 && atomic_exchange(&state_, 1, memory_order_acquire) == 0) 50 return; 51 } 52 } 53}; 54 55class SpinMutex : public StaticSpinMutex { 56 public: 57 SpinMutex() { 58 Init(); 59 } 60 61 private: 62 SpinMutex(const SpinMutex&); 63 void operator=(const SpinMutex&); 64}; 65 66template<typename MutexType> 67class GenericScopedLock { 68 public: 69 explicit GenericScopedLock(MutexType *mu) 70 : mu_(mu) { 71 mu_->Lock(); 72 } 73 74 ~GenericScopedLock() { 75 mu_->Unlock(); 76 } 77 78 private: 79 MutexType *mu_; 80 81 GenericScopedLock(const GenericScopedLock&); 82 void operator=(const GenericScopedLock&); 83}; 84 85template<typename MutexType> 86class GenericScopedReadLock { 87 public: 88 explicit GenericScopedReadLock(MutexType *mu) 89 : mu_(mu) { 90 mu_->ReadLock(); 91 } 92 93 ~GenericScopedReadLock() { 94 mu_->ReadUnlock(); 95 } 96 97 private: 98 MutexType *mu_; 99 100 GenericScopedReadLock(const GenericScopedReadLock&); 101 void operator=(const GenericScopedReadLock&); 102}; 103 104typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock; 105 106} // namespace __sanitizer 107 108#endif // SANITIZER_MUTEX_H 109