Implement Dbg::Disconnected and Dbg::UndoDebuggerSuspensions.
You can now start and stop oatexec-based apps with DDMS running, with
no UNIMPLEMENTEDs.
Change-Id: Ic53e7bdd4ddd3ed93f9d807499d991ea30f48810
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 0512186..875b14e 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -86,6 +86,27 @@
}
}
+void ThreadList::ModifySuspendCount(Thread* thread, int delta, bool for_debugger) {
+#ifndef NDEBUG
+ DCHECK(delta == -1 || delta == +1 || delta == thread->debug_suspend_count_) << delta;
+ DCHECK_GE(thread->suspend_count_, thread->debug_suspend_count_);
+ if (delta == -1) {
+ DCHECK_GT(thread->suspend_count_, 0);
+ if (for_debugger) {
+ DCHECK_GT(thread->debug_suspend_count_, 0);
+ }
+ }
+#else
+ if (delta == -1 && thread->suspend_count_ <= 0) {
+ LOG(FATAL) << *thread << " suspend count already zero";
+ }
+#endif
+ thread->suspend_count_ += delta;
+ if (for_debugger) {
+ thread->debug_suspend_count_ += delta;
+ }
+}
+
void ThreadList::FullSuspendCheck(Thread* thread) {
CHECK(thread != NULL);
CHECK_GE(thread->suspend_count_, 0);
@@ -137,7 +158,7 @@
if (verbose_) {
LOG(INFO) << "requesting thread suspend: " << *thread;
}
- ++thread->suspend_count_;
+ ModifySuspendCount(thread, +1, for_debugger);
}
}
@@ -187,7 +208,7 @@
{
MutexLock mu(thread_suspend_count_lock_);
- ++thread->suspend_count_;
+ ModifySuspendCount(thread, +1, false);
}
thread->WaitUntilSuspended();
@@ -210,7 +231,7 @@
// though.
ThreadListLocker locker(this);
MutexLock mu(thread_suspend_count_lock_);
- ++self->suspend_count_;
+ ModifySuspendCount(self, +1, true);
// Suspend ourselves.
CHECK_GT(self->suspend_count_, 0);
@@ -261,11 +282,7 @@
if (thread == self || (for_debugger && thread == debug_thread)) {
continue;
}
- if (thread->suspend_count_ > 0) {
- --thread->suspend_count_;
- } else {
- LOG(WARNING) << *thread << " suspend count already zero";
- }
+ ModifySuspendCount(thread, -1, for_debugger);
}
}
@@ -297,11 +314,7 @@
if (!Contains(thread)) {
return;
}
- if (thread->suspend_count_ > 0) {
- --thread->suspend_count_;
- } else {
- LOG(WARNING) << *thread << " suspend count already zero";
- }
+ ModifySuspendCount(thread, -1, false);
}
{
@@ -329,6 +342,35 @@
}
}
+void ThreadList::UndoDebuggerSuspensions() {
+ Thread* self = Thread::Current();
+
+ if (verbose_) {
+ LOG(INFO) << *self << " UndoDebuggerSuspensions starting";
+ }
+
+ {
+ ThreadListLocker locker(this);
+ MutexLock mu(thread_suspend_count_lock_);
+ for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
+ Thread* thread = *it;
+ if (thread == self || thread->debug_suspend_count_ == 0) {
+ continue;
+ }
+ ModifySuspendCount(thread, -thread->debug_suspend_count_, true);
+ }
+ }
+
+ {
+ MutexLock mu(thread_suspend_count_lock_);
+ thread_suspend_count_cond_.Broadcast();
+ }
+
+ if (verbose_) {
+ LOG(INFO) << "UndoDebuggerSuspensions(" << *self << ") complete";
+ }
+}
+
void ThreadList::Register() {
Thread* self = Thread::Current();