Commit 01683dbe7e generalized the Session's dispatch mechanism to
hand each runner an opaque Task (move_only_function<void()>), and
simplified QueueingRunner accordingly, but failed to update
ThreadPoolRunner.
Update ThreadPoolRunner to conform to Session's dispatch requirements
and update its unit test to dispatch plain tasks rather than
wrapper-function calls.
88 lines
2.4 KiB
C++
88 lines
2.4 KiB
C++
//===- ThreadPoolRunnerTest.cpp ---------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "orc-rt/ThreadPoolRunner.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <atomic>
|
|
#include <future>
|
|
|
|
using namespace orc_rt;
|
|
|
|
namespace {
|
|
|
|
TEST(ThreadPoolRunnerTest, NoTasks) {
|
|
// Check that immediate destruction works as expected.
|
|
ThreadPoolRunner R(1);
|
|
}
|
|
|
|
TEST(ThreadPoolRunnerTest, BasicTaskExecution) {
|
|
// Smoke test: dispatch one task on a single-threaded pool, wait for it to
|
|
// run, then let the runner destruct.
|
|
std::promise<void> Done;
|
|
std::future<void> DoneF = Done.get_future();
|
|
|
|
{
|
|
ThreadPoolRunner R(1);
|
|
R([&]() { Done.set_value(); });
|
|
DoneF.get();
|
|
}
|
|
}
|
|
|
|
TEST(ThreadPoolRunnerTest, SingleThreadMultipleTasks) {
|
|
// Dispatch multiple tasks on a single-threaded pool. Destruction drains all
|
|
// pending tasks before the worker exits, so every task has run once the
|
|
// runner has been destroyed.
|
|
size_t NumTasksToRun = 10;
|
|
std::atomic<size_t> TasksRun = 0;
|
|
|
|
{
|
|
ThreadPoolRunner R(1);
|
|
for (size_t I = 0; I != NumTasksToRun; ++I)
|
|
R([&]() { ++TasksRun; });
|
|
}
|
|
|
|
EXPECT_EQ(TasksRun, NumTasksToRun);
|
|
}
|
|
|
|
struct ConcurrencyState {
|
|
std::future<int> FInit;
|
|
std::promise<int> P1;
|
|
std::promise<int> P2;
|
|
std::future<int> F1 = P1.get_future();
|
|
std::future<int> F2 = P2.get_future();
|
|
std::promise<int> PResult;
|
|
};
|
|
|
|
TEST(ThreadPoolRunnerTest, ConcurrentTasks) {
|
|
// Check that tasks run concurrently when multiple workers are available.
|
|
// Two tasks communicate values back and forth via futures; neither can
|
|
// complete without the other having started. FResult.get() also serves as
|
|
// the "all tasks have run" wait point before destruction.
|
|
std::promise<int> PInit;
|
|
ConcurrencyState State;
|
|
State.FInit = PInit.get_future();
|
|
std::future<int> FResult = State.PResult.get_future();
|
|
|
|
int ExpectedValue = 42;
|
|
|
|
{
|
|
ThreadPoolRunner R(2);
|
|
R([&]() {
|
|
State.P1.set_value(State.FInit.get());
|
|
State.PResult.set_value(State.F2.get());
|
|
});
|
|
R([&]() { State.P2.set_value(State.F1.get()); });
|
|
|
|
PInit.set_value(ExpectedValue);
|
|
|
|
EXPECT_EQ(FResult.get(), ExpectedValue);
|
|
}
|
|
}
|
|
|
|
} // namespace
|