1 | //===--------- TaskDispatch.h - ORC task dispatch utils ---------*- C++ -*-===// |
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 | // Task and TaskDispatch classes. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_EXECUTIONENGINE_ORC_TASKDISPATCH_H |
14 | #define LLVM_EXECUTIONENGINE_ORC_TASKDISPATCH_H |
15 | |
16 | #include "llvm/Config/llvm-config.h" |
17 | #include "llvm/Support/Debug.h" |
18 | #include "llvm/Support/ExtensibleRTTI.h" |
19 | #include "llvm/Support/raw_ostream.h" |
20 | |
21 | #include <cassert> |
22 | #include <string> |
23 | |
24 | #if LLVM_ENABLE_THREADS |
25 | #include <condition_variable> |
26 | #include <mutex> |
27 | #include <thread> |
28 | #endif |
29 | |
30 | namespace llvm { |
31 | namespace orc { |
32 | |
33 | /// Represents an abstract task for ORC to run. |
34 | class Task : public RTTIExtends<Task, RTTIRoot> { |
35 | public: |
36 | static char ID; |
37 | |
38 | virtual ~Task() = default; |
39 | |
40 | /// Description of the task to be performed. Used for logging. |
41 | virtual void printDescription(raw_ostream &OS) = 0; |
42 | |
43 | /// Run the task. |
44 | virtual void run() = 0; |
45 | |
46 | private: |
47 | void anchor() override; |
48 | }; |
49 | |
50 | /// Base class for generic tasks. |
51 | class GenericNamedTask : public RTTIExtends<GenericNamedTask, Task> { |
52 | public: |
53 | static char ID; |
54 | static const char *DefaultDescription; |
55 | }; |
56 | |
57 | /// Generic task implementation. |
58 | template <typename FnT> class GenericNamedTaskImpl : public GenericNamedTask { |
59 | public: |
60 | GenericNamedTaskImpl(FnT &&Fn, std::string DescBuffer) |
61 | : Fn(std::forward<FnT>(Fn)), Desc(DescBuffer.c_str()), |
62 | DescBuffer(std::move(DescBuffer)) {} |
63 | GenericNamedTaskImpl(FnT &&Fn, const char *Desc) |
64 | : Fn(std::forward<FnT>(Fn)), Desc(Desc) { |
65 | assert(Desc && "Description cannot be null" ); |
66 | } |
67 | void printDescription(raw_ostream &OS) override { OS << Desc; } |
68 | void run() override { Fn(); } |
69 | |
70 | private: |
71 | FnT Fn; |
72 | const char *Desc; |
73 | std::string DescBuffer; |
74 | }; |
75 | |
76 | /// Create a generic named task from a std::string description. |
77 | template <typename FnT> |
78 | std::unique_ptr<GenericNamedTask> makeGenericNamedTask(FnT &&Fn, |
79 | std::string Desc) { |
80 | return std::make_unique<GenericNamedTaskImpl<FnT>>(std::forward<FnT>(Fn), |
81 | std::move(Desc)); |
82 | } |
83 | |
84 | /// Create a generic named task from a const char * description. |
85 | template <typename FnT> |
86 | std::unique_ptr<GenericNamedTask> |
87 | makeGenericNamedTask(FnT &&Fn, const char *Desc = nullptr) { |
88 | if (!Desc) |
89 | Desc = GenericNamedTask::DefaultDescription; |
90 | return std::make_unique<GenericNamedTaskImpl<FnT>>(std::forward<FnT>(Fn), |
91 | Desc); |
92 | } |
93 | |
94 | /// Abstract base for classes that dispatch ORC Tasks. |
95 | class TaskDispatcher { |
96 | public: |
97 | virtual ~TaskDispatcher(); |
98 | |
99 | /// Run the given task. |
100 | virtual void dispatch(std::unique_ptr<Task> T) = 0; |
101 | |
102 | /// Called by ExecutionSession. Waits until all tasks have completed. |
103 | virtual void shutdown() = 0; |
104 | }; |
105 | |
106 | /// Runs all tasks on the current thread. |
107 | class InPlaceTaskDispatcher : public TaskDispatcher { |
108 | public: |
109 | void dispatch(std::unique_ptr<Task> T) override; |
110 | void shutdown() override; |
111 | }; |
112 | |
113 | #if LLVM_ENABLE_THREADS |
114 | |
115 | class DynamicThreadPoolTaskDispatcher : public TaskDispatcher { |
116 | public: |
117 | void dispatch(std::unique_ptr<Task> T) override; |
118 | void shutdown() override; |
119 | private: |
120 | std::mutex DispatchMutex; |
121 | bool Running = true; |
122 | size_t Outstanding = 0; |
123 | std::condition_variable OutstandingCV; |
124 | }; |
125 | |
126 | #endif // LLVM_ENABLE_THREADS |
127 | |
128 | } // End namespace orc |
129 | } // End namespace llvm |
130 | |
131 | #endif // LLVM_EXECUTIONENGINE_ORC_TASKDISPATCH_H |
132 | |