xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===------------ TaskDispatch.cpp - ORC task dispatch utils --------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
10*0fca6ea1SDimitry Andric #include "llvm/ExecutionEngine/Orc/Core.h"
11349cc55cSDimitry Andric 
12349cc55cSDimitry Andric namespace llvm {
13349cc55cSDimitry Andric namespace orc {
14349cc55cSDimitry Andric 
15349cc55cSDimitry Andric char Task::ID = 0;
16349cc55cSDimitry Andric char GenericNamedTask::ID = 0;
17349cc55cSDimitry Andric const char *GenericNamedTask::DefaultDescription = "Generic Task";
18349cc55cSDimitry Andric 
19349cc55cSDimitry Andric void Task::anchor() {}
2081ad6265SDimitry Andric TaskDispatcher::~TaskDispatcher() = default;
21349cc55cSDimitry Andric 
22349cc55cSDimitry Andric void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric void InPlaceTaskDispatcher::shutdown() {}
25349cc55cSDimitry Andric 
26349cc55cSDimitry Andric #if LLVM_ENABLE_THREADS
27349cc55cSDimitry Andric void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
28*0fca6ea1SDimitry Andric   bool IsMaterializationTask = isa<MaterializationTask>(*T);
29*0fca6ea1SDimitry Andric 
30349cc55cSDimitry Andric   {
31349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(DispatchMutex);
32*0fca6ea1SDimitry Andric 
33*0fca6ea1SDimitry Andric     if (IsMaterializationTask) {
34*0fca6ea1SDimitry Andric 
35*0fca6ea1SDimitry Andric       // If this is a materialization task and there are too many running
36*0fca6ea1SDimitry Andric       // already then queue this one up and return early.
37*0fca6ea1SDimitry Andric       if (MaxMaterializationThreads &&
38*0fca6ea1SDimitry Andric           NumMaterializationThreads == *MaxMaterializationThreads) {
39*0fca6ea1SDimitry Andric         MaterializationTaskQueue.push_back(std::move(T));
40*0fca6ea1SDimitry Andric         return;
41*0fca6ea1SDimitry Andric       }
42*0fca6ea1SDimitry Andric 
43*0fca6ea1SDimitry Andric       // Otherwise record that we have a materialization task running.
44*0fca6ea1SDimitry Andric       ++NumMaterializationThreads;
45*0fca6ea1SDimitry Andric     }
46*0fca6ea1SDimitry Andric 
47349cc55cSDimitry Andric     ++Outstanding;
48349cc55cSDimitry Andric   }
49349cc55cSDimitry Andric 
50*0fca6ea1SDimitry Andric   std::thread([this, T = std::move(T), IsMaterializationTask]() mutable {
51*0fca6ea1SDimitry Andric     while (true) {
52*0fca6ea1SDimitry Andric 
53*0fca6ea1SDimitry Andric       // Run the task.
54349cc55cSDimitry Andric       T->run();
55*0fca6ea1SDimitry Andric 
56349cc55cSDimitry Andric       std::lock_guard<std::mutex> Lock(DispatchMutex);
57*0fca6ea1SDimitry Andric       if (!MaterializationTaskQueue.empty()) {
58*0fca6ea1SDimitry Andric         // If there are any materialization tasks running then steal that work.
59*0fca6ea1SDimitry Andric         T = std::move(MaterializationTaskQueue.front());
60*0fca6ea1SDimitry Andric         MaterializationTaskQueue.pop_front();
61*0fca6ea1SDimitry Andric         if (!IsMaterializationTask) {
62*0fca6ea1SDimitry Andric           ++NumMaterializationThreads;
63*0fca6ea1SDimitry Andric           IsMaterializationTask = true;
64*0fca6ea1SDimitry Andric         }
65*0fca6ea1SDimitry Andric       } else {
66*0fca6ea1SDimitry Andric         // Otherwise decrement work counters.
67*0fca6ea1SDimitry Andric         if (IsMaterializationTask)
68*0fca6ea1SDimitry Andric           --NumMaterializationThreads;
69349cc55cSDimitry Andric         --Outstanding;
70349cc55cSDimitry Andric         OutstandingCV.notify_all();
71*0fca6ea1SDimitry Andric         return;
72*0fca6ea1SDimitry Andric       }
73*0fca6ea1SDimitry Andric     }
74349cc55cSDimitry Andric   }).detach();
75349cc55cSDimitry Andric }
76349cc55cSDimitry Andric 
77349cc55cSDimitry Andric void DynamicThreadPoolTaskDispatcher::shutdown() {
78349cc55cSDimitry Andric   std::unique_lock<std::mutex> Lock(DispatchMutex);
79349cc55cSDimitry Andric   Running = false;
80349cc55cSDimitry Andric   OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; });
81349cc55cSDimitry Andric }
82349cc55cSDimitry Andric #endif
83349cc55cSDimitry Andric 
84349cc55cSDimitry Andric } // namespace orc
85349cc55cSDimitry Andric } // namespace llvm
86