Thread suspension.
Includes SuspendAll/ResumeAll, and uses them in Heap and SignalCatcher.
Change-Id: Ie39b868ca5961f5016f367acade5071392bb723e
diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc
index 08db89a..d72002f 100644
--- a/src/signal_catcher.cc
+++ b/src/signal_catcher.cc
@@ -25,26 +25,31 @@
#include "heap.h"
#include "runtime.h"
#include "thread.h"
+#include "thread_list.h"
#include "utils.h"
namespace art {
-SignalCatcher::SignalCatcher() : lock_("SignalCatcher lock") {
+SignalCatcher::SignalCatcher() : lock_("SignalCatcher lock"), thread_(NULL) {
SetHaltFlag(false);
// Create a raw pthread; its start routine will attach to the runtime.
- errno = pthread_create(&thread_, NULL, &Run, this);
- if (errno != 0) {
- PLOG(FATAL) << "pthread_create failed for signal catcher thread";
+ CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Run, this), "signal catcher thread");
+
+ CHECK_PTHREAD_CALL(pthread_cond_init, (&cond_, NULL), "SignalCatcher::cond_");
+ MutexLock mu(lock_);
+ while (thread_ == NULL) {
+ CHECK_PTHREAD_CALL(pthread_cond_wait, (&cond_, lock_.GetImpl()), __FUNCTION__);
}
+ CHECK_PTHREAD_CALL(pthread_cond_destroy, (&cond_), "SignalCatcher::cond_");
}
SignalCatcher::~SignalCatcher() {
// Since we know the thread is just sitting around waiting for signals
// to arrive, send it one.
SetHaltFlag(true);
- pthread_kill(thread_, SIGQUIT);
- pthread_join(thread_, NULL);
+ CHECK_PTHREAD_CALL(pthread_kill, (pthread_, SIGQUIT), "signal catcher shutdown");
+ CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "signal catcher shutdown");
}
void SignalCatcher::SetHaltFlag(bool new_value) {
@@ -58,7 +63,7 @@
}
void SignalCatcher::HandleSigQuit() {
- // TODO: suspend all threads
+ Runtime::Current()->GetThreadList()->SuspendAll();
std::stringstream os;
os << "\n"
@@ -80,7 +85,7 @@
os << "----- end " << getpid() << " -----";
- // TODO: resume all threads
+ Runtime::Current()->GetThreadList()->ResumeAll();
LOG(INFO) << os.str();
}
@@ -112,9 +117,14 @@
SignalCatcher* signal_catcher = reinterpret_cast<SignalCatcher*>(arg);
CHECK(signal_catcher != NULL);
- Runtime::Current()->AttachCurrentThread("Signal Catcher", true);
- Thread* self = Thread::Current();
- CHECK(self != NULL);
+ Runtime* runtime = Runtime::Current();
+ runtime->AttachCurrentThread("Signal Catcher", true);
+
+ {
+ MutexLock mu(signal_catcher->lock_);
+ signal_catcher->thread_ = Thread::Current();
+ CHECK_PTHREAD_CALL(pthread_cond_broadcast, (&signal_catcher->cond_), __FUNCTION__);
+ }
// Set up mask with signals we want to handle.
sigset_t mask;
@@ -123,13 +133,13 @@
sigaddset(&mask, SIGUSR1);
while (true) {
- int signal_number = WaitForSignal(self, mask);
+ int signal_number = WaitForSignal(signal_catcher->thread_, mask);
if (signal_catcher->ShouldHalt()) {
- Runtime::Current()->DetachCurrentThread();
+ runtime->DetachCurrentThread();
return NULL;
}
- LOG(INFO) << *self << ": reacting to signal " << signal_number;
+ LOG(INFO) << *signal_catcher->thread_ << ": reacting to signal " << signal_number;
switch (signal_number) {
case SIGQUIT:
HandleSigQuit();