411c7521创建于 2025年11月19日历史提交
//===- ThreadPoolTaskDispatcher.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
//
//===----------------------------------------------------------------------===//
//
// Contains the implementation of APIs in the orc-rt/ThreadPoolTaskDispatcher.h
// header.
//
//===----------------------------------------------------------------------===//

#include "orc-rt/ThreadPoolTaskDispatcher.h"

#include <cassert>

namespace orc_rt {

ThreadPoolTaskDispatcher::~ThreadPoolTaskDispatcher() {
  assert(!AcceptingTasks && "shutdown was not run");
}

ThreadPoolTaskDispatcher::ThreadPoolTaskDispatcher(size_t NumThreads) {
  Threads.reserve(NumThreads);
  for (size_t I = 0; I < NumThreads; ++I)
    Threads.emplace_back([this]() { taskLoop(); });
}

void ThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
  {
    std::scoped_lock<std::mutex> Lock(M);
    if (!AcceptingTasks)
      return;
    PendingTasks.push_back(std::move(T));
  }
  CV.notify_one();
}

void ThreadPoolTaskDispatcher::shutdown() {
  {
    std::scoped_lock<std::mutex> Lock(M);
    assert(AcceptingTasks && "ThreadPoolTaskDispatcher already shut down?");
    AcceptingTasks = false;
  }
  CV.notify_all();
  for (auto &Thread : Threads)
    Thread.join();
}

void ThreadPoolTaskDispatcher::taskLoop() {
  while (true) {
    std::unique_ptr<Task> T;
    {
      std::unique_lock<std::mutex> Lock(M);
      CV.wait(Lock,
              [this]() { return !PendingTasks.empty() || !AcceptingTasks; });

      if (!AcceptingTasks && PendingTasks.empty())
        return;

      T = std::move(PendingTasks.back());
      PendingTasks.pop_back();
    }

    T->run();
  }
}

} // namespace orc_rt