summaryrefslogtreecommitdiff
path: root/runtime/thread-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/thread-inl.h')
-rw-r--r--runtime/thread-inl.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index d75a788e96..6c3811b8e5 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -312,6 +312,37 @@ inline void Thread::PoisonObjectPointersIfDebug() {
}
}
+inline bool Thread::ModifySuspendCount(Thread* self,
+ int delta,
+ AtomicInteger* suspend_barrier,
+ bool for_debugger) {
+ if (delta > 0 && ((kUseReadBarrier && this != self) || suspend_barrier != nullptr)) {
+ // When delta > 0 (requesting a suspend), ModifySuspendCountInternal() may fail either if
+ // active_suspend_barriers is full or we are in the middle of a thread flip. Retry in a loop.
+ while (true) {
+ if (LIKELY(ModifySuspendCountInternal(self, delta, suspend_barrier, for_debugger))) {
+ return true;
+ } else {
+ // Failure means the list of active_suspend_barriers is full or we are in the middle of a
+ // thread flip, we should release the thread_suspend_count_lock_ (to avoid deadlock) and
+ // wait till the target thread has executed or Thread::PassActiveSuspendBarriers() or the
+ // flip function. Note that we could not simply wait for the thread to change to a suspended
+ // state, because it might need to run checkpoint function before the state change or
+ // resumes from the resume_cond_, which also needs thread_suspend_count_lock_.
+ //
+ // The list of active_suspend_barriers is very unlikely to be full since more than
+ // kMaxSuspendBarriers threads need to execute SuspendAllInternal() simultaneously, and
+ // target thread stays in kRunnable in the mean time.
+ Locks::thread_suspend_count_lock_->ExclusiveUnlock(self);
+ NanoSleep(100000);
+ Locks::thread_suspend_count_lock_->ExclusiveLock(self);
+ }
+ }
+ } else {
+ return ModifySuspendCountInternal(self, delta, suspend_barrier, for_debugger);
+ }
+}
+
} // namespace art
#endif // ART_RUNTIME_THREAD_INL_H_