brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 02cca94 Raw
111 lines · cpp
1//===-- ThreadPoolTaskDispatcherTest.cpp ----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "orc-rt/ThreadPoolTaskDispatcher.h"10#include "gtest/gtest.h"11 12#include <atomic>13#include <future>14#include <thread>15#include <vector>16 17using namespace orc_rt;18 19namespace {20 21TEST(ThreadPoolTaskDispatcherTest, NoTasks) {22  // Check that immediate shutdown works as expected.23  ThreadPoolTaskDispatcher Dispatcher(1);24  Dispatcher.shutdown();25}26 27TEST(ThreadPoolTaskDispatcherTest, BasicTaskExecution) {28  // Smoke test: Check that we can run a single task on a single-threaded pool.29  ThreadPoolTaskDispatcher Dispatcher(1);30  std::atomic<bool> TaskRan = false;31 32  Dispatcher.dispatch(makeGenericTask([&]() { TaskRan = true; }));33 34  Dispatcher.shutdown();35 36  EXPECT_TRUE(TaskRan);37}38 39TEST(ThreadPoolTaskDispatcherTest, SingleThreadMultipleTasks) {40  // Check that multiple tasks in a single threaded pool run as expected.41  ThreadPoolTaskDispatcher Dispatcher(1);42  size_t NumTasksToRun = 10;43  std::atomic<size_t> TasksRun = 0;44 45  for (size_t I = 0; I != NumTasksToRun; ++I)46    Dispatcher.dispatch(makeGenericTask([&]() { ++TasksRun; }));47 48  Dispatcher.shutdown();49 50  EXPECT_EQ(TasksRun, NumTasksToRun);51}52 53TEST(ThreadPoolTaskDispatcherTest, ConcurrentTasks) {54  // Check that tasks are run concurrently when multiple workers are available.55  // Adds two tasks that communicate a value back and forth using futures.56  // Neither task should be able to complete without the other having started.57  ThreadPoolTaskDispatcher Dispatcher(2);58 59  std::promise<int> PInit;60  std::future<int> FInit = PInit.get_future();61  std::promise<int> P1;62  std::future<int> F1 = P1.get_future();63  std::promise<int> P2;64  std::future<int> F2 = P2.get_future();65  std::promise<int> PResult;66  std::future<int> FResult = PResult.get_future();67 68  // Task A gets the initial value, sends it via P1, waits for response on F2.69  Dispatcher.dispatch(makeGenericTask([&]() {70    P1.set_value(FInit.get());71    PResult.set_value(F2.get());72  }));73 74  // Task B gets value from F1, sends it back on P2.75  Dispatcher.dispatch(makeGenericTask([&]() { P2.set_value(F1.get()); }));76 77  int ExpectedValue = 42;78  PInit.set_value(ExpectedValue);79 80  Dispatcher.shutdown();81 82  EXPECT_EQ(FResult.get(), ExpectedValue);83}84 85TEST(ThreadPoolTaskDispatcherTest, TasksRejectedAfterShutdown) {86  class TaskToReject : public Task {87  public:88    TaskToReject(bool &BodyRun, bool &DestructorRun)89        : BodyRun(BodyRun), DestructorRun(DestructorRun) {}90    ~TaskToReject() { DestructorRun = true; }91    void run() override { BodyRun = true; }92 93  private:94    bool &BodyRun;95    bool &DestructorRun;96  };97 98  ThreadPoolTaskDispatcher Dispatcher(1);99  Dispatcher.shutdown();100 101  bool BodyRun = false;102  bool DestructorRun = false;103 104  Dispatcher.dispatch(std::make_unique<TaskToReject>(BodyRun, DestructorRun));105 106  EXPECT_FALSE(BodyRun);107  EXPECT_TRUE(DestructorRun);108}109 110} // end anonymous namespace111