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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/TaskDispatch.h" 10 #include "llvm/ExecutionEngine/Orc/Core.h" 11 12 namespace llvm { 13 namespace orc { 14 15 char Task::ID = 0; 16 char GenericNamedTask::ID = 0; 17 const char *GenericNamedTask::DefaultDescription = "Generic Task"; 18 anchor()19void Task::anchor() {} 20 TaskDispatcher::~TaskDispatcher() = default; 21 dispatch(std::unique_ptr<Task> T)22void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); } 23 shutdown()24void InPlaceTaskDispatcher::shutdown() {} 25 26 #if LLVM_ENABLE_THREADS dispatch(std::unique_ptr<Task> T)27void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) { 28 bool IsMaterializationTask = isa<MaterializationTask>(*T); 29 30 { 31 std::lock_guard<std::mutex> Lock(DispatchMutex); 32 33 if (IsMaterializationTask) { 34 35 // If this is a materialization task and there are too many running 36 // already then queue this one up and return early. 37 if (MaxMaterializationThreads && 38 NumMaterializationThreads == *MaxMaterializationThreads) { 39 MaterializationTaskQueue.push_back(std::move(T)); 40 return; 41 } 42 43 // Otherwise record that we have a materialization task running. 44 ++NumMaterializationThreads; 45 } 46 47 ++Outstanding; 48 } 49 50 std::thread([this, T = std::move(T), IsMaterializationTask]() mutable { 51 while (true) { 52 53 // Run the task. 54 T->run(); 55 56 std::lock_guard<std::mutex> Lock(DispatchMutex); 57 if (!MaterializationTaskQueue.empty()) { 58 // If there are any materialization tasks running then steal that work. 59 T = std::move(MaterializationTaskQueue.front()); 60 MaterializationTaskQueue.pop_front(); 61 if (!IsMaterializationTask) { 62 ++NumMaterializationThreads; 63 IsMaterializationTask = true; 64 } 65 } else { 66 // Otherwise decrement work counters. 67 if (IsMaterializationTask) 68 --NumMaterializationThreads; 69 --Outstanding; 70 OutstandingCV.notify_all(); 71 return; 72 } 73 } 74 }).detach(); 75 } 76 shutdown()77void DynamicThreadPoolTaskDispatcher::shutdown() { 78 std::unique_lock<std::mutex> Lock(DispatchMutex); 79 Running = false; 80 OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; }); 81 } 82 #endif 83 84 } // namespace orc 85 } // namespace llvm 86