1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "mutex.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <errno.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/time.h>
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker #include <sstream>
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
25*795d594fSAndroid Build Coastguard Worker
26*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/systrace.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/time_utils.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/value_object.h"
31*795d594fSAndroid Build Coastguard Worker #include "monitor.h"
32*795d594fSAndroid Build Coastguard Worker #include "mutex-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
34*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "thread.h"
36*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
37*795d594fSAndroid Build Coastguard Worker
38*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
41*795d594fSAndroid Build Coastguard Worker
42*795d594fSAndroid Build Coastguard Worker static constexpr uint64_t kIntervalMillis = 50;
43*795d594fSAndroid Build Coastguard Worker static constexpr int kMonitorTimeoutTryMax = 5;
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker static const char* kLastDumpStackTime = "LastDumpStackTime";
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker struct AllMutexData {
48*795d594fSAndroid Build Coastguard Worker // A guard for all_mutexes_ that's not a mutex (Mutexes must CAS to acquire and busy wait).
49*795d594fSAndroid Build Coastguard Worker Atomic<const BaseMutex*> all_mutexes_guard;
50*795d594fSAndroid Build Coastguard Worker // All created mutexes guarded by all_mutexes_guard_.
51*795d594fSAndroid Build Coastguard Worker std::set<BaseMutex*>* all_mutexes;
AllMutexDataart::AllMutexData52*795d594fSAndroid Build Coastguard Worker AllMutexData() : all_mutexes(nullptr) {}
53*795d594fSAndroid Build Coastguard Worker };
54*795d594fSAndroid Build Coastguard Worker static struct AllMutexData gAllMutexData[kAllMutexDataSize];
55*795d594fSAndroid Build Coastguard Worker
56*795d594fSAndroid Build Coastguard Worker struct DumpStackLastTimeTLSData : public art::TLSData {
DumpStackLastTimeTLSDataart::DumpStackLastTimeTLSData57*795d594fSAndroid Build Coastguard Worker explicit DumpStackLastTimeTLSData(uint64_t last_dump_time_ms)
58*795d594fSAndroid Build Coastguard Worker : last_dump_time_ms_(last_dump_time_ms) {}
59*795d594fSAndroid Build Coastguard Worker std::atomic<uint64_t> last_dump_time_ms_;
60*795d594fSAndroid Build Coastguard Worker };
61*795d594fSAndroid Build Coastguard Worker
62*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
63*795d594fSAndroid Build Coastguard Worker // Compute a relative timespec as *result_ts = lhs - rhs.
64*795d594fSAndroid Build Coastguard Worker // Return false (and produce an invalid *result_ts) if lhs < rhs.
ComputeRelativeTimeSpec(timespec * result_ts,const timespec & lhs,const timespec & rhs)65*795d594fSAndroid Build Coastguard Worker static bool ComputeRelativeTimeSpec(timespec* result_ts, const timespec& lhs, const timespec& rhs) {
66*795d594fSAndroid Build Coastguard Worker const int32_t one_sec = 1000 * 1000 * 1000; // one second in nanoseconds.
67*795d594fSAndroid Build Coastguard Worker static_assert(std::is_signed<decltype(result_ts->tv_sec)>::value); // Signed on Linux.
68*795d594fSAndroid Build Coastguard Worker result_ts->tv_sec = lhs.tv_sec - rhs.tv_sec;
69*795d594fSAndroid Build Coastguard Worker result_ts->tv_nsec = lhs.tv_nsec - rhs.tv_nsec;
70*795d594fSAndroid Build Coastguard Worker if (result_ts->tv_nsec < 0) {
71*795d594fSAndroid Build Coastguard Worker result_ts->tv_sec--;
72*795d594fSAndroid Build Coastguard Worker result_ts->tv_nsec += one_sec;
73*795d594fSAndroid Build Coastguard Worker }
74*795d594fSAndroid Build Coastguard Worker DCHECK(result_ts->tv_nsec >= 0 && result_ts->tv_nsec < one_sec);
75*795d594fSAndroid Build Coastguard Worker return result_ts->tv_sec >= 0;
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker #endif
78*795d594fSAndroid Build Coastguard Worker
79*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
80*795d594fSAndroid Build Coastguard Worker // If we wake up from a futex wake, and the runtime disappeared while we were asleep,
81*795d594fSAndroid Build Coastguard Worker // it's important to stop in our tracks before we touch deallocated memory.
SleepIfRuntimeDeleted(Thread * self)82*795d594fSAndroid Build Coastguard Worker static inline void SleepIfRuntimeDeleted(Thread* self) {
83*795d594fSAndroid Build Coastguard Worker if (self != nullptr) {
84*795d594fSAndroid Build Coastguard Worker JNIEnvExt* const env = self->GetJniEnv();
85*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(env != nullptr && env->IsRuntimeDeleted())) {
86*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsDaemon());
87*795d594fSAndroid Build Coastguard Worker // If the runtime has been deleted, then we cannot proceed. Just sleep forever. This may
88*795d594fSAndroid Build Coastguard Worker // occur for user daemon threads that get a spurious wakeup. This occurs for test 132 with
89*795d594fSAndroid Build Coastguard Worker // --host and --gdb.
90*795d594fSAndroid Build Coastguard Worker // After we wake up, the runtime may have been shutdown, which means that this condition may
91*795d594fSAndroid Build Coastguard Worker // have been deleted. It is not safe to retry the wait.
92*795d594fSAndroid Build Coastguard Worker SleepForever();
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker }
95*795d594fSAndroid Build Coastguard Worker }
96*795d594fSAndroid Build Coastguard Worker #else
97*795d594fSAndroid Build Coastguard Worker // We should be doing this for pthreads to, but it seems to be impossible for something
98*795d594fSAndroid Build Coastguard Worker // like a condition variable wait. Thus we don't bother trying.
99*795d594fSAndroid Build Coastguard Worker #endif
100*795d594fSAndroid Build Coastguard Worker
101*795d594fSAndroid Build Coastguard Worker // Wait for an amount of time that roughly increases in the argument i.
102*795d594fSAndroid Build Coastguard Worker // Spin for small arguments and yield/sleep for longer ones.
BackOff(uint32_t i)103*795d594fSAndroid Build Coastguard Worker static void BackOff(uint32_t i) {
104*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kSpinMax = 10;
105*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kYieldMax = 20;
106*795d594fSAndroid Build Coastguard Worker if (i <= kSpinMax) {
107*795d594fSAndroid Build Coastguard Worker // TODO: Esp. in very latency-sensitive cases, consider replacing this with an explicit
108*795d594fSAndroid Build Coastguard Worker // test-and-test-and-set loop in the caller. Possibly skip entirely on a uniprocessor.
109*795d594fSAndroid Build Coastguard Worker volatile uint32_t x = 0;
110*795d594fSAndroid Build Coastguard Worker const uint32_t spin_count = 10 * i;
111*795d594fSAndroid Build Coastguard Worker for (uint32_t spin = 0; spin < spin_count; ++spin) {
112*795d594fSAndroid Build Coastguard Worker x = x + 1; // Volatile; hence should not be optimized away.
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker // TODO: Consider adding x86 PAUSE and/or ARM YIELD here.
115*795d594fSAndroid Build Coastguard Worker } else if (i <= kYieldMax) {
116*795d594fSAndroid Build Coastguard Worker sched_yield();
117*795d594fSAndroid Build Coastguard Worker } else {
118*795d594fSAndroid Build Coastguard Worker NanoSleep(1000ull * (i - kYieldMax));
119*795d594fSAndroid Build Coastguard Worker }
120*795d594fSAndroid Build Coastguard Worker }
121*795d594fSAndroid Build Coastguard Worker
122*795d594fSAndroid Build Coastguard Worker // Wait until pred(testLoc->load(std::memory_order_relaxed)) holds, or until a
123*795d594fSAndroid Build Coastguard Worker // short time interval, on the order of kernel context-switch time, passes.
124*795d594fSAndroid Build Coastguard Worker // Return true if the predicate test succeeded, false if we timed out.
125*795d594fSAndroid Build Coastguard Worker template<typename Pred>
WaitBrieflyFor(AtomicInteger * testLoc,Thread * self,Pred pred)126*795d594fSAndroid Build Coastguard Worker static inline bool WaitBrieflyFor(AtomicInteger* testLoc, Thread* self, Pred pred) {
127*795d594fSAndroid Build Coastguard Worker // TODO: Tune these parameters correctly. BackOff(3) should take on the order of 100 cycles. So
128*795d594fSAndroid Build Coastguard Worker // this should result in retrying <= 10 times, usually waiting around 100 cycles each. The
129*795d594fSAndroid Build Coastguard Worker // maximum delay should be significantly less than the expected futex() context switch time, so
130*795d594fSAndroid Build Coastguard Worker // there should be little danger of this worsening things appreciably. If the lock was only
131*795d594fSAndroid Build Coastguard Worker // held briefly by a running thread, this should help immensely.
132*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kMaxBackOff = 3; // Should probably be <= kSpinMax above.
133*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kMaxIters = 50;
134*795d594fSAndroid Build Coastguard Worker JNIEnvExt* const env = self == nullptr ? nullptr : self->GetJniEnv();
135*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 1; i <= kMaxIters; ++i) {
136*795d594fSAndroid Build Coastguard Worker BackOff(std::min(i, kMaxBackOff));
137*795d594fSAndroid Build Coastguard Worker if (pred(testLoc->load(std::memory_order_relaxed))) {
138*795d594fSAndroid Build Coastguard Worker return true;
139*795d594fSAndroid Build Coastguard Worker }
140*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(env != nullptr && env->IsRuntimeDeleted())) {
141*795d594fSAndroid Build Coastguard Worker // This returns true once we've started shutting down. We then try to reach a quiescent
142*795d594fSAndroid Build Coastguard Worker // state as soon as possible to avoid touching data that may be deallocated by the shutdown
143*795d594fSAndroid Build Coastguard Worker // process. It currently relies on a timeout.
144*795d594fSAndroid Build Coastguard Worker return false;
145*795d594fSAndroid Build Coastguard Worker }
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker return false;
148*795d594fSAndroid Build Coastguard Worker }
149*795d594fSAndroid Build Coastguard Worker
150*795d594fSAndroid Build Coastguard Worker class ScopedAllMutexesLock final {
151*795d594fSAndroid Build Coastguard Worker public:
ScopedAllMutexesLock(const BaseMutex * mutex)152*795d594fSAndroid Build Coastguard Worker explicit ScopedAllMutexesLock(const BaseMutex* mutex) : mutex_(mutex) {
153*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0;
154*795d594fSAndroid Build Coastguard Worker !gAllMutexData->all_mutexes_guard.CompareAndSetWeakAcquire(nullptr, mutex);
155*795d594fSAndroid Build Coastguard Worker ++i) {
156*795d594fSAndroid Build Coastguard Worker BackOff(i);
157*795d594fSAndroid Build Coastguard Worker }
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker
~ScopedAllMutexesLock()160*795d594fSAndroid Build Coastguard Worker ~ScopedAllMutexesLock() {
161*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(gAllMutexData->all_mutexes_guard.load(std::memory_order_relaxed), mutex_);
162*795d594fSAndroid Build Coastguard Worker gAllMutexData->all_mutexes_guard.store(nullptr, std::memory_order_release);
163*795d594fSAndroid Build Coastguard Worker }
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker private:
166*795d594fSAndroid Build Coastguard Worker const BaseMutex* const mutex_;
167*795d594fSAndroid Build Coastguard Worker };
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Worker // Scoped class that generates events at the beginning and end of lock contention.
170*795d594fSAndroid Build Coastguard Worker class ScopedContentionRecorder final : public ValueObject {
171*795d594fSAndroid Build Coastguard Worker public:
ScopedContentionRecorder(BaseMutex * mutex,uint64_t blocked_tid,uint64_t owner_tid)172*795d594fSAndroid Build Coastguard Worker ScopedContentionRecorder(BaseMutex* mutex, uint64_t blocked_tid, uint64_t owner_tid)
173*795d594fSAndroid Build Coastguard Worker : mutex_(kLogLockContentions ? mutex : nullptr),
174*795d594fSAndroid Build Coastguard Worker blocked_tid_(kLogLockContentions ? blocked_tid : 0),
175*795d594fSAndroid Build Coastguard Worker owner_tid_(kLogLockContentions ? owner_tid : 0),
176*795d594fSAndroid Build Coastguard Worker start_nano_time_(kLogLockContentions ? NanoTime() : 0) {
177*795d594fSAndroid Build Coastguard Worker if (ATraceEnabled()) {
178*795d594fSAndroid Build Coastguard Worker std::string msg = StringPrintf("Lock contention on %s (owner tid: %" PRIu64 ")",
179*795d594fSAndroid Build Coastguard Worker mutex->GetName(), owner_tid);
180*795d594fSAndroid Build Coastguard Worker ATraceBegin(msg.c_str());
181*795d594fSAndroid Build Coastguard Worker }
182*795d594fSAndroid Build Coastguard Worker }
183*795d594fSAndroid Build Coastguard Worker
~ScopedContentionRecorder()184*795d594fSAndroid Build Coastguard Worker ~ScopedContentionRecorder() {
185*795d594fSAndroid Build Coastguard Worker ATraceEnd();
186*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
187*795d594fSAndroid Build Coastguard Worker uint64_t end_nano_time = NanoTime();
188*795d594fSAndroid Build Coastguard Worker mutex_->RecordContention(blocked_tid_, owner_tid_, end_nano_time - start_nano_time_);
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker }
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker private:
193*795d594fSAndroid Build Coastguard Worker BaseMutex* const mutex_;
194*795d594fSAndroid Build Coastguard Worker const uint64_t blocked_tid_;
195*795d594fSAndroid Build Coastguard Worker const uint64_t owner_tid_;
196*795d594fSAndroid Build Coastguard Worker const uint64_t start_nano_time_;
197*795d594fSAndroid Build Coastguard Worker };
198*795d594fSAndroid Build Coastguard Worker
BaseMutex(const char * name,LockLevel level)199*795d594fSAndroid Build Coastguard Worker BaseMutex::BaseMutex(const char* name, LockLevel level)
200*795d594fSAndroid Build Coastguard Worker : name_(name),
201*795d594fSAndroid Build Coastguard Worker level_(level),
202*795d594fSAndroid Build Coastguard Worker should_respond_to_empty_checkpoint_request_(false) {
203*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
204*795d594fSAndroid Build Coastguard Worker ScopedAllMutexesLock mu(this);
205*795d594fSAndroid Build Coastguard Worker std::set<BaseMutex*>** all_mutexes_ptr = &gAllMutexData->all_mutexes;
206*795d594fSAndroid Build Coastguard Worker if (*all_mutexes_ptr == nullptr) {
207*795d594fSAndroid Build Coastguard Worker // We leak the global set of all mutexes to avoid ordering issues in global variable
208*795d594fSAndroid Build Coastguard Worker // construction/destruction.
209*795d594fSAndroid Build Coastguard Worker *all_mutexes_ptr = new std::set<BaseMutex*>();
210*795d594fSAndroid Build Coastguard Worker }
211*795d594fSAndroid Build Coastguard Worker (*all_mutexes_ptr)->insert(this);
212*795d594fSAndroid Build Coastguard Worker }
213*795d594fSAndroid Build Coastguard Worker }
214*795d594fSAndroid Build Coastguard Worker
~BaseMutex()215*795d594fSAndroid Build Coastguard Worker BaseMutex::~BaseMutex() {
216*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
217*795d594fSAndroid Build Coastguard Worker ScopedAllMutexesLock mu(this);
218*795d594fSAndroid Build Coastguard Worker gAllMutexData->all_mutexes->erase(this);
219*795d594fSAndroid Build Coastguard Worker }
220*795d594fSAndroid Build Coastguard Worker }
221*795d594fSAndroid Build Coastguard Worker
DumpAll(std::ostream & os)222*795d594fSAndroid Build Coastguard Worker void BaseMutex::DumpAll(std::ostream& os) {
223*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
224*795d594fSAndroid Build Coastguard Worker os << "Mutex logging:\n";
225*795d594fSAndroid Build Coastguard Worker ScopedAllMutexesLock mu(reinterpret_cast<const BaseMutex*>(-1));
226*795d594fSAndroid Build Coastguard Worker std::set<BaseMutex*>* all_mutexes = gAllMutexData->all_mutexes;
227*795d594fSAndroid Build Coastguard Worker if (all_mutexes == nullptr) {
228*795d594fSAndroid Build Coastguard Worker // No mutexes have been created yet during at startup.
229*795d594fSAndroid Build Coastguard Worker return;
230*795d594fSAndroid Build Coastguard Worker }
231*795d594fSAndroid Build Coastguard Worker os << "(Contended)\n";
232*795d594fSAndroid Build Coastguard Worker for (const BaseMutex* mutex : *all_mutexes) {
233*795d594fSAndroid Build Coastguard Worker if (mutex->HasEverContended()) {
234*795d594fSAndroid Build Coastguard Worker mutex->Dump(os);
235*795d594fSAndroid Build Coastguard Worker os << "\n";
236*795d594fSAndroid Build Coastguard Worker }
237*795d594fSAndroid Build Coastguard Worker }
238*795d594fSAndroid Build Coastguard Worker os << "(Never contented)\n";
239*795d594fSAndroid Build Coastguard Worker for (const BaseMutex* mutex : *all_mutexes) {
240*795d594fSAndroid Build Coastguard Worker if (!mutex->HasEverContended()) {
241*795d594fSAndroid Build Coastguard Worker mutex->Dump(os);
242*795d594fSAndroid Build Coastguard Worker os << "\n";
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker }
245*795d594fSAndroid Build Coastguard Worker }
246*795d594fSAndroid Build Coastguard Worker }
247*795d594fSAndroid Build Coastguard Worker
CheckSafeToWait(Thread * self)248*795d594fSAndroid Build Coastguard Worker void BaseMutex::CheckSafeToWait(Thread* self) {
249*795d594fSAndroid Build Coastguard Worker if (!kDebugLocking) {
250*795d594fSAndroid Build Coastguard Worker return;
251*795d594fSAndroid Build Coastguard Worker }
252*795d594fSAndroid Build Coastguard Worker // Avoid repeated reporting of the same violation in the common case.
253*795d594fSAndroid Build Coastguard Worker // We somewhat ignore races in the duplicate elision code. The first kMaxReports and the first
254*795d594fSAndroid Build Coastguard Worker // report for a given level_ should always appear.
255*795d594fSAndroid Build Coastguard Worker static std::atomic<uint> last_level_reported(kLockLevelCount);
256*795d594fSAndroid Build Coastguard Worker static constexpr int kMaxReports = 5;
257*795d594fSAndroid Build Coastguard Worker static std::atomic<uint> num_reports(0); // For the current level, more or less.
258*795d594fSAndroid Build Coastguard Worker
259*795d594fSAndroid Build Coastguard Worker if (self == nullptr) {
260*795d594fSAndroid Build Coastguard Worker CheckUnattachedThread(level_);
261*795d594fSAndroid Build Coastguard Worker } else if (num_reports.load(std::memory_order_relaxed) > kMaxReports &&
262*795d594fSAndroid Build Coastguard Worker last_level_reported.load(std::memory_order_relaxed) == level_) {
263*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Eliding probably redundant CheckSafeToWait() complaints";
264*795d594fSAndroid Build Coastguard Worker return;
265*795d594fSAndroid Build Coastguard Worker } else {
266*795d594fSAndroid Build Coastguard Worker CHECK(self->GetHeldMutex(level_) == this || level_ == kMonitorLock)
267*795d594fSAndroid Build Coastguard Worker << "Waiting on unacquired mutex: " << name_;
268*795d594fSAndroid Build Coastguard Worker bool bad_mutexes_held = false;
269*795d594fSAndroid Build Coastguard Worker std::string error_msg;
270*795d594fSAndroid Build Coastguard Worker for (int i = kLockLevelCount - 1; i >= 0; --i) {
271*795d594fSAndroid Build Coastguard Worker if (i != level_) {
272*795d594fSAndroid Build Coastguard Worker BaseMutex* held_mutex = self->GetHeldMutex(static_cast<LockLevel>(i));
273*795d594fSAndroid Build Coastguard Worker // We allow the thread to wait even if the user_code_suspension_lock_ is held so long. This
274*795d594fSAndroid Build Coastguard Worker // just means that gc or some other internal process is suspending the thread while it is
275*795d594fSAndroid Build Coastguard Worker // trying to suspend some other thread. So long as the current thread is not being suspended
276*795d594fSAndroid Build Coastguard Worker // by a SuspendReason::kForUserCode (which needs the user_code_suspension_lock_ to clear)
277*795d594fSAndroid Build Coastguard Worker // this is fine. This is needed due to user_code_suspension_lock_ being the way untrusted
278*795d594fSAndroid Build Coastguard Worker // code interacts with suspension. One holds the lock to prevent user-code-suspension from
279*795d594fSAndroid Build Coastguard Worker // occurring. Since this is only initiated from user-supplied native-code this is safe.
280*795d594fSAndroid Build Coastguard Worker if (held_mutex == Locks::user_code_suspension_lock_) {
281*795d594fSAndroid Build Coastguard Worker // No thread safety analysis is fine since we have both the user_code_suspension_lock_
282*795d594fSAndroid Build Coastguard Worker // from the line above and the ThreadSuspendCountLock since it is our level_. We use this
283*795d594fSAndroid Build Coastguard Worker // lambda to avoid having to annotate the whole function as NO_THREAD_SAFETY_ANALYSIS.
284*795d594fSAndroid Build Coastguard Worker auto is_suspending_for_user_code = [self]() NO_THREAD_SAFETY_ANALYSIS {
285*795d594fSAndroid Build Coastguard Worker return self->GetUserCodeSuspendCount() != 0;
286*795d594fSAndroid Build Coastguard Worker };
287*795d594fSAndroid Build Coastguard Worker if (is_suspending_for_user_code()) {
288*795d594fSAndroid Build Coastguard Worker std::ostringstream oss;
289*795d594fSAndroid Build Coastguard Worker oss << "Holding \"" << held_mutex->name_ << "\" "
290*795d594fSAndroid Build Coastguard Worker << "(level " << LockLevel(i) << ") while performing wait on "
291*795d594fSAndroid Build Coastguard Worker << "\"" << name_ << "\" (level " << level_ << ") "
292*795d594fSAndroid Build Coastguard Worker << "with SuspendReason::kForUserCode pending suspensions";
293*795d594fSAndroid Build Coastguard Worker error_msg = oss.str();
294*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << error_msg;
295*795d594fSAndroid Build Coastguard Worker bad_mutexes_held = true;
296*795d594fSAndroid Build Coastguard Worker }
297*795d594fSAndroid Build Coastguard Worker } else if (held_mutex != nullptr) {
298*795d594fSAndroid Build Coastguard Worker if (last_level_reported.load(std::memory_order_relaxed) == level_) {
299*795d594fSAndroid Build Coastguard Worker num_reports.fetch_add(1, std::memory_order_relaxed);
300*795d594fSAndroid Build Coastguard Worker } else {
301*795d594fSAndroid Build Coastguard Worker last_level_reported.store(level_, std::memory_order_relaxed);
302*795d594fSAndroid Build Coastguard Worker num_reports.store(0, std::memory_order_relaxed);
303*795d594fSAndroid Build Coastguard Worker }
304*795d594fSAndroid Build Coastguard Worker std::ostringstream oss;
305*795d594fSAndroid Build Coastguard Worker oss << "Holding \"" << held_mutex->name_ << "\" "
306*795d594fSAndroid Build Coastguard Worker << "(level " << LockLevel(i) << ") while performing wait on "
307*795d594fSAndroid Build Coastguard Worker << "\"" << name_ << "\" (level " << level_ << ")";
308*795d594fSAndroid Build Coastguard Worker error_msg = oss.str();
309*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << error_msg;
310*795d594fSAndroid Build Coastguard Worker bad_mutexes_held = true;
311*795d594fSAndroid Build Coastguard Worker }
312*795d594fSAndroid Build Coastguard Worker }
313*795d594fSAndroid Build Coastguard Worker }
314*795d594fSAndroid Build Coastguard Worker if (gAborting == 0) { // Avoid recursive aborts.
315*795d594fSAndroid Build Coastguard Worker CHECK(!bad_mutexes_held) << error_msg;
316*795d594fSAndroid Build Coastguard Worker }
317*795d594fSAndroid Build Coastguard Worker }
318*795d594fSAndroid Build Coastguard Worker }
319*795d594fSAndroid Build Coastguard Worker
AddToWaitTime(uint64_t value)320*795d594fSAndroid Build Coastguard Worker void BaseMutex::ContentionLogData::AddToWaitTime(uint64_t value) {
321*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
322*795d594fSAndroid Build Coastguard Worker // Atomically add value to wait_time.
323*795d594fSAndroid Build Coastguard Worker wait_time.fetch_add(value, std::memory_order_seq_cst);
324*795d594fSAndroid Build Coastguard Worker }
325*795d594fSAndroid Build Coastguard Worker }
326*795d594fSAndroid Build Coastguard Worker
RecordContention(uint64_t blocked_tid,uint64_t owner_tid,uint64_t nano_time_blocked)327*795d594fSAndroid Build Coastguard Worker void BaseMutex::RecordContention(uint64_t blocked_tid,
328*795d594fSAndroid Build Coastguard Worker uint64_t owner_tid,
329*795d594fSAndroid Build Coastguard Worker uint64_t nano_time_blocked) {
330*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
331*795d594fSAndroid Build Coastguard Worker ContentionLogData* data = contention_log_data_;
332*795d594fSAndroid Build Coastguard Worker ++(data->contention_count);
333*795d594fSAndroid Build Coastguard Worker data->AddToWaitTime(nano_time_blocked);
334*795d594fSAndroid Build Coastguard Worker ContentionLogEntry* log = data->contention_log;
335*795d594fSAndroid Build Coastguard Worker // This code is intentionally racy as it is only used for diagnostics.
336*795d594fSAndroid Build Coastguard Worker int32_t slot = data->cur_content_log_entry.load(std::memory_order_relaxed);
337*795d594fSAndroid Build Coastguard Worker if (log[slot].blocked_tid == blocked_tid &&
338*795d594fSAndroid Build Coastguard Worker log[slot].owner_tid == blocked_tid) {
339*795d594fSAndroid Build Coastguard Worker ++log[slot].count;
340*795d594fSAndroid Build Coastguard Worker } else {
341*795d594fSAndroid Build Coastguard Worker uint32_t new_slot;
342*795d594fSAndroid Build Coastguard Worker do {
343*795d594fSAndroid Build Coastguard Worker slot = data->cur_content_log_entry.load(std::memory_order_relaxed);
344*795d594fSAndroid Build Coastguard Worker new_slot = (slot + 1) % kContentionLogSize;
345*795d594fSAndroid Build Coastguard Worker } while (!data->cur_content_log_entry.CompareAndSetWeakRelaxed(slot, new_slot));
346*795d594fSAndroid Build Coastguard Worker log[new_slot].blocked_tid = blocked_tid;
347*795d594fSAndroid Build Coastguard Worker log[new_slot].owner_tid = owner_tid;
348*795d594fSAndroid Build Coastguard Worker log[new_slot].count.store(1, std::memory_order_relaxed);
349*795d594fSAndroid Build Coastguard Worker }
350*795d594fSAndroid Build Coastguard Worker }
351*795d594fSAndroid Build Coastguard Worker }
352*795d594fSAndroid Build Coastguard Worker
DumpContention(std::ostream & os) const353*795d594fSAndroid Build Coastguard Worker void BaseMutex::DumpContention(std::ostream& os) const {
354*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) {
355*795d594fSAndroid Build Coastguard Worker const ContentionLogData* data = contention_log_data_;
356*795d594fSAndroid Build Coastguard Worker const ContentionLogEntry* log = data->contention_log;
357*795d594fSAndroid Build Coastguard Worker uint64_t wait_time = data->wait_time.load(std::memory_order_relaxed);
358*795d594fSAndroid Build Coastguard Worker uint32_t contention_count = data->contention_count.load(std::memory_order_relaxed);
359*795d594fSAndroid Build Coastguard Worker if (contention_count == 0) {
360*795d594fSAndroid Build Coastguard Worker os << "never contended";
361*795d594fSAndroid Build Coastguard Worker } else {
362*795d594fSAndroid Build Coastguard Worker os << "contended " << contention_count
363*795d594fSAndroid Build Coastguard Worker << " total wait of contender " << PrettyDuration(wait_time)
364*795d594fSAndroid Build Coastguard Worker << " average " << PrettyDuration(wait_time / contention_count);
365*795d594fSAndroid Build Coastguard Worker SafeMap<uint64_t, size_t> most_common_blocker;
366*795d594fSAndroid Build Coastguard Worker SafeMap<uint64_t, size_t> most_common_blocked;
367*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < kContentionLogSize; ++i) {
368*795d594fSAndroid Build Coastguard Worker uint64_t blocked_tid = log[i].blocked_tid;
369*795d594fSAndroid Build Coastguard Worker uint64_t owner_tid = log[i].owner_tid;
370*795d594fSAndroid Build Coastguard Worker uint32_t count = log[i].count.load(std::memory_order_relaxed);
371*795d594fSAndroid Build Coastguard Worker if (count > 0) {
372*795d594fSAndroid Build Coastguard Worker auto it = most_common_blocked.find(blocked_tid);
373*795d594fSAndroid Build Coastguard Worker if (it != most_common_blocked.end()) {
374*795d594fSAndroid Build Coastguard Worker most_common_blocked.Overwrite(blocked_tid, it->second + count);
375*795d594fSAndroid Build Coastguard Worker } else {
376*795d594fSAndroid Build Coastguard Worker most_common_blocked.Put(blocked_tid, count);
377*795d594fSAndroid Build Coastguard Worker }
378*795d594fSAndroid Build Coastguard Worker it = most_common_blocker.find(owner_tid);
379*795d594fSAndroid Build Coastguard Worker if (it != most_common_blocker.end()) {
380*795d594fSAndroid Build Coastguard Worker most_common_blocker.Overwrite(owner_tid, it->second + count);
381*795d594fSAndroid Build Coastguard Worker } else {
382*795d594fSAndroid Build Coastguard Worker most_common_blocker.Put(owner_tid, count);
383*795d594fSAndroid Build Coastguard Worker }
384*795d594fSAndroid Build Coastguard Worker }
385*795d594fSAndroid Build Coastguard Worker }
386*795d594fSAndroid Build Coastguard Worker uint64_t max_tid = 0;
387*795d594fSAndroid Build Coastguard Worker size_t max_tid_count = 0;
388*795d594fSAndroid Build Coastguard Worker for (const auto& pair : most_common_blocked) {
389*795d594fSAndroid Build Coastguard Worker if (pair.second > max_tid_count) {
390*795d594fSAndroid Build Coastguard Worker max_tid = pair.first;
391*795d594fSAndroid Build Coastguard Worker max_tid_count = pair.second;
392*795d594fSAndroid Build Coastguard Worker }
393*795d594fSAndroid Build Coastguard Worker }
394*795d594fSAndroid Build Coastguard Worker if (max_tid != 0) {
395*795d594fSAndroid Build Coastguard Worker os << " sample shows most blocked tid=" << max_tid;
396*795d594fSAndroid Build Coastguard Worker }
397*795d594fSAndroid Build Coastguard Worker max_tid = 0;
398*795d594fSAndroid Build Coastguard Worker max_tid_count = 0;
399*795d594fSAndroid Build Coastguard Worker for (const auto& pair : most_common_blocker) {
400*795d594fSAndroid Build Coastguard Worker if (pair.second > max_tid_count) {
401*795d594fSAndroid Build Coastguard Worker max_tid = pair.first;
402*795d594fSAndroid Build Coastguard Worker max_tid_count = pair.second;
403*795d594fSAndroid Build Coastguard Worker }
404*795d594fSAndroid Build Coastguard Worker }
405*795d594fSAndroid Build Coastguard Worker if (max_tid != 0) {
406*795d594fSAndroid Build Coastguard Worker os << " sample shows tid=" << max_tid << " owning during this time";
407*795d594fSAndroid Build Coastguard Worker }
408*795d594fSAndroid Build Coastguard Worker }
409*795d594fSAndroid Build Coastguard Worker }
410*795d594fSAndroid Build Coastguard Worker }
411*795d594fSAndroid Build Coastguard Worker
412*795d594fSAndroid Build Coastguard Worker
Mutex(const char * name,LockLevel level,bool recursive)413*795d594fSAndroid Build Coastguard Worker Mutex::Mutex(const char* name, LockLevel level, bool recursive)
414*795d594fSAndroid Build Coastguard Worker : BaseMutex(name, level), exclusive_owner_(0), recursion_count_(0), recursive_(recursive) {
415*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
416*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(0, state_and_contenders_.load(std::memory_order_relaxed));
417*795d594fSAndroid Build Coastguard Worker #else
418*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_mutex_init, (&mutex_, nullptr));
419*795d594fSAndroid Build Coastguard Worker #endif
420*795d594fSAndroid Build Coastguard Worker }
421*795d594fSAndroid Build Coastguard Worker
422*795d594fSAndroid Build Coastguard Worker // Helper to allow checking shutdown while locking for thread safety.
IsSafeToCallAbortSafe()423*795d594fSAndroid Build Coastguard Worker static bool IsSafeToCallAbortSafe() {
424*795d594fSAndroid Build Coastguard Worker MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_);
425*795d594fSAndroid Build Coastguard Worker return Locks::IsSafeToCallAbortRacy();
426*795d594fSAndroid Build Coastguard Worker }
427*795d594fSAndroid Build Coastguard Worker
~Mutex()428*795d594fSAndroid Build Coastguard Worker Mutex::~Mutex() {
429*795d594fSAndroid Build Coastguard Worker bool safe_to_call_abort = Locks::IsSafeToCallAbortRacy();
430*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
431*795d594fSAndroid Build Coastguard Worker if (state_and_contenders_.load(std::memory_order_relaxed) != 0) {
432*795d594fSAndroid Build Coastguard Worker LOG(safe_to_call_abort ? FATAL : WARNING)
433*795d594fSAndroid Build Coastguard Worker << "destroying mutex with owner or contenders. Owner:" << GetExclusiveOwnerTid();
434*795d594fSAndroid Build Coastguard Worker } else {
435*795d594fSAndroid Build Coastguard Worker if (GetExclusiveOwnerTid() != 0) {
436*795d594fSAndroid Build Coastguard Worker LOG(safe_to_call_abort ? FATAL : WARNING)
437*795d594fSAndroid Build Coastguard Worker << "unexpectedly found an owner on unlocked mutex " << name_;
438*795d594fSAndroid Build Coastguard Worker }
439*795d594fSAndroid Build Coastguard Worker }
440*795d594fSAndroid Build Coastguard Worker #else
441*795d594fSAndroid Build Coastguard Worker // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread
442*795d594fSAndroid Build Coastguard Worker // may still be using locks.
443*795d594fSAndroid Build Coastguard Worker int rc = pthread_mutex_destroy(&mutex_);
444*795d594fSAndroid Build Coastguard Worker if (rc != 0) {
445*795d594fSAndroid Build Coastguard Worker errno = rc;
446*795d594fSAndroid Build Coastguard Worker PLOG(safe_to_call_abort ? FATAL : WARNING)
447*795d594fSAndroid Build Coastguard Worker << "pthread_mutex_destroy failed for " << name_;
448*795d594fSAndroid Build Coastguard Worker }
449*795d594fSAndroid Build Coastguard Worker #endif
450*795d594fSAndroid Build Coastguard Worker }
451*795d594fSAndroid Build Coastguard Worker
ExclusiveLock(Thread * self)452*795d594fSAndroid Build Coastguard Worker void Mutex::ExclusiveLock(Thread* self) {
453*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
454*795d594fSAndroid Build Coastguard Worker if (kDebugLocking && !recursive_) {
455*795d594fSAndroid Build Coastguard Worker AssertNotHeld(self);
456*795d594fSAndroid Build Coastguard Worker }
457*795d594fSAndroid Build Coastguard Worker if (!recursive_ || !IsExclusiveHeld(self)) {
458*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
459*795d594fSAndroid Build Coastguard Worker bool done = false;
460*795d594fSAndroid Build Coastguard Worker do {
461*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_and_contenders_.load(std::memory_order_relaxed);
462*795d594fSAndroid Build Coastguard Worker if (LIKELY((cur_state & kHeldMask) == 0) /* lock not held */) {
463*795d594fSAndroid Build Coastguard Worker done = state_and_contenders_.CompareAndSetWeakAcquire(cur_state, cur_state | kHeldMask);
464*795d594fSAndroid Build Coastguard Worker } else {
465*795d594fSAndroid Build Coastguard Worker // Failed to acquire, hang up.
466*795d594fSAndroid Build Coastguard Worker // We don't hold the mutex: GetExclusiveOwnerTid() is usually, but not always, correct.
467*795d594fSAndroid Build Coastguard Worker ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
468*795d594fSAndroid Build Coastguard Worker // Empirically, it appears important to spin again each time through the loop; if we
469*795d594fSAndroid Build Coastguard Worker // bother to go to sleep and wake up, we should be fairly persistent in trying for the
470*795d594fSAndroid Build Coastguard Worker // lock.
471*795d594fSAndroid Build Coastguard Worker if (!WaitBrieflyFor(&state_and_contenders_, self,
472*795d594fSAndroid Build Coastguard Worker [](int32_t v) { return (v & kHeldMask) == 0; })) {
473*795d594fSAndroid Build Coastguard Worker // Increment contender count. We can't create enough threads for this to overflow.
474*795d594fSAndroid Build Coastguard Worker increment_contenders();
475*795d594fSAndroid Build Coastguard Worker // Make cur_state again reflect the expected value of state_and_contenders.
476*795d594fSAndroid Build Coastguard Worker cur_state += kContenderIncrement;
477*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
478*795d594fSAndroid Build Coastguard Worker self->CheckEmptyCheckpointFromMutex();
479*795d594fSAndroid Build Coastguard Worker }
480*795d594fSAndroid Build Coastguard Worker
481*795d594fSAndroid Build Coastguard Worker uint64_t wait_start_ms = enable_monitor_timeout_ ? MilliTime() : 0;
482*795d594fSAndroid Build Coastguard Worker uint64_t try_times = 0;
483*795d594fSAndroid Build Coastguard Worker do {
484*795d594fSAndroid Build Coastguard Worker timespec timeout_ts;
485*795d594fSAndroid Build Coastguard Worker timeout_ts.tv_sec = 0;
486*795d594fSAndroid Build Coastguard Worker // NB: Some tests use the mutex without the runtime.
487*795d594fSAndroid Build Coastguard Worker timeout_ts.tv_nsec = Runtime::Current() != nullptr
488*795d594fSAndroid Build Coastguard Worker ? Runtime::Current()->GetMonitorTimeoutNs()
489*795d594fSAndroid Build Coastguard Worker : Monitor::kDefaultMonitorTimeoutMs;
490*795d594fSAndroid Build Coastguard Worker if (futex(state_and_contenders_.Address(), FUTEX_WAIT_PRIVATE, cur_state,
491*795d594fSAndroid Build Coastguard Worker enable_monitor_timeout_ ? &timeout_ts : nullptr , nullptr, 0) != 0) {
492*795d594fSAndroid Build Coastguard Worker // We only went to sleep after incrementing and contenders and checking that the
493*795d594fSAndroid Build Coastguard Worker // lock is still held by someone else. EAGAIN and EINTR both indicate a spurious
494*795d594fSAndroid Build Coastguard Worker // failure, try again from the beginning. We don't use TEMP_FAILURE_RETRY so we can
495*795d594fSAndroid Build Coastguard Worker // intentionally retry to acquire the lock.
496*795d594fSAndroid Build Coastguard Worker if ((errno != EAGAIN) && (errno != EINTR)) {
497*795d594fSAndroid Build Coastguard Worker if (errno == ETIMEDOUT) {
498*795d594fSAndroid Build Coastguard Worker try_times++;
499*795d594fSAndroid Build Coastguard Worker if (try_times <= kMonitorTimeoutTryMax) {
500*795d594fSAndroid Build Coastguard Worker DumpStack(self, wait_start_ms, try_times);
501*795d594fSAndroid Build Coastguard Worker }
502*795d594fSAndroid Build Coastguard Worker } else {
503*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "futex wait failed for " << name_;
504*795d594fSAndroid Build Coastguard Worker }
505*795d594fSAndroid Build Coastguard Worker }
506*795d594fSAndroid Build Coastguard Worker }
507*795d594fSAndroid Build Coastguard Worker SleepIfRuntimeDeleted(self);
508*795d594fSAndroid Build Coastguard Worker // Retry until not held. In heavy contention situations we otherwise get redundant
509*795d594fSAndroid Build Coastguard Worker // futex wakeups as a result of repeatedly decrementing and incrementing contenders.
510*795d594fSAndroid Build Coastguard Worker cur_state = state_and_contenders_.load(std::memory_order_relaxed);
511*795d594fSAndroid Build Coastguard Worker } while ((cur_state & kHeldMask) != 0);
512*795d594fSAndroid Build Coastguard Worker decrement_contenders();
513*795d594fSAndroid Build Coastguard Worker }
514*795d594fSAndroid Build Coastguard Worker }
515*795d594fSAndroid Build Coastguard Worker } while (!done);
516*795d594fSAndroid Build Coastguard Worker // Confirm that lock is now held.
517*795d594fSAndroid Build Coastguard Worker DCHECK_NE(state_and_contenders_.load(std::memory_order_relaxed) & kHeldMask, 0);
518*795d594fSAndroid Build Coastguard Worker #else
519*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_mutex_lock, (&mutex_));
520*795d594fSAndroid Build Coastguard Worker #endif
521*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(GetExclusiveOwnerTid(), 0) << " my tid = " << SafeGetTid(self)
522*795d594fSAndroid Build Coastguard Worker << " recursive_ = " << recursive_;
523*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(SafeGetTid(self), std::memory_order_relaxed);
524*795d594fSAndroid Build Coastguard Worker RegisterAsLocked(self);
525*795d594fSAndroid Build Coastguard Worker }
526*795d594fSAndroid Build Coastguard Worker recursion_count_++;
527*795d594fSAndroid Build Coastguard Worker if (kDebugLocking) {
528*795d594fSAndroid Build Coastguard Worker CHECK(recursion_count_ == 1 || recursive_) << "Unexpected recursion count on mutex: "
529*795d594fSAndroid Build Coastguard Worker << name_ << " " << recursion_count_;
530*795d594fSAndroid Build Coastguard Worker AssertHeld(self);
531*795d594fSAndroid Build Coastguard Worker }
532*795d594fSAndroid Build Coastguard Worker }
533*795d594fSAndroid Build Coastguard Worker
DumpStack(Thread * self,uint64_t wait_start_ms,uint64_t try_times)534*795d594fSAndroid Build Coastguard Worker void Mutex::DumpStack(Thread* self, uint64_t wait_start_ms, uint64_t try_times) {
535*795d594fSAndroid Build Coastguard Worker ScopedObjectAccess soa(self);
536*795d594fSAndroid Build Coastguard Worker Locks::thread_list_lock_->ExclusiveLock(self);
537*795d594fSAndroid Build Coastguard Worker std::string owner_stack_dump;
538*795d594fSAndroid Build Coastguard Worker pid_t owner_tid = GetExclusiveOwnerTid();
539*795d594fSAndroid Build Coastguard Worker CHECK(Runtime::Current() != nullptr);
540*795d594fSAndroid Build Coastguard Worker Thread *owner = Runtime::Current()->GetThreadList()->FindThreadByTid(owner_tid);
541*795d594fSAndroid Build Coastguard Worker if (owner != nullptr) {
542*795d594fSAndroid Build Coastguard Worker if (IsDumpFrequent(owner, try_times)) {
543*795d594fSAndroid Build Coastguard Worker Locks::thread_list_lock_->ExclusiveUnlock(self);
544*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Contention with tid " << owner_tid << ", monitor id " << monitor_id_;
545*795d594fSAndroid Build Coastguard Worker return;
546*795d594fSAndroid Build Coastguard Worker }
547*795d594fSAndroid Build Coastguard Worker struct CollectStackTrace : public Closure {
548*795d594fSAndroid Build Coastguard Worker void Run(art::Thread* thread) override
549*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {
550*795d594fSAndroid Build Coastguard Worker if (IsDumpFrequent(thread)) {
551*795d594fSAndroid Build Coastguard Worker return;
552*795d594fSAndroid Build Coastguard Worker }
553*795d594fSAndroid Build Coastguard Worker DumpStackLastTimeTLSData* tls_data =
554*795d594fSAndroid Build Coastguard Worker reinterpret_cast<DumpStackLastTimeTLSData*>(thread->GetCustomTLS(kLastDumpStackTime));
555*795d594fSAndroid Build Coastguard Worker if (tls_data == nullptr) {
556*795d594fSAndroid Build Coastguard Worker thread->SetCustomTLS(kLastDumpStackTime, new DumpStackLastTimeTLSData(MilliTime()));
557*795d594fSAndroid Build Coastguard Worker } else {
558*795d594fSAndroid Build Coastguard Worker tls_data->last_dump_time_ms_.store(MilliTime());
559*795d594fSAndroid Build Coastguard Worker }
560*795d594fSAndroid Build Coastguard Worker thread->DumpJavaStack(oss);
561*795d594fSAndroid Build Coastguard Worker }
562*795d594fSAndroid Build Coastguard Worker std::ostringstream oss;
563*795d594fSAndroid Build Coastguard Worker };
564*795d594fSAndroid Build Coastguard Worker CollectStackTrace owner_trace;
565*795d594fSAndroid Build Coastguard Worker owner->RequestSynchronousCheckpoint(&owner_trace);
566*795d594fSAndroid Build Coastguard Worker owner_stack_dump = owner_trace.oss.str();
567*795d594fSAndroid Build Coastguard Worker uint64_t wait_ms = MilliTime() - wait_start_ms;
568*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Monitor contention with tid " << owner_tid << ", wait time: " << wait_ms
569*795d594fSAndroid Build Coastguard Worker << "ms, monitor id: " << monitor_id_
570*795d594fSAndroid Build Coastguard Worker << "\nPerfMonitor owner thread(" << owner_tid << ") stack is:\n"
571*795d594fSAndroid Build Coastguard Worker << owner_stack_dump;
572*795d594fSAndroid Build Coastguard Worker } else {
573*795d594fSAndroid Build Coastguard Worker Locks::thread_list_lock_->ExclusiveUnlock(self);
574*795d594fSAndroid Build Coastguard Worker }
575*795d594fSAndroid Build Coastguard Worker }
576*795d594fSAndroid Build Coastguard Worker
IsDumpFrequent(Thread * thread,uint64_t try_times)577*795d594fSAndroid Build Coastguard Worker bool Mutex::IsDumpFrequent(Thread* thread, uint64_t try_times) {
578*795d594fSAndroid Build Coastguard Worker uint64_t last_dump_time_ms = 0;
579*795d594fSAndroid Build Coastguard Worker DumpStackLastTimeTLSData* tls_data =
580*795d594fSAndroid Build Coastguard Worker reinterpret_cast<DumpStackLastTimeTLSData*>(thread->GetCustomTLS(kLastDumpStackTime));
581*795d594fSAndroid Build Coastguard Worker if (tls_data != nullptr) {
582*795d594fSAndroid Build Coastguard Worker last_dump_time_ms = tls_data->last_dump_time_ms_.load();
583*795d594fSAndroid Build Coastguard Worker }
584*795d594fSAndroid Build Coastguard Worker uint64_t interval = MilliTime() - last_dump_time_ms;
585*795d594fSAndroid Build Coastguard Worker if (interval < kIntervalMillis * try_times) {
586*795d594fSAndroid Build Coastguard Worker return true;
587*795d594fSAndroid Build Coastguard Worker } else {
588*795d594fSAndroid Build Coastguard Worker return false;
589*795d594fSAndroid Build Coastguard Worker }
590*795d594fSAndroid Build Coastguard Worker }
591*795d594fSAndroid Build Coastguard Worker
592*795d594fSAndroid Build Coastguard Worker template <bool kCheck>
ExclusiveTryLock(Thread * self)593*795d594fSAndroid Build Coastguard Worker bool Mutex::ExclusiveTryLock(Thread* self) {
594*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
595*795d594fSAndroid Build Coastguard Worker if (kDebugLocking && !recursive_) {
596*795d594fSAndroid Build Coastguard Worker AssertNotHeld(self);
597*795d594fSAndroid Build Coastguard Worker }
598*795d594fSAndroid Build Coastguard Worker if (!recursive_ || !IsExclusiveHeld(self)) {
599*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
600*795d594fSAndroid Build Coastguard Worker bool done = false;
601*795d594fSAndroid Build Coastguard Worker do {
602*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_and_contenders_.load(std::memory_order_relaxed);
603*795d594fSAndroid Build Coastguard Worker if ((cur_state & kHeldMask) == 0) {
604*795d594fSAndroid Build Coastguard Worker // Change state to held and impose load/store ordering appropriate for lock acquisition.
605*795d594fSAndroid Build Coastguard Worker done = state_and_contenders_.CompareAndSetWeakAcquire(cur_state, cur_state | kHeldMask);
606*795d594fSAndroid Build Coastguard Worker } else {
607*795d594fSAndroid Build Coastguard Worker return false;
608*795d594fSAndroid Build Coastguard Worker }
609*795d594fSAndroid Build Coastguard Worker } while (!done);
610*795d594fSAndroid Build Coastguard Worker DCHECK_NE(state_and_contenders_.load(std::memory_order_relaxed) & kHeldMask, 0);
611*795d594fSAndroid Build Coastguard Worker #else
612*795d594fSAndroid Build Coastguard Worker int result = pthread_mutex_trylock(&mutex_);
613*795d594fSAndroid Build Coastguard Worker if (result == EBUSY) {
614*795d594fSAndroid Build Coastguard Worker return false;
615*795d594fSAndroid Build Coastguard Worker }
616*795d594fSAndroid Build Coastguard Worker if (result != 0) {
617*795d594fSAndroid Build Coastguard Worker errno = result;
618*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_;
619*795d594fSAndroid Build Coastguard Worker }
620*795d594fSAndroid Build Coastguard Worker #endif
621*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(GetExclusiveOwnerTid(), 0);
622*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(SafeGetTid(self), std::memory_order_relaxed);
623*795d594fSAndroid Build Coastguard Worker RegisterAsLocked(self, kCheck);
624*795d594fSAndroid Build Coastguard Worker }
625*795d594fSAndroid Build Coastguard Worker recursion_count_++;
626*795d594fSAndroid Build Coastguard Worker if (kDebugLocking) {
627*795d594fSAndroid Build Coastguard Worker CHECK(recursion_count_ == 1 || recursive_) << "Unexpected recursion count on mutex: "
628*795d594fSAndroid Build Coastguard Worker << name_ << " " << recursion_count_;
629*795d594fSAndroid Build Coastguard Worker AssertHeld(self);
630*795d594fSAndroid Build Coastguard Worker }
631*795d594fSAndroid Build Coastguard Worker return true;
632*795d594fSAndroid Build Coastguard Worker }
633*795d594fSAndroid Build Coastguard Worker
634*795d594fSAndroid Build Coastguard Worker template bool Mutex::ExclusiveTryLock<false>(Thread* self);
635*795d594fSAndroid Build Coastguard Worker template bool Mutex::ExclusiveTryLock<true>(Thread* self);
636*795d594fSAndroid Build Coastguard Worker
ExclusiveTryLockWithSpinning(Thread * self)637*795d594fSAndroid Build Coastguard Worker bool Mutex::ExclusiveTryLockWithSpinning(Thread* self) {
638*795d594fSAndroid Build Coastguard Worker // Spin a small number of times, since this affects our ability to respond to suspension
639*795d594fSAndroid Build Coastguard Worker // requests. We spin repeatedly only if the mutex repeatedly becomes available and unavailable
640*795d594fSAndroid Build Coastguard Worker // in rapid succession, and then we will typically not spin for the maximal period.
641*795d594fSAndroid Build Coastguard Worker const int kMaxSpins = 5;
642*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < kMaxSpins; ++i) {
643*795d594fSAndroid Build Coastguard Worker if (ExclusiveTryLock(self)) {
644*795d594fSAndroid Build Coastguard Worker return true;
645*795d594fSAndroid Build Coastguard Worker }
646*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
647*795d594fSAndroid Build Coastguard Worker if (!WaitBrieflyFor(&state_and_contenders_, self,
648*795d594fSAndroid Build Coastguard Worker [](int32_t v) { return (v & kHeldMask) == 0; })) {
649*795d594fSAndroid Build Coastguard Worker return false;
650*795d594fSAndroid Build Coastguard Worker }
651*795d594fSAndroid Build Coastguard Worker #endif
652*795d594fSAndroid Build Coastguard Worker }
653*795d594fSAndroid Build Coastguard Worker return ExclusiveTryLock(self);
654*795d594fSAndroid Build Coastguard Worker }
655*795d594fSAndroid Build Coastguard Worker
656*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
ExclusiveLockUncontendedFor(Thread * new_owner)657*795d594fSAndroid Build Coastguard Worker void Mutex::ExclusiveLockUncontendedFor(Thread* new_owner) {
658*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(level_, kMonitorLock);
659*795d594fSAndroid Build Coastguard Worker DCHECK(!recursive_);
660*795d594fSAndroid Build Coastguard Worker state_and_contenders_.store(kHeldMask, std::memory_order_relaxed);
661*795d594fSAndroid Build Coastguard Worker recursion_count_ = 1;
662*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(SafeGetTid(new_owner), std::memory_order_relaxed);
663*795d594fSAndroid Build Coastguard Worker // Don't call RegisterAsLocked(). It wouldn't register anything anyway. And
664*795d594fSAndroid Build Coastguard Worker // this happens as we're inflating a monitor, which doesn't logically affect
665*795d594fSAndroid Build Coastguard Worker // held "locks"; it effectively just converts a thin lock to a mutex. By doing
666*795d594fSAndroid Build Coastguard Worker // this while the lock is already held, we're delaying the acquisition of a
667*795d594fSAndroid Build Coastguard Worker // logically held mutex, which can introduce bogus lock order violations.
668*795d594fSAndroid Build Coastguard Worker }
669*795d594fSAndroid Build Coastguard Worker
ExclusiveUnlockUncontended()670*795d594fSAndroid Build Coastguard Worker void Mutex::ExclusiveUnlockUncontended() {
671*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(level_, kMonitorLock);
672*795d594fSAndroid Build Coastguard Worker state_and_contenders_.store(0, std::memory_order_relaxed);
673*795d594fSAndroid Build Coastguard Worker recursion_count_ = 0;
674*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
675*795d594fSAndroid Build Coastguard Worker // Skip RegisterAsUnlocked(), which wouldn't do anything anyway.
676*795d594fSAndroid Build Coastguard Worker }
677*795d594fSAndroid Build Coastguard Worker #endif // ART_USE_FUTEXES
678*795d594fSAndroid Build Coastguard Worker
ExclusiveUnlock(Thread * self)679*795d594fSAndroid Build Coastguard Worker void Mutex::ExclusiveUnlock(Thread* self) {
680*795d594fSAndroid Build Coastguard Worker if (kIsDebugBuild && self != nullptr && self != Thread::Current()) {
681*795d594fSAndroid Build Coastguard Worker std::string name1 = "<null>";
682*795d594fSAndroid Build Coastguard Worker std::string name2 = "<null>";
683*795d594fSAndroid Build Coastguard Worker if (self != nullptr) {
684*795d594fSAndroid Build Coastguard Worker self->GetThreadName(name1);
685*795d594fSAndroid Build Coastguard Worker }
686*795d594fSAndroid Build Coastguard Worker if (Thread::Current() != nullptr) {
687*795d594fSAndroid Build Coastguard Worker Thread::Current()->GetThreadName(name2);
688*795d594fSAndroid Build Coastguard Worker }
689*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << GetName() << " level=" << level_ << " self=" << name1
690*795d594fSAndroid Build Coastguard Worker << " Thread::Current()=" << name2;
691*795d594fSAndroid Build Coastguard Worker }
692*795d594fSAndroid Build Coastguard Worker AssertHeld(self);
693*795d594fSAndroid Build Coastguard Worker DCHECK_NE(GetExclusiveOwnerTid(), 0);
694*795d594fSAndroid Build Coastguard Worker recursion_count_--;
695*795d594fSAndroid Build Coastguard Worker if (!recursive_ || recursion_count_ == 0) {
696*795d594fSAndroid Build Coastguard Worker if (kDebugLocking) {
697*795d594fSAndroid Build Coastguard Worker CHECK(recursion_count_ == 0 || recursive_) << "Unexpected recursion count on mutex: "
698*795d594fSAndroid Build Coastguard Worker << name_ << " " << recursion_count_;
699*795d594fSAndroid Build Coastguard Worker }
700*795d594fSAndroid Build Coastguard Worker RegisterAsUnlocked(self);
701*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
702*795d594fSAndroid Build Coastguard Worker bool done = false;
703*795d594fSAndroid Build Coastguard Worker do {
704*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_and_contenders_.load(std::memory_order_relaxed);
705*795d594fSAndroid Build Coastguard Worker if (LIKELY((cur_state & kHeldMask) != 0)) {
706*795d594fSAndroid Build Coastguard Worker // We're no longer the owner.
707*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
708*795d594fSAndroid Build Coastguard Worker // Change state to not held and impose load/store ordering appropriate for lock release.
709*795d594fSAndroid Build Coastguard Worker uint32_t new_state = cur_state & ~kHeldMask; // Same number of contenders.
710*795d594fSAndroid Build Coastguard Worker done = state_and_contenders_.CompareAndSetWeakRelease(cur_state, new_state);
711*795d594fSAndroid Build Coastguard Worker if (LIKELY(done)) { // Spurious fail or waiters changed ?
712*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(new_state != 0) /* have contenders */) {
713*795d594fSAndroid Build Coastguard Worker futex(state_and_contenders_.Address(), FUTEX_WAKE_PRIVATE, kWakeOne,
714*795d594fSAndroid Build Coastguard Worker nullptr, nullptr, 0);
715*795d594fSAndroid Build Coastguard Worker }
716*795d594fSAndroid Build Coastguard Worker // We only do a futex wait after incrementing contenders and verifying the lock was
717*795d594fSAndroid Build Coastguard Worker // still held. If we didn't see waiters, then there couldn't have been any futexes
718*795d594fSAndroid Build Coastguard Worker // waiting on this lock when we did the CAS. New arrivals after that cannot wait for us,
719*795d594fSAndroid Build Coastguard Worker // since the futex wait call would see the lock available and immediately return.
720*795d594fSAndroid Build Coastguard Worker }
721*795d594fSAndroid Build Coastguard Worker } else {
722*795d594fSAndroid Build Coastguard Worker // Logging acquires the logging lock, avoid infinite recursion in that case.
723*795d594fSAndroid Build Coastguard Worker if (this != Locks::logging_lock_) {
724*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_;
725*795d594fSAndroid Build Coastguard Worker } else {
726*795d594fSAndroid Build Coastguard Worker LogHelper::LogLineLowStack(__FILE__,
727*795d594fSAndroid Build Coastguard Worker __LINE__,
728*795d594fSAndroid Build Coastguard Worker ::android::base::FATAL_WITHOUT_ABORT,
729*795d594fSAndroid Build Coastguard Worker StringPrintf("Unexpected state_ %d in unlock for %s",
730*795d594fSAndroid Build Coastguard Worker cur_state, name_).c_str());
731*795d594fSAndroid Build Coastguard Worker _exit(1);
732*795d594fSAndroid Build Coastguard Worker }
733*795d594fSAndroid Build Coastguard Worker }
734*795d594fSAndroid Build Coastguard Worker } while (!done);
735*795d594fSAndroid Build Coastguard Worker #else
736*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
737*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_mutex_unlock, (&mutex_));
738*795d594fSAndroid Build Coastguard Worker #endif
739*795d594fSAndroid Build Coastguard Worker }
740*795d594fSAndroid Build Coastguard Worker }
741*795d594fSAndroid Build Coastguard Worker
Dump(std::ostream & os) const742*795d594fSAndroid Build Coastguard Worker void Mutex::Dump(std::ostream& os) const {
743*795d594fSAndroid Build Coastguard Worker os << (recursive_ ? "recursive " : "non-recursive ") << name_
744*795d594fSAndroid Build Coastguard Worker << " level=" << static_cast<int>(level_) << " rec=" << recursion_count_
745*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
746*795d594fSAndroid Build Coastguard Worker << " state_and_contenders = " << std::hex << state_and_contenders_ << std::dec
747*795d594fSAndroid Build Coastguard Worker #endif
748*795d594fSAndroid Build Coastguard Worker << " owner=" << GetExclusiveOwnerTid() << " ";
749*795d594fSAndroid Build Coastguard Worker DumpContention(os);
750*795d594fSAndroid Build Coastguard Worker }
751*795d594fSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const Mutex & mu)752*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const Mutex& mu) {
753*795d594fSAndroid Build Coastguard Worker mu.Dump(os);
754*795d594fSAndroid Build Coastguard Worker return os;
755*795d594fSAndroid Build Coastguard Worker }
756*795d594fSAndroid Build Coastguard Worker
WakeupToRespondToEmptyCheckpoint()757*795d594fSAndroid Build Coastguard Worker void Mutex::WakeupToRespondToEmptyCheckpoint() {
758*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
759*795d594fSAndroid Build Coastguard Worker // Wake up all the waiters so they will respond to the emtpy checkpoint.
760*795d594fSAndroid Build Coastguard Worker DCHECK(should_respond_to_empty_checkpoint_request_);
761*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(get_contenders() != 0)) {
762*795d594fSAndroid Build Coastguard Worker futex(state_and_contenders_.Address(), FUTEX_WAKE_PRIVATE, kWakeAll, nullptr, nullptr, 0);
763*795d594fSAndroid Build Coastguard Worker }
764*795d594fSAndroid Build Coastguard Worker #else
765*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Non futex case isn't supported.";
766*795d594fSAndroid Build Coastguard Worker #endif
767*795d594fSAndroid Build Coastguard Worker }
768*795d594fSAndroid Build Coastguard Worker
ReaderWriterMutex(const char * name,LockLevel level)769*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex::ReaderWriterMutex(const char* name, LockLevel level)
770*795d594fSAndroid Build Coastguard Worker : BaseMutex(name, level)
771*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
772*795d594fSAndroid Build Coastguard Worker , state_(0), exclusive_owner_(0), num_contenders_(0)
773*795d594fSAndroid Build Coastguard Worker #endif
774*795d594fSAndroid Build Coastguard Worker {
775*795d594fSAndroid Build Coastguard Worker #if !ART_USE_FUTEXES
776*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_rwlock_init, (&rwlock_, nullptr));
777*795d594fSAndroid Build Coastguard Worker #endif
778*795d594fSAndroid Build Coastguard Worker }
779*795d594fSAndroid Build Coastguard Worker
~ReaderWriterMutex()780*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex::~ReaderWriterMutex() {
781*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
782*795d594fSAndroid Build Coastguard Worker CHECK_EQ(state_.load(std::memory_order_relaxed), 0);
783*795d594fSAndroid Build Coastguard Worker CHECK_EQ(GetExclusiveOwnerTid(), 0);
784*795d594fSAndroid Build Coastguard Worker CHECK_EQ(num_contenders_.load(std::memory_order_relaxed), 0);
785*795d594fSAndroid Build Coastguard Worker #else
786*795d594fSAndroid Build Coastguard Worker // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread
787*795d594fSAndroid Build Coastguard Worker // may still be using locks.
788*795d594fSAndroid Build Coastguard Worker int rc = pthread_rwlock_destroy(&rwlock_);
789*795d594fSAndroid Build Coastguard Worker if (rc != 0) {
790*795d594fSAndroid Build Coastguard Worker errno = rc;
791*795d594fSAndroid Build Coastguard Worker bool is_safe_to_call_abort = IsSafeToCallAbortSafe();
792*795d594fSAndroid Build Coastguard Worker PLOG(is_safe_to_call_abort ? FATAL : WARNING) << "pthread_rwlock_destroy failed for " << name_;
793*795d594fSAndroid Build Coastguard Worker }
794*795d594fSAndroid Build Coastguard Worker #endif
795*795d594fSAndroid Build Coastguard Worker }
796*795d594fSAndroid Build Coastguard Worker
ExclusiveLock(Thread * self)797*795d594fSAndroid Build Coastguard Worker void ReaderWriterMutex::ExclusiveLock(Thread* self) {
798*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
799*795d594fSAndroid Build Coastguard Worker AssertNotExclusiveHeld(self);
800*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
801*795d594fSAndroid Build Coastguard Worker bool done = false;
802*795d594fSAndroid Build Coastguard Worker do {
803*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_.load(std::memory_order_relaxed);
804*795d594fSAndroid Build Coastguard Worker if (LIKELY(cur_state == 0)) {
805*795d594fSAndroid Build Coastguard Worker // Change state from 0 to -1 and impose load/store ordering appropriate for lock acquisition.
806*795d594fSAndroid Build Coastguard Worker done = state_.CompareAndSetWeakAcquire(0 /* cur_state*/, -1 /* new state */);
807*795d594fSAndroid Build Coastguard Worker } else {
808*795d594fSAndroid Build Coastguard Worker // Failed to acquire, hang up.
809*795d594fSAndroid Build Coastguard Worker ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
810*795d594fSAndroid Build Coastguard Worker if (!WaitBrieflyFor(&state_, self, [](int32_t v) { return v == 0; })) {
811*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_add(1);
812*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
813*795d594fSAndroid Build Coastguard Worker self->CheckEmptyCheckpointFromMutex();
814*795d594fSAndroid Build Coastguard Worker }
815*795d594fSAndroid Build Coastguard Worker if (futex(state_.Address(), FUTEX_WAIT_PRIVATE, cur_state, nullptr, nullptr, 0) != 0) {
816*795d594fSAndroid Build Coastguard Worker // EAGAIN and EINTR both indicate a spurious failure, try again from the beginning.
817*795d594fSAndroid Build Coastguard Worker // We don't use TEMP_FAILURE_RETRY so we can intentionally retry to acquire the lock.
818*795d594fSAndroid Build Coastguard Worker if ((errno != EAGAIN) && (errno != EINTR)) {
819*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "futex wait failed for " << name_;
820*795d594fSAndroid Build Coastguard Worker }
821*795d594fSAndroid Build Coastguard Worker }
822*795d594fSAndroid Build Coastguard Worker SleepIfRuntimeDeleted(self);
823*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_sub(1);
824*795d594fSAndroid Build Coastguard Worker }
825*795d594fSAndroid Build Coastguard Worker }
826*795d594fSAndroid Build Coastguard Worker } while (!done);
827*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(state_.load(std::memory_order_relaxed), -1);
828*795d594fSAndroid Build Coastguard Worker #else
829*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_rwlock_wrlock, (&rwlock_));
830*795d594fSAndroid Build Coastguard Worker #endif
831*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(GetExclusiveOwnerTid(), 0);
832*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(SafeGetTid(self), std::memory_order_relaxed);
833*795d594fSAndroid Build Coastguard Worker RegisterAsLocked(self);
834*795d594fSAndroid Build Coastguard Worker AssertExclusiveHeld(self);
835*795d594fSAndroid Build Coastguard Worker }
836*795d594fSAndroid Build Coastguard Worker
ExclusiveUnlock(Thread * self)837*795d594fSAndroid Build Coastguard Worker void ReaderWriterMutex::ExclusiveUnlock(Thread* self) {
838*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
839*795d594fSAndroid Build Coastguard Worker AssertExclusiveHeld(self);
840*795d594fSAndroid Build Coastguard Worker RegisterAsUnlocked(self);
841*795d594fSAndroid Build Coastguard Worker DCHECK_NE(GetExclusiveOwnerTid(), 0);
842*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
843*795d594fSAndroid Build Coastguard Worker bool done = false;
844*795d594fSAndroid Build Coastguard Worker do {
845*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_.load(std::memory_order_relaxed);
846*795d594fSAndroid Build Coastguard Worker if (LIKELY(cur_state == -1)) {
847*795d594fSAndroid Build Coastguard Worker // We're no longer the owner.
848*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
849*795d594fSAndroid Build Coastguard Worker // Change state from -1 to 0 and impose load/store ordering appropriate for lock release.
850*795d594fSAndroid Build Coastguard Worker // Note, the num_contenders_ load below musn't reorder before the CompareAndSet.
851*795d594fSAndroid Build Coastguard Worker done = state_.CompareAndSetWeakSequentiallyConsistent(-1 /* cur_state*/, 0 /* new state */);
852*795d594fSAndroid Build Coastguard Worker if (LIKELY(done)) { // Weak CAS may fail spuriously.
853*795d594fSAndroid Build Coastguard Worker // Wake any waiters.
854*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(num_contenders_.load(std::memory_order_seq_cst) > 0)) {
855*795d594fSAndroid Build Coastguard Worker futex(state_.Address(), FUTEX_WAKE_PRIVATE, kWakeAll, nullptr, nullptr, 0);
856*795d594fSAndroid Build Coastguard Worker }
857*795d594fSAndroid Build Coastguard Worker }
858*795d594fSAndroid Build Coastguard Worker } else {
859*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unexpected state_:" << cur_state << " for " << name_;
860*795d594fSAndroid Build Coastguard Worker }
861*795d594fSAndroid Build Coastguard Worker } while (!done);
862*795d594fSAndroid Build Coastguard Worker #else
863*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
864*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_rwlock_unlock, (&rwlock_));
865*795d594fSAndroid Build Coastguard Worker #endif
866*795d594fSAndroid Build Coastguard Worker }
867*795d594fSAndroid Build Coastguard Worker
868*795d594fSAndroid Build Coastguard Worker #if HAVE_TIMED_RWLOCK
ExclusiveLockWithTimeout(Thread * self,int64_t ms,int32_t ns)869*795d594fSAndroid Build Coastguard Worker bool ReaderWriterMutex::ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32_t ns) {
870*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
871*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
872*795d594fSAndroid Build Coastguard Worker bool done = false;
873*795d594fSAndroid Build Coastguard Worker timespec end_abs_ts;
874*795d594fSAndroid Build Coastguard Worker InitTimeSpec(true, CLOCK_MONOTONIC, ms, ns, &end_abs_ts);
875*795d594fSAndroid Build Coastguard Worker do {
876*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_.load(std::memory_order_relaxed);
877*795d594fSAndroid Build Coastguard Worker if (cur_state == 0) {
878*795d594fSAndroid Build Coastguard Worker // Change state from 0 to -1 and impose load/store ordering appropriate for lock acquisition.
879*795d594fSAndroid Build Coastguard Worker done = state_.CompareAndSetWeakAcquire(0 /* cur_state */, -1 /* new state */);
880*795d594fSAndroid Build Coastguard Worker } else {
881*795d594fSAndroid Build Coastguard Worker // Failed to acquire, hang up.
882*795d594fSAndroid Build Coastguard Worker timespec now_abs_ts;
883*795d594fSAndroid Build Coastguard Worker InitTimeSpec(true, CLOCK_MONOTONIC, 0, 0, &now_abs_ts);
884*795d594fSAndroid Build Coastguard Worker timespec rel_ts;
885*795d594fSAndroid Build Coastguard Worker if (!ComputeRelativeTimeSpec(&rel_ts, end_abs_ts, now_abs_ts)) {
886*795d594fSAndroid Build Coastguard Worker return false; // Timed out.
887*795d594fSAndroid Build Coastguard Worker }
888*795d594fSAndroid Build Coastguard Worker ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
889*795d594fSAndroid Build Coastguard Worker if (!WaitBrieflyFor(&state_, self, [](int32_t v) { return v == 0; })) {
890*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_add(1);
891*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
892*795d594fSAndroid Build Coastguard Worker self->CheckEmptyCheckpointFromMutex();
893*795d594fSAndroid Build Coastguard Worker }
894*795d594fSAndroid Build Coastguard Worker if (futex(state_.Address(), FUTEX_WAIT_PRIVATE, cur_state, &rel_ts, nullptr, 0) != 0) {
895*795d594fSAndroid Build Coastguard Worker if (errno == ETIMEDOUT) {
896*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_sub(1);
897*795d594fSAndroid Build Coastguard Worker return false; // Timed out.
898*795d594fSAndroid Build Coastguard Worker } else if ((errno != EAGAIN) && (errno != EINTR)) {
899*795d594fSAndroid Build Coastguard Worker // EAGAIN and EINTR both indicate a spurious failure,
900*795d594fSAndroid Build Coastguard Worker // recompute the relative time out from now and try again.
901*795d594fSAndroid Build Coastguard Worker // We don't use TEMP_FAILURE_RETRY so we can recompute rel_ts;
902*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_sub(1); // Unlikely to matter.
903*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "timed futex wait failed for " << name_;
904*795d594fSAndroid Build Coastguard Worker }
905*795d594fSAndroid Build Coastguard Worker }
906*795d594fSAndroid Build Coastguard Worker SleepIfRuntimeDeleted(self);
907*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_sub(1);
908*795d594fSAndroid Build Coastguard Worker }
909*795d594fSAndroid Build Coastguard Worker }
910*795d594fSAndroid Build Coastguard Worker } while (!done);
911*795d594fSAndroid Build Coastguard Worker #else
912*795d594fSAndroid Build Coastguard Worker timespec ts;
913*795d594fSAndroid Build Coastguard Worker InitTimeSpec(true, CLOCK_REALTIME, ms, ns, &ts);
914*795d594fSAndroid Build Coastguard Worker int result = pthread_rwlock_timedwrlock(&rwlock_, &ts);
915*795d594fSAndroid Build Coastguard Worker if (result == ETIMEDOUT) {
916*795d594fSAndroid Build Coastguard Worker return false;
917*795d594fSAndroid Build Coastguard Worker }
918*795d594fSAndroid Build Coastguard Worker if (result != 0) {
919*795d594fSAndroid Build Coastguard Worker errno = result;
920*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "pthread_rwlock_timedwrlock failed for " << name_;
921*795d594fSAndroid Build Coastguard Worker }
922*795d594fSAndroid Build Coastguard Worker #endif
923*795d594fSAndroid Build Coastguard Worker exclusive_owner_.store(SafeGetTid(self), std::memory_order_relaxed);
924*795d594fSAndroid Build Coastguard Worker RegisterAsLocked(self);
925*795d594fSAndroid Build Coastguard Worker AssertSharedHeld(self);
926*795d594fSAndroid Build Coastguard Worker return true;
927*795d594fSAndroid Build Coastguard Worker }
928*795d594fSAndroid Build Coastguard Worker #endif
929*795d594fSAndroid Build Coastguard Worker
930*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
HandleSharedLockContention(Thread * self,int32_t cur_state)931*795d594fSAndroid Build Coastguard Worker void ReaderWriterMutex::HandleSharedLockContention(Thread* self, int32_t cur_state) {
932*795d594fSAndroid Build Coastguard Worker // Owner holds it exclusively, hang up.
933*795d594fSAndroid Build Coastguard Worker ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
934*795d594fSAndroid Build Coastguard Worker if (!WaitBrieflyFor(&state_, self, [](int32_t v) { return v >= 0; })) {
935*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_add(1);
936*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
937*795d594fSAndroid Build Coastguard Worker self->CheckEmptyCheckpointFromMutex();
938*795d594fSAndroid Build Coastguard Worker }
939*795d594fSAndroid Build Coastguard Worker if (futex(state_.Address(), FUTEX_WAIT_PRIVATE, cur_state, nullptr, nullptr, 0) != 0) {
940*795d594fSAndroid Build Coastguard Worker if (errno != EAGAIN && errno != EINTR) {
941*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "futex wait failed for " << name_;
942*795d594fSAndroid Build Coastguard Worker }
943*795d594fSAndroid Build Coastguard Worker }
944*795d594fSAndroid Build Coastguard Worker SleepIfRuntimeDeleted(self);
945*795d594fSAndroid Build Coastguard Worker num_contenders_.fetch_sub(1);
946*795d594fSAndroid Build Coastguard Worker }
947*795d594fSAndroid Build Coastguard Worker }
948*795d594fSAndroid Build Coastguard Worker #endif
949*795d594fSAndroid Build Coastguard Worker
SharedTryLock(Thread * self,bool check)950*795d594fSAndroid Build Coastguard Worker bool ReaderWriterMutex::SharedTryLock(Thread* self, bool check) {
951*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
952*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
953*795d594fSAndroid Build Coastguard Worker bool done = false;
954*795d594fSAndroid Build Coastguard Worker do {
955*795d594fSAndroid Build Coastguard Worker int32_t cur_state = state_.load(std::memory_order_relaxed);
956*795d594fSAndroid Build Coastguard Worker if (cur_state >= 0) {
957*795d594fSAndroid Build Coastguard Worker // Add as an extra reader and impose load/store ordering appropriate for lock acquisition.
958*795d594fSAndroid Build Coastguard Worker done = state_.CompareAndSetWeakAcquire(cur_state, cur_state + 1);
959*795d594fSAndroid Build Coastguard Worker } else {
960*795d594fSAndroid Build Coastguard Worker // Owner holds it exclusively.
961*795d594fSAndroid Build Coastguard Worker return false;
962*795d594fSAndroid Build Coastguard Worker }
963*795d594fSAndroid Build Coastguard Worker } while (!done);
964*795d594fSAndroid Build Coastguard Worker #else
965*795d594fSAndroid Build Coastguard Worker int result = pthread_rwlock_tryrdlock(&rwlock_);
966*795d594fSAndroid Build Coastguard Worker if (result == EBUSY) {
967*795d594fSAndroid Build Coastguard Worker return false;
968*795d594fSAndroid Build Coastguard Worker }
969*795d594fSAndroid Build Coastguard Worker if (result != 0) {
970*795d594fSAndroid Build Coastguard Worker errno = result;
971*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_;
972*795d594fSAndroid Build Coastguard Worker }
973*795d594fSAndroid Build Coastguard Worker #endif
974*795d594fSAndroid Build Coastguard Worker RegisterAsLocked(self, check);
975*795d594fSAndroid Build Coastguard Worker AssertSharedHeld(self);
976*795d594fSAndroid Build Coastguard Worker return true;
977*795d594fSAndroid Build Coastguard Worker }
978*795d594fSAndroid Build Coastguard Worker
IsSharedHeld(const Thread * self) const979*795d594fSAndroid Build Coastguard Worker bool ReaderWriterMutex::IsSharedHeld(const Thread* self) const {
980*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
981*795d594fSAndroid Build Coastguard Worker bool result;
982*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(self == nullptr)) { // Handle unattached threads.
983*795d594fSAndroid Build Coastguard Worker result = IsExclusiveHeld(self); // TODO: a better best effort here.
984*795d594fSAndroid Build Coastguard Worker } else {
985*795d594fSAndroid Build Coastguard Worker result = (self->GetHeldMutex(level_) == this);
986*795d594fSAndroid Build Coastguard Worker }
987*795d594fSAndroid Build Coastguard Worker return result;
988*795d594fSAndroid Build Coastguard Worker }
989*795d594fSAndroid Build Coastguard Worker
Dump(std::ostream & os) const990*795d594fSAndroid Build Coastguard Worker void ReaderWriterMutex::Dump(std::ostream& os) const {
991*795d594fSAndroid Build Coastguard Worker os << name_
992*795d594fSAndroid Build Coastguard Worker << " level=" << static_cast<int>(level_)
993*795d594fSAndroid Build Coastguard Worker << " owner=" << GetExclusiveOwnerTid()
994*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
995*795d594fSAndroid Build Coastguard Worker << " state=" << state_.load(std::memory_order_seq_cst)
996*795d594fSAndroid Build Coastguard Worker << " num_contenders=" << num_contenders_.load(std::memory_order_seq_cst)
997*795d594fSAndroid Build Coastguard Worker #endif
998*795d594fSAndroid Build Coastguard Worker << " ";
999*795d594fSAndroid Build Coastguard Worker DumpContention(os);
1000*795d594fSAndroid Build Coastguard Worker }
1001*795d594fSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const ReaderWriterMutex & mu)1002*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu) {
1003*795d594fSAndroid Build Coastguard Worker mu.Dump(os);
1004*795d594fSAndroid Build Coastguard Worker return os;
1005*795d594fSAndroid Build Coastguard Worker }
1006*795d594fSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const MutatorMutex & mu)1007*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const MutatorMutex& mu) {
1008*795d594fSAndroid Build Coastguard Worker mu.Dump(os);
1009*795d594fSAndroid Build Coastguard Worker return os;
1010*795d594fSAndroid Build Coastguard Worker }
1011*795d594fSAndroid Build Coastguard Worker
WakeupToRespondToEmptyCheckpoint()1012*795d594fSAndroid Build Coastguard Worker void ReaderWriterMutex::WakeupToRespondToEmptyCheckpoint() {
1013*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1014*795d594fSAndroid Build Coastguard Worker // Wake up all the waiters so they will respond to the emtpy checkpoint.
1015*795d594fSAndroid Build Coastguard Worker DCHECK(should_respond_to_empty_checkpoint_request_);
1016*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(num_contenders_.load(std::memory_order_relaxed) > 0)) {
1017*795d594fSAndroid Build Coastguard Worker futex(state_.Address(), FUTEX_WAKE_PRIVATE, kWakeAll, nullptr, nullptr, 0);
1018*795d594fSAndroid Build Coastguard Worker }
1019*795d594fSAndroid Build Coastguard Worker #else
1020*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Non futex case isn't supported.";
1021*795d594fSAndroid Build Coastguard Worker #endif
1022*795d594fSAndroid Build Coastguard Worker }
1023*795d594fSAndroid Build Coastguard Worker
ConditionVariable(const char * name,Mutex & guard)1024*795d594fSAndroid Build Coastguard Worker ConditionVariable::ConditionVariable(const char* name, Mutex& guard)
1025*795d594fSAndroid Build Coastguard Worker : name_(name), guard_(guard) {
1026*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1027*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(0, sequence_.load(std::memory_order_relaxed));
1028*795d594fSAndroid Build Coastguard Worker num_waiters_ = 0;
1029*795d594fSAndroid Build Coastguard Worker #else
1030*795d594fSAndroid Build Coastguard Worker pthread_condattr_t cond_attrs;
1031*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_condattr_init, (&cond_attrs));
1032*795d594fSAndroid Build Coastguard Worker #if !defined(__APPLE__)
1033*795d594fSAndroid Build Coastguard Worker // Apple doesn't have CLOCK_MONOTONIC or pthread_condattr_setclock.
1034*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_condattr_setclock, (&cond_attrs, CLOCK_MONOTONIC));
1035*795d594fSAndroid Build Coastguard Worker #endif
1036*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_cond_init, (&cond_, &cond_attrs));
1037*795d594fSAndroid Build Coastguard Worker #endif
1038*795d594fSAndroid Build Coastguard Worker }
1039*795d594fSAndroid Build Coastguard Worker
~ConditionVariable()1040*795d594fSAndroid Build Coastguard Worker ConditionVariable::~ConditionVariable() {
1041*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1042*795d594fSAndroid Build Coastguard Worker if (num_waiters_!= 0) {
1043*795d594fSAndroid Build Coastguard Worker bool is_safe_to_call_abort = IsSafeToCallAbortSafe();
1044*795d594fSAndroid Build Coastguard Worker LOG(is_safe_to_call_abort ? FATAL : WARNING)
1045*795d594fSAndroid Build Coastguard Worker << "ConditionVariable::~ConditionVariable for " << name_
1046*795d594fSAndroid Build Coastguard Worker << " called with " << num_waiters_ << " waiters.";
1047*795d594fSAndroid Build Coastguard Worker }
1048*795d594fSAndroid Build Coastguard Worker #else
1049*795d594fSAndroid Build Coastguard Worker // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread
1050*795d594fSAndroid Build Coastguard Worker // may still be using condition variables.
1051*795d594fSAndroid Build Coastguard Worker int rc = pthread_cond_destroy(&cond_);
1052*795d594fSAndroid Build Coastguard Worker if (rc != 0) {
1053*795d594fSAndroid Build Coastguard Worker errno = rc;
1054*795d594fSAndroid Build Coastguard Worker bool is_safe_to_call_abort = IsSafeToCallAbortSafe();
1055*795d594fSAndroid Build Coastguard Worker PLOG(is_safe_to_call_abort ? FATAL : WARNING) << "pthread_cond_destroy failed for " << name_;
1056*795d594fSAndroid Build Coastguard Worker }
1057*795d594fSAndroid Build Coastguard Worker #endif
1058*795d594fSAndroid Build Coastguard Worker }
1059*795d594fSAndroid Build Coastguard Worker
Broadcast(Thread * self)1060*795d594fSAndroid Build Coastguard Worker void ConditionVariable::Broadcast(Thread* self) {
1061*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
1062*795d594fSAndroid Build Coastguard Worker // TODO: enable below, there's a race in thread creation that causes false failures currently.
1063*795d594fSAndroid Build Coastguard Worker // guard_.AssertExclusiveHeld(self);
1064*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(guard_.GetExclusiveOwnerTid(), SafeGetTid(self));
1065*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1066*795d594fSAndroid Build Coastguard Worker RequeueWaiters(std::numeric_limits<int32_t>::max());
1067*795d594fSAndroid Build Coastguard Worker #else
1068*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_cond_broadcast, (&cond_));
1069*795d594fSAndroid Build Coastguard Worker #endif
1070*795d594fSAndroid Build Coastguard Worker }
1071*795d594fSAndroid Build Coastguard Worker
1072*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
RequeueWaiters(int32_t count)1073*795d594fSAndroid Build Coastguard Worker void ConditionVariable::RequeueWaiters(int32_t count) {
1074*795d594fSAndroid Build Coastguard Worker if (num_waiters_ > 0) {
1075*795d594fSAndroid Build Coastguard Worker sequence_++; // Indicate a signal occurred.
1076*795d594fSAndroid Build Coastguard Worker // Move waiters from the condition variable's futex to the guard's futex,
1077*795d594fSAndroid Build Coastguard Worker // so that they will be woken up when the mutex is released.
1078*795d594fSAndroid Build Coastguard Worker bool done = futex(sequence_.Address(),
1079*795d594fSAndroid Build Coastguard Worker FUTEX_REQUEUE_PRIVATE,
1080*795d594fSAndroid Build Coastguard Worker /* Threads to wake */ 0,
1081*795d594fSAndroid Build Coastguard Worker /* Threads to requeue*/ reinterpret_cast<const timespec*>(count),
1082*795d594fSAndroid Build Coastguard Worker guard_.state_and_contenders_.Address(),
1083*795d594fSAndroid Build Coastguard Worker 0) != -1;
1084*795d594fSAndroid Build Coastguard Worker if (!done && errno != EAGAIN && errno != EINTR) {
1085*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "futex requeue failed for " << name_;
1086*795d594fSAndroid Build Coastguard Worker }
1087*795d594fSAndroid Build Coastguard Worker }
1088*795d594fSAndroid Build Coastguard Worker }
1089*795d594fSAndroid Build Coastguard Worker #endif
1090*795d594fSAndroid Build Coastguard Worker
1091*795d594fSAndroid Build Coastguard Worker
Signal(Thread * self)1092*795d594fSAndroid Build Coastguard Worker void ConditionVariable::Signal(Thread* self) {
1093*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
1094*795d594fSAndroid Build Coastguard Worker guard_.AssertExclusiveHeld(self);
1095*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1096*795d594fSAndroid Build Coastguard Worker RequeueWaiters(1);
1097*795d594fSAndroid Build Coastguard Worker #else
1098*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_cond_signal, (&cond_));
1099*795d594fSAndroid Build Coastguard Worker #endif
1100*795d594fSAndroid Build Coastguard Worker }
1101*795d594fSAndroid Build Coastguard Worker
Wait(Thread * self)1102*795d594fSAndroid Build Coastguard Worker void ConditionVariable::Wait(Thread* self) {
1103*795d594fSAndroid Build Coastguard Worker guard_.CheckSafeToWait(self);
1104*795d594fSAndroid Build Coastguard Worker WaitHoldingLocks(self);
1105*795d594fSAndroid Build Coastguard Worker }
1106*795d594fSAndroid Build Coastguard Worker
WaitHoldingLocks(Thread * self)1107*795d594fSAndroid Build Coastguard Worker void ConditionVariable::WaitHoldingLocks(Thread* self) {
1108*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
1109*795d594fSAndroid Build Coastguard Worker guard_.AssertExclusiveHeld(self);
1110*795d594fSAndroid Build Coastguard Worker unsigned int old_recursion_count = guard_.recursion_count_;
1111*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1112*795d594fSAndroid Build Coastguard Worker num_waiters_++;
1113*795d594fSAndroid Build Coastguard Worker // Ensure the Mutex is contended so that requeued threads are awoken.
1114*795d594fSAndroid Build Coastguard Worker guard_.increment_contenders();
1115*795d594fSAndroid Build Coastguard Worker guard_.recursion_count_ = 1;
1116*795d594fSAndroid Build Coastguard Worker int32_t cur_sequence = sequence_.load(std::memory_order_relaxed);
1117*795d594fSAndroid Build Coastguard Worker guard_.ExclusiveUnlock(self);
1118*795d594fSAndroid Build Coastguard Worker if (futex(sequence_.Address(), FUTEX_WAIT_PRIVATE, cur_sequence, nullptr, nullptr, 0) != 0) {
1119*795d594fSAndroid Build Coastguard Worker // Futex failed, check it is an expected error.
1120*795d594fSAndroid Build Coastguard Worker // EAGAIN == EWOULDBLK, so we let the caller try again.
1121*795d594fSAndroid Build Coastguard Worker // EINTR implies a signal was sent to this thread.
1122*795d594fSAndroid Build Coastguard Worker if ((errno != EINTR) && (errno != EAGAIN)) {
1123*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "futex wait failed for " << name_;
1124*795d594fSAndroid Build Coastguard Worker }
1125*795d594fSAndroid Build Coastguard Worker }
1126*795d594fSAndroid Build Coastguard Worker SleepIfRuntimeDeleted(self);
1127*795d594fSAndroid Build Coastguard Worker guard_.ExclusiveLock(self);
1128*795d594fSAndroid Build Coastguard Worker CHECK_GT(num_waiters_, 0);
1129*795d594fSAndroid Build Coastguard Worker num_waiters_--;
1130*795d594fSAndroid Build Coastguard Worker // We awoke and so no longer require awakes from the guard_'s unlock.
1131*795d594fSAndroid Build Coastguard Worker CHECK_GT(guard_.get_contenders(), 0);
1132*795d594fSAndroid Build Coastguard Worker guard_.decrement_contenders();
1133*795d594fSAndroid Build Coastguard Worker #else
1134*795d594fSAndroid Build Coastguard Worker pid_t old_owner = guard_.GetExclusiveOwnerTid();
1135*795d594fSAndroid Build Coastguard Worker guard_.exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
1136*795d594fSAndroid Build Coastguard Worker guard_.recursion_count_ = 0;
1137*795d594fSAndroid Build Coastguard Worker CHECK_MUTEX_CALL(pthread_cond_wait, (&cond_, &guard_.mutex_));
1138*795d594fSAndroid Build Coastguard Worker guard_.exclusive_owner_.store(old_owner, std::memory_order_relaxed);
1139*795d594fSAndroid Build Coastguard Worker #endif
1140*795d594fSAndroid Build Coastguard Worker guard_.recursion_count_ = old_recursion_count;
1141*795d594fSAndroid Build Coastguard Worker }
1142*795d594fSAndroid Build Coastguard Worker
TimedWait(Thread * self,int64_t ms,int32_t ns)1143*795d594fSAndroid Build Coastguard Worker bool ConditionVariable::TimedWait(Thread* self, int64_t ms, int32_t ns) {
1144*795d594fSAndroid Build Coastguard Worker DCHECK(self == nullptr || self == Thread::Current());
1145*795d594fSAndroid Build Coastguard Worker bool timed_out = false;
1146*795d594fSAndroid Build Coastguard Worker guard_.AssertExclusiveHeld(self);
1147*795d594fSAndroid Build Coastguard Worker guard_.CheckSafeToWait(self);
1148*795d594fSAndroid Build Coastguard Worker unsigned int old_recursion_count = guard_.recursion_count_;
1149*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES
1150*795d594fSAndroid Build Coastguard Worker timespec rel_ts;
1151*795d594fSAndroid Build Coastguard Worker InitTimeSpec(false, CLOCK_REALTIME, ms, ns, &rel_ts);
1152*795d594fSAndroid Build Coastguard Worker num_waiters_++;
1153*795d594fSAndroid Build Coastguard Worker // Ensure the Mutex is contended so that requeued threads are awoken.
1154*795d594fSAndroid Build Coastguard Worker guard_.increment_contenders();
1155*795d594fSAndroid Build Coastguard Worker guard_.recursion_count_ = 1;
1156*795d594fSAndroid Build Coastguard Worker int32_t cur_sequence = sequence_.load(std::memory_order_relaxed);
1157*795d594fSAndroid Build Coastguard Worker guard_.ExclusiveUnlock(self);
1158*795d594fSAndroid Build Coastguard Worker if (futex(sequence_.Address(), FUTEX_WAIT_PRIVATE, cur_sequence, &rel_ts, nullptr, 0) != 0) {
1159*795d594fSAndroid Build Coastguard Worker if (errno == ETIMEDOUT) {
1160*795d594fSAndroid Build Coastguard Worker // Timed out we're done.
1161*795d594fSAndroid Build Coastguard Worker timed_out = true;
1162*795d594fSAndroid Build Coastguard Worker } else if ((errno == EAGAIN) || (errno == EINTR)) {
1163*795d594fSAndroid Build Coastguard Worker // A signal or ConditionVariable::Signal/Broadcast has come in.
1164*795d594fSAndroid Build Coastguard Worker } else {
1165*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "timed futex wait failed for " << name_;
1166*795d594fSAndroid Build Coastguard Worker }
1167*795d594fSAndroid Build Coastguard Worker }
1168*795d594fSAndroid Build Coastguard Worker SleepIfRuntimeDeleted(self);
1169*795d594fSAndroid Build Coastguard Worker guard_.ExclusiveLock(self);
1170*795d594fSAndroid Build Coastguard Worker CHECK_GT(num_waiters_, 0);
1171*795d594fSAndroid Build Coastguard Worker num_waiters_--;
1172*795d594fSAndroid Build Coastguard Worker // We awoke and so no longer require awakes from the guard_'s unlock.
1173*795d594fSAndroid Build Coastguard Worker CHECK_GT(guard_.get_contenders(), 0);
1174*795d594fSAndroid Build Coastguard Worker guard_.decrement_contenders();
1175*795d594fSAndroid Build Coastguard Worker #else
1176*795d594fSAndroid Build Coastguard Worker #if !defined(__APPLE__)
1177*795d594fSAndroid Build Coastguard Worker int clock = CLOCK_MONOTONIC;
1178*795d594fSAndroid Build Coastguard Worker #else
1179*795d594fSAndroid Build Coastguard Worker int clock = CLOCK_REALTIME;
1180*795d594fSAndroid Build Coastguard Worker #endif
1181*795d594fSAndroid Build Coastguard Worker pid_t old_owner = guard_.GetExclusiveOwnerTid();
1182*795d594fSAndroid Build Coastguard Worker guard_.exclusive_owner_.store(0 /* pid */, std::memory_order_relaxed);
1183*795d594fSAndroid Build Coastguard Worker guard_.recursion_count_ = 0;
1184*795d594fSAndroid Build Coastguard Worker timespec ts;
1185*795d594fSAndroid Build Coastguard Worker InitTimeSpec(true, clock, ms, ns, &ts);
1186*795d594fSAndroid Build Coastguard Worker int rc;
1187*795d594fSAndroid Build Coastguard Worker while ((rc = pthread_cond_timedwait(&cond_, &guard_.mutex_, &ts)) == EINTR) {
1188*795d594fSAndroid Build Coastguard Worker continue;
1189*795d594fSAndroid Build Coastguard Worker }
1190*795d594fSAndroid Build Coastguard Worker
1191*795d594fSAndroid Build Coastguard Worker if (rc == ETIMEDOUT) {
1192*795d594fSAndroid Build Coastguard Worker timed_out = true;
1193*795d594fSAndroid Build Coastguard Worker } else if (rc != 0) {
1194*795d594fSAndroid Build Coastguard Worker errno = rc;
1195*795d594fSAndroid Build Coastguard Worker PLOG(FATAL) << "TimedWait failed for " << name_;
1196*795d594fSAndroid Build Coastguard Worker }
1197*795d594fSAndroid Build Coastguard Worker guard_.exclusive_owner_.store(old_owner, std::memory_order_relaxed);
1198*795d594fSAndroid Build Coastguard Worker #endif
1199*795d594fSAndroid Build Coastguard Worker guard_.recursion_count_ = old_recursion_count;
1200*795d594fSAndroid Build Coastguard Worker return timed_out;
1201*795d594fSAndroid Build Coastguard Worker }
1202*795d594fSAndroid Build Coastguard Worker
1203*795d594fSAndroid Build Coastguard Worker } // namespace art
1204