diff options
author | Zachary Turner <zturner@google.com> | 2018-06-13 19:29:16 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2018-06-13 19:29:16 +0000 |
commit | 1b76a128a8a6610c3063cc105bfb2cb2857ddcdf (patch) | |
tree | 6311a83450b7ca36e02291ed8f82ab4d8cbdb78e /llvm/unittests/Support/ThreadPool.cpp | |
parent | 9d6fabf9e37b1c2a69ba5d15b1dcbcb044990dc6 (diff) | |
download | bcm5719-llvm-1b76a128a8a6610c3063cc105bfb2cb2857ddcdf.tar.gz bcm5719-llvm-1b76a128a8a6610c3063cc105bfb2cb2857ddcdf.zip |
Enable ThreadPool to support tasks that return values.
Previously ThreadPool could only queue async "jobs", i.e. work
that was done for its side effects and not for its result. It's
useful occasionally to queue async work that returns a value.
From an API perspective, this is very intuitive. The previous
API just returned a shared_future<void>, so all we need to do is
make it return a shared_future<T>, where T is the type of value
that the operation returns.
Making this work required a little magic, but ultimately it's not
too bad. Instead of keeping a shared queue<packaged_task<void()>>
we just keep a shared queue<unique_ptr<TaskBase>>, where TaskBase
is a class with a pure virtual execute() method, then have a
templated derived class that stores a packaged_task<T()>. Everything
else works out pretty cleanly.
Differential Revision: https://reviews.llvm.org/D48115
llvm-svn: 334643
Diffstat (limited to 'llvm/unittests/Support/ThreadPool.cpp')
-rw-r--r-- | llvm/unittests/Support/ThreadPool.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/unittests/Support/ThreadPool.cpp b/llvm/unittests/Support/ThreadPool.cpp index 0da33ad50c0..d2d50c3764e 100644 --- a/llvm/unittests/Support/ThreadPool.cpp +++ b/llvm/unittests/Support/ThreadPool.cpp @@ -147,6 +147,25 @@ TEST_F(ThreadPoolTest, GetFuture) { ASSERT_EQ(2, i.load()); } +TEST_F(ThreadPoolTest, TaskWithResult) { + CHECK_UNSUPPORTED(); + // By making only 1 thread in the pool the two tasks are serialized with + // respect to each other, which means that the second one must return 2. + ThreadPool Pool{1}; + std::atomic_int i{0}; + Pool.async([this, &i] { + waitForMainThread(); + ++i; + }); + // Force the future using get() + std::shared_future<int> Future = Pool.async([&i] { return ++i; }); + ASSERT_EQ(0, i.load()); + setMainThreadReady(); + int Result = Future.get(); + ASSERT_EQ(2, i.load()); + ASSERT_EQ(2, Result); +} + TEST_F(ThreadPoolTest, PoolDestruction) { CHECK_UNSUPPORTED(); // Test that we are waiting on destruction |