diff options
author | Benoit Steiner <benoit.steiner.goog@gmail.com> | 2016-12-08 08:12:49 -0800 |
---|---|---|
committer | Benoit Steiner <benoit.steiner.goog@gmail.com> | 2016-12-08 08:12:49 -0800 |
commit | 7bfff85355215a4702d4d42b1f3bfbfc08977372 (patch) | |
tree | 8698dff508476a28aece2f17fd5793407b987a15 | |
parent | 6811e6cf492731b3e1504bfa42237f909c93d129 (diff) |
Added support for thread cancellation on Linux
6 files changed, 58 insertions, 0 deletions
diff --git a/unsupported/Eigen/CXX11/ThreadPool b/unsupported/Eigen/CXX11/ThreadPool index 09d637e9a..141372f63 100644 --- a/unsupported/Eigen/CXX11/ThreadPool +++ b/unsupported/Eigen/CXX11/ThreadPool @@ -50,6 +50,7 @@ #include "src/ThreadPool/ThreadLocal.h" #include "src/ThreadPool/ThreadYield.h" +#include "src/ThreadPool/ThreadCancel.h" #include "src/ThreadPool/EventCount.h" #include "src/ThreadPool/RunQueue.h" #include "src/ThreadPool/ThreadPoolInterface.h" diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h b/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h index 354bce52a..b57863163 100644 --- a/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h +++ b/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h @@ -97,6 +97,12 @@ class NonBlockingThreadPoolTempl : public Eigen::ThreadPoolInterface { env_.ExecuteTask(t); // Push failed, execute directly. } + void Cancel() { + for (size_t i = 0; i < threads_.size(); i++) { + threads_[i]->Cancel(); + } + } + int NumThreads() const final { return static_cast<int>(threads_.size()); } diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h b/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h index e75d0f467..ab4f85fbf 100644 --- a/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h +++ b/unsupported/Eigen/CXX11/src/ThreadPool/SimpleThreadPool.h @@ -69,6 +69,12 @@ class SimpleThreadPoolTempl : public ThreadPoolInterface { } } + void Cancel() { + for (size_t i = 0; i < threads_.size(); i++) { + threads_[i]->Cancel(); + } + } + int NumThreads() const final { return static_cast<int>(threads_.size()); } diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h new file mode 100644 index 000000000..a05685f11 --- /dev/null +++ b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h @@ -0,0 +1,23 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2016 Benoit Steiner <benoit.steiner.goog@gmail.com> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CXX11_THREADPOOL_THREAD_CANCEL_H +#define EIGEN_CXX11_THREADPOOL_THREAD_CANCEL_H + +// Try to come up with a portable way to cancel a thread +#if EIGEN_OS_GNULINUX + #define EIGEN_THREAD_CANCEL(t) \ + pthread_cancel(t.native_handle()); + #define EIGEN_SUPPORTS_THREAD_CANCELLATION 1 +#else +#define EIGEN_THREAD_CANCEL(t) +#endif + + +#endif // EIGEN_CXX11_THREADPOOL_THREAD_CANCEL_H diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h index 399f95cc1..b3c45057d 100644 --- a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h +++ b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h @@ -23,6 +23,7 @@ struct StlThreadEnvironment { public: EnvThread(std::function<void()> f) : thr_(std::move(f)) {} ~EnvThread() { thr_.join(); } + void Cancel() { EIGEN_THREAD_CANCEL(thr_); } private: std::thread thr_; diff --git a/unsupported/test/cxx11_non_blocking_thread_pool.cpp b/unsupported/test/cxx11_non_blocking_thread_pool.cpp index 5f9bb938b..0fc5a257a 100644 --- a/unsupported/test/cxx11_non_blocking_thread_pool.cpp +++ b/unsupported/test/cxx11_non_blocking_thread_pool.cpp @@ -10,6 +10,7 @@ #define EIGEN_USE_THREADS #include "main.h" +#include <unistd.h> #include "Eigen/CXX11/ThreadPool" static void test_create_destroy_empty_pool() @@ -100,8 +101,28 @@ static void test_parallelism() } } + +static void test_cancel() +{ + NonBlockingThreadPool tp(4); + +#ifdef EIGEN_SUPPORTS_THREAD_CANCELLATION + // Put 2 threads to sleep for much longer than the default test timeout. + tp.Schedule([]() { sleep(3600); } ); + tp.Schedule([]() { sleep(3600 * 24); } ); +#else + // Make 2 threads sleep for a short period of time + tp.Schedule([]() { sleep(1); } ); + tp.Schedule([]() { sleep(2); } ); +#endif + + // Call cancel: + tp.Cancel(); +} + void test_cxx11_non_blocking_thread_pool() { CALL_SUBTEST(test_create_destroy_empty_pool()); CALL_SUBTEST(test_parallelism()); + CALL_SUBTEST(test_cancel()); } |