Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2194)

Unified Diff: runtime/vm/thread_pool.cc

Issue 1275853008: Reverts VM thread cleanup (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/thread_pool.h ('k') | runtime/vm/thread_pool_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/thread_pool.cc
diff --git a/runtime/vm/thread_pool.cc b/runtime/vm/thread_pool.cc
index 87f441519e454e66bc4f3dd5c9c781089c511906..5b3a713d2d09b2c32be7605f622e7671669e36c6 100644
--- a/runtime/vm/thread_pool.cc
+++ b/runtime/vm/thread_pool.cc
@@ -12,6 +12,9 @@ namespace dart {
DEFINE_FLAG(int, worker_timeout_millis, 5000,
"Free workers when they have been idle for this amount of time.");
+Monitor* ThreadPool::exit_monitor_ = NULL;
+int* ThreadPool::exit_count_ = NULL;
+
ThreadPool::ThreadPool()
: shutting_down_(false),
all_workers_(NULL),
@@ -19,8 +22,7 @@ ThreadPool::ThreadPool()
count_started_(0),
count_stopped_(0),
count_running_(0),
- count_idle_(0),
- shutting_down_workers_(NULL) {
+ count_idle_(0) {
}
@@ -92,27 +94,14 @@ void ThreadPool::Shutdown() {
}
// Release ThreadPool::mutex_ before calling Worker functions.
- {
- MonitorLocker eml(&exit_monitor_);
-
- // First tell all the workers to shut down.
- Worker* current = saved;
- while (current != NULL) {
- Worker* next = current->all_next_;
- if (current->id_ != OSThread::GetCurrentThreadId()) {
- AddWorkerToShutdownList(current);
- }
- current->Shutdown();
- current = next;
- }
- saved = NULL;
-
- // Wait until all workers have exited.
- while (shutting_down_workers_ != NULL) {
- // Here, we are waiting for workers to exit. When a worker exits we will
- // be notified.
- eml.Wait();
- }
+ Worker* current = saved;
+ while (current != NULL) {
+ // We may access all_next_ without holding ThreadPool::mutex_ here
+ // because the worker is no longer owned by the ThreadPool.
+ Worker* next = current->all_next_;
+ current->all_next_ = NULL;
+ current->Shutdown();
+ current = next;
}
}
@@ -168,7 +157,6 @@ bool ThreadPool::RemoveWorkerFromAllList(Worker* worker) {
worker->all_next_ = NULL;
worker->owned_ = false;
worker->pool_ = NULL;
- worker->done_ = true;
return true;
}
@@ -218,38 +206,6 @@ bool ThreadPool::ReleaseIdleWorker(Worker* worker) {
}
-// Only call while holding the exit_monitor_
-void ThreadPool::AddWorkerToShutdownList(Worker* worker) {
- worker->shutdown_next_ = shutting_down_workers_;
- shutting_down_workers_ = worker;
-}
-
-
-// Only call while holding the exit_monitor_
-bool ThreadPool::RemoveWorkerFromShutdownList(Worker* worker) {
- ASSERT(worker != NULL);
- ASSERT(shutting_down_workers_ != NULL);
-
- // Special case head of list.
- if (shutting_down_workers_ == worker) {
- shutting_down_workers_ = worker->shutdown_next_;
- worker->shutdown_next_ = NULL;
- return true;
- }
-
- for (Worker* current = shutting_down_workers_;
- current->shutdown_next_ != NULL;
- current = current->shutdown_next_) {
- if (current->shutdown_next_ == worker) {
- current->shutdown_next_ = worker->shutdown_next_;
- worker->shutdown_next_ = NULL;
- return true;
- }
- }
- return false;
-}
-
-
ThreadPool::Task::Task() {
}
@@ -260,14 +216,10 @@ ThreadPool::Task::~Task() {
ThreadPool::Worker::Worker(ThreadPool* pool)
: pool_(pool),
- done_(false),
task_(NULL),
- id_(OSThread::kInvalidThreadId),
- started_(false),
owned_(false),
all_next_(NULL),
- idle_next_(NULL),
- shutdown_next_(NULL) {
+ idle_next_(NULL) {
}
@@ -312,7 +264,7 @@ static int64_t ComputeTimeout(int64_t idle_start) {
}
-bool ThreadPool::Worker::Loop() {
+void ThreadPool::Worker::Loop() {
MonitorLocker ml(&monitor_);
int64_t idle_start;
while (true) {
@@ -329,9 +281,9 @@ bool ThreadPool::Worker::Loop() {
ASSERT(task_ == NULL);
if (IsDone()) {
- return false;
+ return;
}
- ASSERT(!done_);
+ ASSERT(pool_ != NULL);
pool_->SetIdle(this);
idle_start = OS::GetCurrentTimeMillis();
while (true) {
@@ -342,21 +294,21 @@ bool ThreadPool::Worker::Loop() {
break;
}
if (IsDone()) {
- return false;
+ return;
}
- if ((result == Monitor::kTimedOut) && pool_->ReleaseIdleWorker(this)) {
- return true;
+ if (result == Monitor::kTimedOut &&
+ pool_->ReleaseIdleWorker(this)) {
+ return;
}
}
}
UNREACHABLE();
- return false;
}
void ThreadPool::Worker::Shutdown() {
MonitorLocker ml(&monitor_);
- done_ = true;
+ pool_ = NULL; // Fail fast if someone tries to access pool_.
ml.Notify();
}
@@ -365,55 +317,20 @@ void ThreadPool::Worker::Shutdown() {
void ThreadPool::Worker::Main(uword args) {
Thread::EnsureInit();
Worker* worker = reinterpret_cast<Worker*>(args);
- bool delete_self = false;
-
- {
- MonitorLocker ml(&(worker->monitor_));
- if (worker->IsDone()) {
- // id_ hasn't been set yet, but the ThreadPool is being shutdown.
- // Delete the task, and return.
- ASSERT(worker->task_);
- delete worker->task_;
- worker->task_ = NULL;
- delete_self = true;
- } else {
- worker->id_ = OSThread::GetCurrentThreadId();
- worker->started_ = true;
- }
- }
-
- // We aren't able to delete the worker while holding the worker's monitor.
- // Now that we have released it, and we know that ThreadPool::Shutdown
- // won't touch it again, we can delete it and return.
- if (delete_self) {
- MonitorLocker eml(&worker->pool_->exit_monitor_);
- worker->pool_->RemoveWorkerFromShutdownList(worker);
- delete worker;
- eml.Notify();
- return;
- }
-
- bool released = worker->Loop();
+ worker->Loop();
// It should be okay to access these unlocked here in this assert.
- // worker->all_next_ is retained by the pool for shutdown monitoring.
- ASSERT(!worker->owned_ && (worker->idle_next_ == NULL));
-
- if (!released) {
- // This worker is exiting because the thread pool is being shut down.
- // Inform the thread pool that we are exiting. We remove this worker from
- // shutting_down_workers_ list because there will be no need for the
- // ThreadPool to take action for this worker.
- MonitorLocker eml(&worker->pool_->exit_monitor_);
- worker->id_ = OSThread::kInvalidThreadId;
- worker->pool_->RemoveWorkerFromShutdownList(worker);
- delete worker;
- eml.Notify();
- } else {
- // This worker is going down because it was idle for too long. This case
- // is not due to a ThreadPool Shutdown. Thus, we simply delete the worker.
- delete worker;
+ ASSERT(!worker->owned_ &&
+ worker->all_next_ == NULL &&
+ worker->idle_next_ == NULL);
+
+ // The exit monitor is only used during testing.
+ if (ThreadPool::exit_monitor_) {
+ MonitorLocker ml(ThreadPool::exit_monitor_);
+ (*ThreadPool::exit_count_)++;
+ ml.Notify();
}
+ delete worker;
#if defined(TARGET_OS_WINDOWS)
Thread::CleanUp();
#endif
« no previous file with comments | « runtime/vm/thread_pool.h ('k') | runtime/vm/thread_pool_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698