diff options
-rw-r--r-- | runtime/Android.bp | 1 | ||||
-rw-r--r-- | runtime/debugger.cc | 10 | ||||
-rw-r--r-- | runtime/monitor.cc | 6 | ||||
-rw-r--r-- | runtime/native/dalvik_system_VMStack.cc | 7 | ||||
-rw-r--r-- | runtime/native/java_lang_Thread.cc | 7 | ||||
-rw-r--r-- | runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc | 6 | ||||
-rw-r--r-- | runtime/openjdkjvm/OpenjdkJvm.cc | 7 | ||||
-rw-r--r-- | runtime/suspend_reason.h | 37 | ||||
-rw-r--r-- | runtime/thread-inl.h | 6 | ||||
-rw-r--r-- | runtime/thread.cc | 16 | ||||
-rw-r--r-- | runtime/thread.h | 5 | ||||
-rw-r--r-- | runtime/thread_list.cc | 57 | ||||
-rw-r--r-- | runtime/thread_list.h | 11 |
13 files changed, 117 insertions, 59 deletions
diff --git a/runtime/Android.bp b/runtime/Android.bp index 46307ddde8..0dfc60d88a 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -461,6 +461,7 @@ gensrcs { "object_callbacks.h", "process_state.h", "stack.h", + "suspend_reason.h", "thread.h", "thread_state.h", "ti/agent.h", diff --git a/runtime/debugger.cc b/runtime/debugger.cc index cc12439074..c94a8e0f3e 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -2446,7 +2446,7 @@ JDWP::JdwpError Dbg::SuspendThread(JDWP::ObjectId thread_id, bool request_suspen ThreadList* thread_list = Runtime::Current()->GetThreadList(); Thread* thread = thread_list->SuspendThreadByPeer(peer.get(), request_suspension, - /* debug_suspension */ true, + SuspendReason::kForDebugger, &timed_out); if (thread != nullptr) { return JDWP::ERR_NONE; @@ -2477,7 +2477,7 @@ void Dbg::ResumeThread(JDWP::ObjectId thread_id) { needs_resume = thread->GetDebugSuspendCount() > 0; } if (needs_resume) { - Runtime::Current()->GetThreadList()->Resume(thread, true); + Runtime::Current()->GetThreadList()->Resume(thread, SuspendReason::kForDebugger); } } @@ -3694,7 +3694,7 @@ class ScopedDebuggerThreadSuspension { ThreadList* const thread_list = Runtime::Current()->GetThreadList(); suspended_thread = thread_list->SuspendThreadByPeer(thread_peer, /* request_suspension */ true, - /* debug_suspension */ true, + SuspendReason::kForDebugger, &timed_out); } if (suspended_thread == nullptr) { @@ -3718,7 +3718,7 @@ class ScopedDebuggerThreadSuspension { ~ScopedDebuggerThreadSuspension() { if (other_suspend_) { - Runtime::Current()->GetThreadList()->Resume(thread_, true); + Runtime::Current()->GetThreadList()->Resume(thread_, SuspendReason::kForDebugger); } } @@ -4040,7 +4040,7 @@ JDWP::JdwpError Dbg::PrepareInvokeMethod(uint32_t request_id, JDWP::ObjectId thr thread_list->UndoDebuggerSuspensions(); } else { VLOG(jdwp) << " Resuming event thread only"; - thread_list->Resume(targetThread, true); + thread_list->Resume(targetThread, SuspendReason::kForDebugger); } return JDWP::ERR_NONE; diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 940afc8448..3e3eaae13a 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -898,7 +898,9 @@ void Monitor::InflateThinLocked(Thread* self, Handle<mirror::Object> obj, LockWo Thread* owner; { ScopedThreadSuspension sts(self, kBlocked); - owner = thread_list->SuspendThreadByThreadId(owner_thread_id, false, &timed_out); + owner = thread_list->SuspendThreadByThreadId(owner_thread_id, + SuspendReason::kInternal, + &timed_out); } if (owner != nullptr) { // We succeeded in suspending the thread, check the lock's status didn't change. @@ -908,7 +910,7 @@ void Monitor::InflateThinLocked(Thread* self, Handle<mirror::Object> obj, LockWo // Go ahead and inflate the lock. Inflate(self, owner, obj.Get(), hash_code); } - thread_list->Resume(owner, false); + thread_list->Resume(owner, SuspendReason::kInternal); } self->SetMonitorEnterObject(nullptr); } diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc index e86e64ed6a..7d2d0e5bb9 100644 --- a/runtime/native/dalvik_system_VMStack.cc +++ b/runtime/native/dalvik_system_VMStack.cc @@ -51,7 +51,10 @@ static jobject GetThreadStack(const ScopedFastNativeObjectAccess& soa, jobject p ScopedThreadSuspension sts(soa.Self(), kNative); ThreadList* thread_list = Runtime::Current()->GetThreadList(); bool timed_out; - Thread* thread = thread_list->SuspendThreadByPeer(peer, true, false, &timed_out); + Thread* thread = thread_list->SuspendThreadByPeer(peer, + /* request_suspension */ true, + SuspendReason::kInternal, + &timed_out); if (thread != nullptr) { // Must be runnable to create returned array. { @@ -59,7 +62,7 @@ static jobject GetThreadStack(const ScopedFastNativeObjectAccess& soa, jobject p trace = thread->CreateInternalStackTrace<false>(soa); } // Restart suspended thread. - thread_list->Resume(thread, false); + thread_list->Resume(thread, SuspendReason::kInternal); } else if (timed_out) { LOG(ERROR) << "Trying to get thread's stack failed as the thread failed to suspend within a " "generous timeout."; diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc index e4d1705d28..8b76327fa8 100644 --- a/runtime/native/java_lang_Thread.cc +++ b/runtime/native/java_lang_Thread.cc @@ -146,13 +146,16 @@ static void Thread_nativeSetName(JNIEnv* env, jobject peer, jstring java_name) { ThreadList* thread_list = Runtime::Current()->GetThreadList(); bool timed_out; // Take suspend thread lock to avoid races with threads trying to suspend this one. - Thread* thread = thread_list->SuspendThreadByPeer(peer, true, false, &timed_out); + Thread* thread = thread_list->SuspendThreadByPeer(peer, + /* request_suspension */ true, + SuspendReason::kInternal, + &timed_out); if (thread != nullptr) { { ScopedObjectAccess soa(env); thread->SetThreadName(name.c_str()); } - thread_list->Resume(thread, false); + thread_list->Resume(thread, SuspendReason::kInternal); } else if (timed_out) { LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread " "failed to suspend within a generous timeout."; diff --git a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc index 0a254aca54..c516b66d93 100644 --- a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc +++ b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc @@ -66,7 +66,9 @@ static jobjectArray DdmVmInternal_getStackTraceById(JNIEnv* env, jclass, jint th } // Suspend thread to build stack trace. - Thread* thread = thread_list->SuspendThreadByThreadId(thin_lock_id, false, &timed_out); + Thread* thread = thread_list->SuspendThreadByThreadId(thin_lock_id, + SuspendReason::kInternal, + &timed_out); if (thread != nullptr) { { ScopedObjectAccess soa(env); @@ -74,7 +76,7 @@ static jobjectArray DdmVmInternal_getStackTraceById(JNIEnv* env, jclass, jint th trace = Thread::InternalStackTraceToStackTraceElementArray(soa, internal_trace); } // Restart suspended thread. - thread_list->Resume(thread, false); + thread_list->Resume(thread, SuspendReason::kInternal); } else { if (timed_out) { LOG(ERROR) << "Trying to get thread's stack by id failed as the thread failed to suspend " diff --git a/runtime/openjdkjvm/OpenjdkJvm.cc b/runtime/openjdkjvm/OpenjdkJvm.cc index 0b93b079d5..4560dda4dd 100644 --- a/runtime/openjdkjvm/OpenjdkJvm.cc +++ b/runtime/openjdkjvm/OpenjdkJvm.cc @@ -422,14 +422,17 @@ JNIEXPORT void JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring jav // Take suspend thread lock to avoid races with threads trying to suspend this one. art::Thread* thread; { - thread = thread_list->SuspendThreadByPeer(jthread, true, false, &timed_out); + thread = thread_list->SuspendThreadByPeer(jthread, + true, + art::SuspendReason::kInternal, + &timed_out); } if (thread != NULL) { { art::ScopedObjectAccess soa(env); thread->SetThreadName(name.c_str()); } - thread_list->Resume(thread, false); + thread_list->Resume(thread, art::SuspendReason::kInternal); } else if (timed_out) { LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread " "failed to suspend within a generous timeout."; diff --git a/runtime/suspend_reason.h b/runtime/suspend_reason.h new file mode 100644 index 0000000000..27c4d3207b --- /dev/null +++ b/runtime/suspend_reason.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_SUSPEND_REASON_H_ +#define ART_RUNTIME_SUSPEND_REASON_H_ + +#include <ostream> + +namespace art { + +// The various reasons that we might be suspending a thread. +enum class SuspendReason { + // Suspending for internal reasons (e.g. GC, stack trace, etc.). + // TODO Split this into more descriptive sections. + kInternal, + // Suspending for debugger (code in Dbg::*, runtime/jdwp/, etc.). + kForDebugger, +}; + +std::ostream& operator<<(std::ostream& os, const SuspendReason& thread); + +} // namespace art + +#endif // ART_RUNTIME_SUSPEND_REASON_H_ diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h index 7da15d9f4c..95608b5f63 100644 --- a/runtime/thread-inl.h +++ b/runtime/thread-inl.h @@ -330,12 +330,12 @@ inline void Thread::PoisonObjectPointersIfDebug() { inline bool Thread::ModifySuspendCount(Thread* self, int delta, AtomicInteger* suspend_barrier, - bool for_debugger) { + SuspendReason reason) { 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))) { + if (LIKELY(ModifySuspendCountInternal(self, delta, suspend_barrier, reason))) { return true; } else { // Failure means the list of active_suspend_barriers is full or we are in the middle of a @@ -354,7 +354,7 @@ inline bool Thread::ModifySuspendCount(Thread* self, } } } else { - return ModifySuspendCountInternal(self, delta, suspend_barrier, for_debugger); + return ModifySuspendCountInternal(self, delta, suspend_barrier, reason); } } diff --git a/runtime/thread.cc b/runtime/thread.cc index be1614b3cc..a81166640a 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -1178,10 +1178,10 @@ static void UnsafeLogFatalForSuspendCount(Thread* self, Thread* thread) NO_THREA bool Thread::ModifySuspendCountInternal(Thread* self, int delta, AtomicInteger* suspend_barrier, - bool for_debugger) { + SuspendReason reason) { if (kIsDebugBuild) { DCHECK(delta == -1 || delta == +1 || delta == -tls32_.debug_suspend_count) - << delta << " " << tls32_.debug_suspend_count << " " << this; + << reason << " " << delta << " " << tls32_.debug_suspend_count << " " << this; DCHECK_GE(tls32_.suspend_count, tls32_.debug_suspend_count) << this; Locks::thread_suspend_count_lock_->AssertHeld(self); if (this != self && !IsSuspended()) { @@ -1217,8 +1217,12 @@ bool Thread::ModifySuspendCountInternal(Thread* self, } tls32_.suspend_count += delta; - if (for_debugger) { - tls32_.debug_suspend_count += delta; + switch (reason) { + case SuspendReason::kForDebugger: + tls32_.debug_suspend_count += delta; + break; + case SuspendReason::kInternal: + break; } if (tls32_.suspend_count == 0) { @@ -1458,7 +1462,7 @@ bool Thread::RequestSynchronousCheckpoint(Closure* function) { { MutexLock mu2(self, *Locks::thread_suspend_count_lock_); - if (!ModifySuspendCount(self, +1, nullptr, false)) { + if (!ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal)) { // Just retry the loop. sched_yield(); continue; @@ -1483,7 +1487,7 @@ bool Thread::RequestSynchronousCheckpoint(Closure* function) { MutexLock mu2(self, *Locks::thread_suspend_count_lock_); DCHECK_NE(GetState(), ThreadState::kRunnable); - bool updated = ModifySuspendCount(self, -1, nullptr, false); + bool updated = ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(updated); } diff --git a/runtime/thread.h b/runtime/thread.h index 770173e47e..e785ddc803 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -40,6 +40,7 @@ #include "managed_stack.h" #include "offsets.h" #include "runtime_stats.h" +#include "suspend_reason.h" #include "thread_state.h" class BacktraceMap; @@ -244,7 +245,7 @@ class Thread { bool ModifySuspendCount(Thread* self, int delta, AtomicInteger* suspend_barrier, - bool for_debugger) + SuspendReason reason) WARN_UNUSED REQUIRES(Locks::thread_suspend_count_lock_); @@ -1300,7 +1301,7 @@ class Thread { bool ModifySuspendCountInternal(Thread* self, int delta, AtomicInteger* suspend_barrier, - bool for_debugger) + SuspendReason reason) WARN_UNUSED REQUIRES(Locks::thread_suspend_count_lock_); diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 95aba79ed7..fc767ed899 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -332,7 +332,7 @@ size_t ThreadList::RunCheckpoint(Closure* checkpoint_function, Closure* callback // Spurious fail, try again. continue; } - bool updated = thread->ModifySuspendCount(self, +1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal); DCHECK(updated); suspended_count_modified_threads.push_back(thread); break; @@ -375,7 +375,7 @@ size_t ThreadList::RunCheckpoint(Closure* checkpoint_function, Closure* callback checkpoint_function->Run(thread); { MutexLock mu2(self, *Locks::thread_suspend_count_lock_); - bool updated = thread->ModifySuspendCount(self, -1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(updated); } } @@ -583,7 +583,7 @@ size_t ThreadList::FlipThreadRoots(Closure* thread_flip_visitor, if ((state == kWaitingForGcThreadFlip || thread->IsTransitioningToRunnable()) && thread->GetSuspendCount() == 1) { // The thread will resume right after the broadcast. - bool updated = thread->ModifySuspendCount(self, -1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(updated); ++runnable_thread_count; } else { @@ -617,7 +617,7 @@ size_t ThreadList::FlipThreadRoots(Closure* thread_flip_visitor, TimingLogger::ScopedTiming split4("ResumeOtherThreads", collector->GetTimings()); MutexLock mu2(self, *Locks::thread_suspend_count_lock_); for (const auto& thread : other_threads) { - bool updated = thread->ModifySuspendCount(self, -1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(updated); } Thread::resume_cond_->Broadcast(self); @@ -688,7 +688,7 @@ void ThreadList::SuspendAll(const char* cause, bool long_suspend) { void ThreadList::SuspendAllInternal(Thread* self, Thread* ignore1, Thread* ignore2, - bool debug_suspend) { + SuspendReason reason) { Locks::mutator_lock_->AssertNotExclusiveHeld(self); Locks::thread_list_lock_->AssertNotHeld(self); Locks::thread_suspend_count_lock_->AssertNotHeld(self); @@ -718,7 +718,7 @@ void ThreadList::SuspendAllInternal(Thread* self, MutexLock mu2(self, *Locks::thread_suspend_count_lock_); // Update global suspend all state for attaching threads. ++suspend_all_count_; - if (debug_suspend) { + if (reason == SuspendReason::kForDebugger) { ++debug_suspend_all_count_; } pending_threads.StoreRelaxed(list_.size() - num_ignored); @@ -728,7 +728,7 @@ void ThreadList::SuspendAllInternal(Thread* self, continue; } VLOG(threads) << "requesting thread suspend: " << *thread; - bool updated = thread->ModifySuspendCount(self, +1, &pending_threads, debug_suspend); + bool updated = thread->ModifySuspendCount(self, +1, &pending_threads, reason); DCHECK(updated); // Must install the pending_threads counter first, then check thread->IsSuspend() and clear @@ -807,7 +807,7 @@ void ThreadList::ResumeAll() { if (thread == self) { continue; } - bool updated = thread->ModifySuspendCount(self, -1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(updated); } @@ -828,14 +828,13 @@ void ThreadList::ResumeAll() { } } -void ThreadList::Resume(Thread* thread, bool for_debugger) { +void ThreadList::Resume(Thread* thread, SuspendReason reason) { // This assumes there was an ATRACE_BEGIN when we suspended the thread. ATRACE_END(); Thread* self = Thread::Current(); DCHECK_NE(thread, self); - VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") starting..." - << (for_debugger ? " (debugger)" : ""); + VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") starting..." << reason; { // To check Contains. @@ -850,7 +849,7 @@ void ThreadList::Resume(Thread* thread, bool for_debugger) { << ") thread not within thread list"; return; } - bool updated = thread->ModifySuspendCount(self, -1, nullptr, for_debugger); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, reason); DCHECK(updated); } @@ -882,7 +881,7 @@ static void ThreadSuspendByPeerWarning(Thread* self, Thread* ThreadList::SuspendThreadByPeer(jobject peer, bool request_suspension, - bool debug_suspension, + SuspendReason reason, bool* timed_out) { const uint64_t start_time = NanoTime(); useconds_t sleep_us = kThreadSuspendInitialSleepUs; @@ -910,7 +909,7 @@ Thread* ThreadList::SuspendThreadByPeer(jobject peer, bool updated = suspended_thread->ModifySuspendCount(soa.Self(), -1, nullptr, - debug_suspension); + reason); DCHECK(updated); } ThreadSuspendByPeerWarning(self, @@ -937,7 +936,7 @@ Thread* ThreadList::SuspendThreadByPeer(jobject peer, } CHECK(suspended_thread == nullptr); suspended_thread = thread; - bool updated = suspended_thread->ModifySuspendCount(self, +1, nullptr, debug_suspension); + bool updated = suspended_thread->ModifySuspendCount(self, +1, nullptr, reason); DCHECK(updated); request_suspension = false; } else { @@ -973,7 +972,7 @@ Thread* ThreadList::SuspendThreadByPeer(jobject peer, bool updated = suspended_thread->ModifySuspendCount(soa.Self(), -1, nullptr, - debug_suspension); + reason); DCHECK(updated); } *timed_out = true; @@ -1002,7 +1001,7 @@ static void ThreadSuspendByThreadIdWarning(LogSeverity severity, } Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id, - bool debug_suspension, + SuspendReason reason, bool* timed_out) { const uint64_t start_time = NanoTime(); useconds_t sleep_us = kThreadSuspendInitialSleepUs; @@ -1047,7 +1046,7 @@ Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id, // which will allow this thread to be suspended. continue; } - bool updated = thread->ModifySuspendCount(self, +1, nullptr, debug_suspension); + bool updated = thread->ModifySuspendCount(self, +1, nullptr, reason); DCHECK(updated); suspended_thread = thread; } else { @@ -1079,7 +1078,7 @@ Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id, "Thread suspension timed out", thread_id); if (suspended_thread != nullptr) { - bool updated = thread->ModifySuspendCount(soa.Self(), -1, nullptr, debug_suspension); + bool updated = thread->ModifySuspendCount(soa.Self(), -1, nullptr, reason); DCHECK(updated); } *timed_out = true; @@ -1114,7 +1113,7 @@ void ThreadList::SuspendAllForDebugger() { VLOG(threads) << *self << " SuspendAllForDebugger starting..."; - SuspendAllInternal(self, self, debug_thread, true); + SuspendAllInternal(self, self, debug_thread, SuspendReason::kForDebugger); // Block on the mutator lock until all Runnable threads release their share of access then // immediately unlock again. #if HAVE_TIMED_RWLOCK @@ -1157,7 +1156,7 @@ void ThreadList::SuspendSelfForDebugger() { // to ensure that we're the only one fiddling with the suspend count // though. MutexLock mu(self, *Locks::thread_suspend_count_lock_); - bool updated = self->ModifySuspendCount(self, +1, nullptr, true); + bool updated = self->ModifySuspendCount(self, +1, nullptr, SuspendReason::kForDebugger); DCHECK(updated); CHECK_GT(self->GetSuspendCount(), 0); @@ -1242,7 +1241,7 @@ void ThreadList::ResumeAllForDebugger() { continue; } VLOG(threads) << "requesting thread resume: " << *thread; - bool updated = thread->ModifySuspendCount(self, -1, nullptr, true); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kForDebugger); DCHECK(updated); } } @@ -1275,7 +1274,7 @@ void ThreadList::UndoDebuggerSuspensions() { bool suspended = thread->ModifySuspendCount(self, -thread->GetDebugSuspendCount(), nullptr, - true); + SuspendReason::kForDebugger); DCHECK(suspended); } } @@ -1333,7 +1332,7 @@ void ThreadList::SuspendAllDaemonThreadsForShutdown() { // daemons. CHECK(thread->IsDaemon()) << *thread; if (thread != self) { - bool updated = thread->ModifySuspendCount(self, +1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal); DCHECK(updated); ++daemons_left; } @@ -1394,11 +1393,11 @@ void ThreadList::Register(Thread* self) { // Modify suspend count in increments of 1 to maintain invariants in ModifySuspendCount. While // this isn't particularly efficient the suspend counts are most commonly 0 or 1. for (int delta = debug_suspend_all_count_; delta > 0; delta--) { - bool updated = self->ModifySuspendCount(self, +1, nullptr, true); + bool updated = self->ModifySuspendCount(self, +1, nullptr, SuspendReason::kForDebugger); DCHECK(updated); } for (int delta = suspend_all_count_ - debug_suspend_all_count_; delta > 0; delta--) { - bool updated = self->ModifySuspendCount(self, +1, nullptr, false); + bool updated = self->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal); DCHECK(updated); } CHECK(!Contains(self)); @@ -1495,12 +1494,12 @@ void ThreadList::VisitRootsForSuspendedThreads(RootVisitor* visitor) { MutexLock mu(self, *Locks::thread_list_lock_); MutexLock mu2(self, *Locks::thread_suspend_count_lock_); for (Thread* thread : list_) { - bool suspended = thread->ModifySuspendCount(self, +1, nullptr, false); + bool suspended = thread->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal); DCHECK(suspended); if (thread == self || thread->IsSuspended()) { threads_to_visit.push_back(thread); } else { - bool resumed = thread->ModifySuspendCount(self, -1, nullptr, false); + bool resumed = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(resumed); } } @@ -1516,7 +1515,7 @@ void ThreadList::VisitRootsForSuspendedThreads(RootVisitor* visitor) { { MutexLock mu2(self, *Locks::thread_suspend_count_lock_); for (Thread* thread : threads_to_visit) { - bool updated = thread->ModifySuspendCount(self, -1, nullptr, false); + bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal); DCHECK(updated); } } diff --git a/runtime/thread_list.h b/runtime/thread_list.h index 92702c6498..41c5e328b0 100644 --- a/runtime/thread_list.h +++ b/runtime/thread_list.h @@ -23,6 +23,7 @@ #include "base/time_utils.h" #include "base/value_object.h" #include "jni.h" +#include "suspend_reason.h" #include <bitset> #include <list> @@ -64,7 +65,7 @@ class ThreadList { void ResumeAll() REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_) UNLOCK_FUNCTION(Locks::mutator_lock_); - void Resume(Thread* thread, bool for_debugger = false) + void Resume(Thread* thread, SuspendReason reason = SuspendReason::kInternal) REQUIRES(!Locks::thread_suspend_count_lock_); // Suspends all threads and gets exclusive access to the mutator_lock_. @@ -81,7 +82,9 @@ class ThreadList { // If the thread should be suspended then value of request_suspension should be true otherwise // the routine will wait for a previous suspend request. If the suspension times out then *timeout // is set to true. - Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension, + Thread* SuspendThreadByPeer(jobject peer, + bool request_suspension, + SuspendReason reason, bool* timed_out) REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, @@ -91,7 +94,7 @@ class ThreadList { // thread on success else null. The thread id is used to identify the thread to avoid races with // the thread terminating. Note that as thread ids are recycled this may not suspend the expected // thread, that may be terminating. If the suspension times out then *timeout is set to true. - Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out) + Thread* SuspendThreadByThreadId(uint32_t thread_id, SuspendReason reason, bool* timed_out) REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_); @@ -198,7 +201,7 @@ class ThreadList { void SuspendAllInternal(Thread* self, Thread* ignore1, Thread* ignore2 = nullptr, - bool debug_suspend = false) + SuspendReason reason = SuspendReason::kInternal) REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_); void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = nullptr) |