LLVM 20.0.0git
TaskDispatch.cpp
Go to the documentation of this file.
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
10#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
12
13namespace llvm {
14namespace orc {
15
16char Task::ID = 0;
18const char *GenericNamedTask::DefaultDescription = "Generic Task";
19
20void Task::anchor() {}
22
23void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }
24
26
27#if LLVM_ENABLE_THREADS
28void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
29 bool IsMaterializationTask = isa<MaterializationTask>(*T);
30
31 {
32 std::lock_guard<std::mutex> Lock(DispatchMutex);
33
34 // Reject new tasks if they're dispatched after a call to shutdown.
35 if (Shutdown)
36 return;
37
38 if (IsMaterializationTask) {
39
40 // If this is a materialization task and there are too many running
41 // already then queue this one up and return early.
42 if (MaxMaterializationThreads &&
43 NumMaterializationThreads == *MaxMaterializationThreads) {
44 MaterializationTaskQueue.push_back(std::move(T));
45 return;
46 }
47
48 // Otherwise record that we have a materialization task running.
49 ++NumMaterializationThreads;
50 }
51
52 ++Outstanding;
53 }
54
55 std::thread([this, T = std::move(T), IsMaterializationTask]() mutable {
56 while (true) {
57
58 // Run the task.
59 T->run();
60
61 // Reset the task to free any resources. We need this to happen *before*
62 // we notify anyone (via Outstanding) that this thread is done to ensure
63 // that we don't proceed with JIT shutdown while still holding resources.
64 // (E.g. this was causing "Dangling SymbolStringPtr" assertions).
65 T.reset();
66
67 // Check the work queue state and either proceed with the next task or
68 // end this thread.
69 std::lock_guard<std::mutex> Lock(DispatchMutex);
70 if (!MaterializationTaskQueue.empty()) {
71 // If there are any materialization tasks running then steal that work.
72 T = std::move(MaterializationTaskQueue.front());
73 MaterializationTaskQueue.pop_front();
74 if (!IsMaterializationTask) {
75 ++NumMaterializationThreads;
76 IsMaterializationTask = true;
77 }
78 } else {
79 if (IsMaterializationTask)
80 --NumMaterializationThreads;
81 --Outstanding;
82 if (Outstanding == 0)
83 OutstandingCV.notify_all();
84 return;
85 }
86 }
87 }).detach();
88}
89
90void DynamicThreadPoolTaskDispatcher::shutdown() {
91 std::unique_lock<std::mutex> Lock(DispatchMutex);
92 Shutdown = true;
93 OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; });
94}
95#endif
96
97} // namespace orc
98} // namespace llvm
static const char * DefaultDescription
Definition: TaskDispatch.h:55
void shutdown() override
Called by ExecutionSession. Waits until all tasks have completed.
void dispatch(std::unique_ptr< Task > T) override
Run the given task.
static char ID
Definition: TaskDispatch.h:37
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18