summaryrefslogtreecommitdiff
path: root/lib/asan/asan_lock.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asan/asan_lock.h')
-rw-r--r--lib/asan/asan_lock.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/asan/asan_lock.h b/lib/asan/asan_lock.h
new file mode 100644
index 000000000000..030fae613c23
--- /dev/null
+++ b/lib/asan/asan_lock.h
@@ -0,0 +1,100 @@
+//===-- asan_lock.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 AddressSanitizer, an address sanity checker.
+//
+// A wrapper for a simple lock.
+//===----------------------------------------------------------------------===//
+#ifndef ASAN_LOCK_H
+#define ASAN_LOCK_H
+
+#include "asan_internal.h"
+
+// The locks in ASan are global objects and they are never destroyed to avoid
+// at-exit races (that is, a lock is being used by other threads while the main
+// thread is doing atexit destructors).
+
+#ifdef __APPLE__
+#include <pthread.h>
+
+#include <libkern/OSAtomic.h>
+namespace __asan {
+class AsanLock {
+ public:
+ explicit AsanLock(LinkerInitialized) :
+ mu_(OS_SPINLOCK_INIT),
+ owner_(0),
+ is_locked_(false) {}
+
+ void Lock() {
+ CHECK(owner_ != pthread_self());
+ OSSpinLockLock(&mu_);
+ is_locked_ = true;
+ owner_ = pthread_self();
+ }
+ void Unlock() {
+ owner_ = 0;
+ is_locked_ = false;
+ OSSpinLockUnlock(&mu_);
+ }
+
+ bool IsLocked() {
+ // This is not atomic, e.g. one thread may get different values if another
+ // one is about to release the lock.
+ return is_locked_;
+ }
+ private:
+ OSSpinLock mu_;
+ volatile pthread_t owner_; // for debugging purposes
+ bool is_locked_; // for silly malloc_introspection_t interface
+};
+} // namespace __asan
+
+#else // assume linux
+#include <pthread.h>
+namespace __asan {
+class AsanLock {
+ public:
+ explicit AsanLock(LinkerInitialized) {
+ // We assume that pthread_mutex_t initialized to all zeroes is a valid
+ // unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
+ // a gcc warning:
+ // extended initializer lists only available with -std=c++0x or -std=gnu++0x
+ }
+ void Lock() {
+ pthread_mutex_lock(&mu_);
+ // pthread_spin_lock(&mu_);
+ }
+ void Unlock() {
+ pthread_mutex_unlock(&mu_);
+ // pthread_spin_unlock(&mu_);
+ }
+ private:
+ pthread_mutex_t mu_;
+ // pthread_spinlock_t mu_;
+};
+} // namespace __asan
+#endif
+
+namespace __asan {
+class ScopedLock {
+ public:
+ explicit ScopedLock(AsanLock *mu) : mu_(mu) {
+ mu_->Lock();
+ }
+ ~ScopedLock() {
+ mu_->Unlock();
+ }
+ private:
+ AsanLock *mu_;
+};
+
+} // namespace __asan
+
+#endif // ASAN_LOCK_H