From 0ddfd3a397eefde12a2999111cbdda0e77ab5639 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 24 Jan 2018 15:50:13 -0800 Subject: Threading fixes (#1377) * threading fixes, be careful when creating the pool (more than one thread may try to) and don't create it just to check if its running in the thread constructor assertions * child threads will call ::get() - don't do initialize() under the lock --- src/support/threads.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/support/threads.cpp') diff --git a/src/support/threads.cpp b/src/support/threads.cpp index 31c900ceb..c4f714f8e 100644 --- a/src/support/threads.cpp +++ b/src/support/threads.cpp @@ -41,18 +41,19 @@ namespace wasm { // Global thread information +static std::mutex poolMutex; static std::unique_ptr pool; // Thread Thread::Thread() { - assert(!ThreadPool::get()->isRunning()); + assert(!ThreadPool::isRunning()); thread = make_unique(mainLoop, this); } Thread::~Thread() { - assert(!ThreadPool::get()->isRunning()); + assert(!ThreadPool::isRunning()); { std::lock_guard lock(mutex); // notify the thread that it can exit @@ -138,9 +139,23 @@ size_t ThreadPool::getNumCores() { } ThreadPool* ThreadPool::get() { - if (!pool) { - pool = make_unique(); + DEBUG_POOL("::get()\n"); + bool created = false; + { + // lock on the creation + std::lock_guard lock(poolMutex); + if (!pool) { + DEBUG_POOL("::get() creating\n"); + created = true; + pool = make_unique(); + } + } + if (created) { + // if we created it here, do the initialization too. this + // is outside of the mutex, as we create child threads who + // will call ::get() themselves pool->initialize(getNumCores()); + DEBUG_POOL("::get() created\n"); } return pool.get(); } @@ -178,6 +193,7 @@ size_t ThreadPool::size() { } bool ThreadPool::isRunning() { + DEBUG_POOL("check if running\n"); return pool && pool->running; } -- cgit v1.2.3