xref: /aosp_15_r20/art/runtime/base/mutex.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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