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
12namespace llvm {
13namespace orc {
14
15char Task::ID = 0;
16char GenericNamedTask::ID = 0;
17const char *GenericNamedTask::DefaultDescription = "Generic Task";
18
19void Task::anchor() {}
20TaskDispatcher::~TaskDispatcher() = default;
21
22void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }
23
24void InPlaceTaskDispatcher::shutdown() {}
25
26#if LLVM_ENABLE_THREADS
27void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
28 bool IsMaterializationTask = isa<MaterializationTask>(Val: *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(x: 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
77void DynamicThreadPoolTaskDispatcher::shutdown() {
78 std::unique_lock<std::mutex> Lock(DispatchMutex);
79 Running = false;
80 OutstandingCV.wait(lock&: Lock, p: [this]() { return Outstanding == 0; });
81}
82#endif
83
84} // namespace orc
85} // namespace llvm
86