blob: 030fae613c2394c2bf537388f0013e4e19e5b207 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
|