summaryrefslogtreecommitdiffstats
path: root/lib/sanitizer_common/sanitizer_mutex.h
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2012-07-30 10:58:13 +0000
committerandrew <andrew@FreeBSD.org>2012-07-30 10:58:13 +0000
commitcfeab007a554034f0b3ab4a677cf9dd2696c12f9 (patch)
tree40cc44a3d02ed86de24f2117a55680e4f0eb01a0 /lib/sanitizer_common/sanitizer_mutex.h
parent07af089f1449ec5506ca7ede5b593e11a0f48603 (diff)
downloadFreeBSD-src-cfeab007a554034f0b3ab4a677cf9dd2696c12f9.zip
FreeBSD-src-cfeab007a554034f0b3ab4a677cf9dd2696c12f9.tar.gz
Import compiler-rt r160957.
Diffstat (limited to 'lib/sanitizer_common/sanitizer_mutex.h')
-rw-r--r--lib/sanitizer_common/sanitizer_mutex.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_mutex.h b/lib/sanitizer_common/sanitizer_mutex.h
new file mode 100644
index 0000000..ca3e2f9
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_mutex.h
@@ -0,0 +1,100 @@
+//===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_MUTEX_H
+#define SANITIZER_MUTEX_H
+
+#include "sanitizer_atomic.h"
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_libc.h"
+
+namespace __sanitizer {
+
+class SpinMutex {
+ public:
+ SpinMutex() {
+ atomic_store(&state_, 0, memory_order_relaxed);
+ }
+
+ void Lock() {
+ if (atomic_exchange(&state_, 1, memory_order_acquire) == 0)
+ return;
+ LockSlow();
+ }
+
+ void Unlock() {
+ atomic_store(&state_, 0, memory_order_release);
+ }
+
+ private:
+ atomic_uint8_t state_;
+
+ void NOINLINE LockSlow() {
+ for (int i = 0;; i++) {
+ if (i < 10)
+ proc_yield(10);
+ else
+ internal_sched_yield();
+ if (atomic_load(&state_, memory_order_relaxed) == 0
+ && atomic_exchange(&state_, 1, memory_order_acquire) == 0)
+ return;
+ }
+ }
+
+ SpinMutex(const SpinMutex&);
+ void operator=(const SpinMutex&);
+};
+
+template<typename MutexType>
+class GenericScopedLock {
+ public:
+ explicit GenericScopedLock(MutexType *mu)
+ : mu_(mu) {
+ mu_->Lock();
+ }
+
+ ~GenericScopedLock() {
+ mu_->Unlock();
+ }
+
+ private:
+ MutexType *mu_;
+
+ GenericScopedLock(const GenericScopedLock&);
+ void operator=(const GenericScopedLock&);
+};
+
+template<typename MutexType>
+class GenericScopedReadLock {
+ public:
+ explicit GenericScopedReadLock(MutexType *mu)
+ : mu_(mu) {
+ mu_->ReadLock();
+ }
+
+ ~GenericScopedReadLock() {
+ mu_->ReadUnlock();
+ }
+
+ private:
+ MutexType *mu_;
+
+ GenericScopedReadLock(const GenericScopedReadLock&);
+ void operator=(const GenericScopedReadLock&);
+};
+
+typedef GenericScopedLock<SpinMutex> SpinMutexLock;
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_MUTEX_H
OpenPOWER on IntegriCloud