Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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 |