xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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()19 void Task::anchor() {}
20 TaskDispatcher::~TaskDispatcher() = default;
21 
dispatch(std::unique_ptr<Task> T)22 void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }
23 
shutdown()24 void InPlaceTaskDispatcher::shutdown() {}
25 
26 #if LLVM_ENABLE_THREADS
dispatch(std::unique_ptr<Task> T)27 void 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()77 void 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