Add gfx950 mfma instructions to ROCDL dialect (#123361)
[llvm-project.git] / llvm / lib / ExecutionEngine / Orc / TaskDispatch.cpp
blobe87a14f3ea7c4ffe7564858aa221c7861332c946
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 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
10 #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
11 #include "llvm/ExecutionEngine/Orc/Core.h"
13 namespace llvm {
14 namespace orc {
16 char Task::ID = 0;
17 char GenericNamedTask::ID = 0;
18 char IdleTask::ID = 0;
20 const char *GenericNamedTask::DefaultDescription = "Generic Task";
22 void Task::anchor() {}
23 void IdleTask::anchor() {}
25 TaskDispatcher::~TaskDispatcher() = default;
27 void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }
29 void InPlaceTaskDispatcher::shutdown() {}
31 #if LLVM_ENABLE_THREADS
32 void DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
34 enum { Normal, Materialization, Idle } TaskKind;
36 if (isa<MaterializationTask>(*T))
37 TaskKind = Materialization;
38 else if (isa<IdleTask>(*T))
39 TaskKind = Idle;
40 else
41 TaskKind = Normal;
44 std::lock_guard<std::mutex> Lock(DispatchMutex);
46 // Reject new tasks if they're dispatched after a call to shutdown.
47 if (Shutdown)
48 return;
50 if (TaskKind == Materialization) {
52 // If this is a materialization task and there are too many running
53 // already then queue this one up and return early.
54 if (!canRunMaterializationTaskNow())
55 return MaterializationTaskQueue.push_back(std::move(T));
57 // Otherwise record that we have a materialization task running.
58 ++NumMaterializationThreads;
59 } else if (TaskKind == Idle) {
60 if (!canRunIdleTaskNow())
61 return IdleTaskQueue.push_back(std::move(T));
64 ++Outstanding;
67 std::thread([this, T = std::move(T), TaskKind]() mutable {
68 while (true) {
70 // Run the task.
71 T->run();
73 // Reset the task to free any resources. We need this to happen *before*
74 // we notify anyone (via Outstanding) that this thread is done to ensure
75 // that we don't proceed with JIT shutdown while still holding resources.
76 // (E.g. this was causing "Dangling SymbolStringPtr" assertions).
77 T.reset();
79 // Check the work queue state and either proceed with the next task or
80 // end this thread.
81 std::lock_guard<std::mutex> Lock(DispatchMutex);
83 if (TaskKind == Materialization)
84 --NumMaterializationThreads;
85 --Outstanding;
87 if (!MaterializationTaskQueue.empty() && canRunMaterializationTaskNow()) {
88 // If there are any materialization tasks running then steal that work.
89 T = std::move(MaterializationTaskQueue.front());
90 MaterializationTaskQueue.pop_front();
91 TaskKind = Materialization;
92 ++NumMaterializationThreads;
93 ++Outstanding;
94 } else if (!IdleTaskQueue.empty() && canRunIdleTaskNow()) {
95 T = std::move(IdleTaskQueue.front());
96 IdleTaskQueue.pop_front();
97 TaskKind = Idle;
98 ++Outstanding;
99 } else {
100 if (Outstanding == 0)
101 OutstandingCV.notify_all();
102 return;
105 }).detach();
108 void DynamicThreadPoolTaskDispatcher::shutdown() {
109 std::unique_lock<std::mutex> Lock(DispatchMutex);
110 Shutdown = true;
111 OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; });
114 bool DynamicThreadPoolTaskDispatcher::canRunMaterializationTaskNow() {
115 return !MaxMaterializationThreads ||
116 (NumMaterializationThreads < *MaxMaterializationThreads);
119 bool DynamicThreadPoolTaskDispatcher::canRunIdleTaskNow() {
120 return !MaxMaterializationThreads ||
121 (Outstanding < *MaxMaterializationThreads);
124 #endif
126 } // namespace orc
127 } // namespace llvm