diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d288f2..2a0e80c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_definitions(DEBUG) # ASan and TSan are incompatible, so we can't use them together. # And because we use std::shared_ptr, it is most likely that there is no need for ASan. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,thread") + # However, TSan is somehow too strict, enable it only temporarily. + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,thread") endif() # strict warnings diff --git a/src/threading/Worker.h b/src/threading/Worker.h index 1917f27..13b77a2 100644 --- a/src/threading/Worker.h +++ b/src/threading/Worker.h @@ -10,6 +10,7 @@ #include "threading/Queue.h" +#include #include #include @@ -66,8 +67,6 @@ template class Worker final void Start(Worker* donor); void Stop(); - void Shutdown(); - /** * @brief Post a task to the worker. * @tparam T For std::forward to work @@ -83,8 +82,7 @@ template class Worker final private: Queue _queue; std::thread _thread; - - bool _running; + std::atomic _running; }; template @@ -112,15 +110,13 @@ template Worker& Worker::operator=(Worker&& other template void Worker::Start(Worker* donor) { - MINET_ASSERT(!_running, "Worker is already running"); - _running = true; + _running.store(true, std::memory_order_relaxed); _thread = std::thread(&Worker::_Routine, this, donor); } template void Worker::Stop() { - MINET_ASSERT(_running, "Working is not running"); - _running = false; + _running.store(false, std::memory_order_relaxed); _thread.join(); } @@ -137,7 +133,7 @@ template bool Worker::_Steal(TTask* task) template void Worker::_Routine(Worker* donor) { TTask task; - while (_running) + while (_running.load(std::memory_order_relaxed)) { // Get one from the worker itself, or steal one to keep busy. if (_queue.Pop(&task) || donor->_Steal(&task)) diff --git a/tests/ThreadPoolTest.cpp b/tests/ThreadPoolTest.cpp index 1ae6c64..750403b 100644 --- a/tests/ThreadPoolTest.cpp +++ b/tests/ThreadPoolTest.cpp @@ -14,7 +14,8 @@ TEST_CASE("ThreadPool") std::packaged_task tasks[TASK_NUM]; // Make it busier? - ThreadPool pool(2, TASK_NUM / 2); + unsigned int threads = HardwareConcurrency(); + ThreadPool pool(threads, TASK_NUM / threads); for (int i = 0; i < TASK_NUM; i++) { tasks[i] = std::packaged_task([i]() { @@ -29,7 +30,6 @@ TEST_CASE("ThreadPool") // clang-format off CHECK_EQ(pool.Submit([&tasks, i]() { tasks[i](); - return i; }), true); // clang-format on }