Implement most of VMStack and some of Zygote.
Change-Id: I07e18259a0452a2a9b077148f4f1ca67d3f63427
diff --git a/src/thread_list.cc b/src/thread_list.cc
index f17414c..8c6185d 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -122,6 +122,29 @@
//LOG(INFO) << *self << " SuspendAll complete";
}
+void ThreadList::Suspend(Thread* thread) {
+ DCHECK(thread != Thread::Current());
+
+ // TODO: add another thread_suspend_lock_ to avoid GC/debugger races.
+
+ //LOG(INFO) << "Suspend(" << *thread << ") starting...";
+
+ MutexLock mu(thread_list_lock_);
+ if (!Contains(thread)) {
+ return;
+ }
+
+ {
+ MutexLock mu(thread_suspend_count_lock_);
+ ++thread->suspend_count_;
+ }
+
+ thread->WaitUntilSuspended();
+
+ //LOG(INFO) << "Suspend(" << *thread << ") complete";
+}
+
+
void ThreadList::ResumeAll() {
Thread* self = Thread::Current();
@@ -156,6 +179,45 @@
//LOG(INFO) << *self << " ResumeAll complete";
}
+void ThreadList::Resume(Thread* thread) {
+ DCHECK(thread != Thread::Current());
+
+ //LOG(INFO) << "Resume(" << *thread << ") starting...";
+
+ {
+ MutexLock mu1(thread_list_lock_);
+ MutexLock mu2(thread_suspend_count_lock_);
+ if (!Contains(thread)) {
+ return;
+ }
+ if (thread->suspend_count_ > 0) {
+ --thread->suspend_count_;
+ } else {
+ LOG(WARNING) << *thread << " suspend count already zero";
+ }
+ }
+
+ {
+ //LOG(INFO) << "Resume(" << *thread << ") waking others";
+ MutexLock mu(thread_suspend_count_lock_);
+ thread_suspend_count_cond_.Broadcast();
+ }
+
+ //LOG(INFO) << "Resume(" << *thread << ") complete";
+}
+
+void ThreadList::RunWhileSuspended(Thread* thread, void (*callback)(void*), void* arg) {
+ DCHECK(thread != NULL);
+ Thread* self = Thread::Current();
+ if (thread != self) {
+ Suspend(thread);
+ }
+ callback(arg);
+ if (thread != self) {
+ Resume(thread);
+ }
+}
+
void ThreadList::Register(Thread* thread) {
//LOG(INFO) << "ThreadList::Register() " << *thread;
MutexLock mu(thread_list_lock_);