brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · e87a14f Raw
128 lines · cpp
1//===------------ TaskDispatch.cpp - ORC task dispatch utils --------------===//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 "llvm/ExecutionEngine/Orc/TaskDispatch.h"10#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS11#include "llvm/ExecutionEngine/Orc/Core.h"12 13namespace llvm {14namespace orc {15 16char Task::ID = 0;17char GenericNamedTask::ID = 0;18char IdleTask::ID = 0;19 20const char *GenericNamedTask::DefaultDescription = "Generic Task";21 22void Task::anchor() {}23void IdleTask::anchor() {}24 25TaskDispatcher::~TaskDispatcher() = default;26 27void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }28 29void InPlaceTaskDispatcher::shutdown() {}30 31#if LLVM_ENABLE_THREADS32void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {33 34  enum { Normal, Materialization, Idle } TaskKind;35 36  if (isa<MaterializationTask>(*T))37    TaskKind = Materialization;38  else if (isa<IdleTask>(*T))39    TaskKind = Idle;40  else41    TaskKind = Normal;42 43  {44    std::lock_guard<std::mutex> Lock(DispatchMutex);45 46    // Reject new tasks if they're dispatched after a call to shutdown.47    if (Shutdown)48      return;49 50    if (TaskKind == Materialization) {51 52      // If this is a materialization task and there are too many running53      // already then queue this one up and return early.54      if (!canRunMaterializationTaskNow())55        return MaterializationTaskQueue.push_back(std::move(T));56 57      // Otherwise record that we have a materialization task running.58      ++NumMaterializationThreads;59    } else if (TaskKind == Idle) {60      if (!canRunIdleTaskNow())61        return IdleTaskQueue.push_back(std::move(T));62    }63 64    ++Outstanding;65  }66 67  std::thread([this, T = std::move(T), TaskKind]() mutable {68    while (true) {69 70      // Run the task.71      T->run();72 73      // Reset the task to free any resources. We need this to happen *before*74      // we notify anyone (via Outstanding) that this thread is done to ensure75      // that we don't proceed with JIT shutdown while still holding resources.76      // (E.g. this was causing "Dangling SymbolStringPtr" assertions).77      T.reset();78 79      // Check the work queue state and either proceed with the next task or80      // end this thread.81      std::lock_guard<std::mutex> Lock(DispatchMutex);82 83      if (TaskKind == Materialization)84        --NumMaterializationThreads;85      --Outstanding;86 87      if (!MaterializationTaskQueue.empty() && canRunMaterializationTaskNow()) {88        // If there are any materialization tasks running then steal that work.89        T = std::move(MaterializationTaskQueue.front());90        MaterializationTaskQueue.pop_front();91        TaskKind = Materialization;92        ++NumMaterializationThreads;93        ++Outstanding;94      } else if (!IdleTaskQueue.empty() && canRunIdleTaskNow()) {95        T = std::move(IdleTaskQueue.front());96        IdleTaskQueue.pop_front();97        TaskKind = Idle;98        ++Outstanding;99      } else {100        if (Outstanding == 0)101          OutstandingCV.notify_all();102        return;103      }104    }105  }).detach();106}107 108void DynamicThreadPoolTaskDispatcher::shutdown() {109  std::unique_lock<std::mutex> Lock(DispatchMutex);110  Shutdown = true;111  OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; });112}113 114bool DynamicThreadPoolTaskDispatcher::canRunMaterializationTaskNow() {115  return !MaxMaterializationThreads ||116         (NumMaterializationThreads < *MaxMaterializationThreads);117}118 119bool DynamicThreadPoolTaskDispatcher::canRunIdleTaskNow() {120  return !MaxMaterializationThreads ||121         (Outstanding < *MaxMaterializationThreads);122}123 124#endif125 126} // namespace orc127} // namespace llvm128