1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef API_CORE_THREADING_INTF_THREAD_POOL_H
17 #define API_CORE_THREADING_INTF_THREAD_POOL_H
18
19 #include <cstdint>
20
21 #include <base/containers/refcnt_ptr.h>
22 #include <base/containers/unique_ptr.h>
23 #include <base/containers/vector.h>
24 #include <base/namespace.h>
25 #include <base/util/uid.h>
26 #include <core/namespace.h>
27 #include <core/plugin/intf_interface.h>
28
29 BASE_BEGIN_NAMESPACE()
30 template<class T>
31 class array_view;
32 BASE_END_NAMESPACE()
33
CORE_BEGIN_NAMESPACE()34 CORE_BEGIN_NAMESPACE()
35 /** \addtogroup group_threading
36 * @{
37 */
38 /** Interface for thread safe thread pool.
39 * ITask instances pushed to the queue are executed in different threads and completing can be waited with the returned
40 * IResult.
41 */
42 class IThreadPool : public IInterface {
43 public:
44 static constexpr BASE_NS::Uid UID { "5b0d3810-cbcf-418a-a2e1-5df69fde1c09" };
45
46 using Ptr = BASE_NS::refcnt_ptr<IThreadPool>;
47
48 /** Interface for tasks that can be submitted to execution in the pool. */
49 class ITask {
50 public:
51 virtual void operator()() = 0;
52
53 struct Deleter {
54 constexpr Deleter() noexcept = default;
55 void operator()(ITask* ptr) const
56 {
57 ptr->Destroy();
58 }
59 };
60 using Ptr = BASE_NS::unique_ptr<ITask, Deleter>;
61
62 protected:
63 virtual ~ITask() = default;
64 virtual void Destroy() = 0;
65 };
66
67 /** Interface for result tasks that can be submitted to execution in the pool. */
68 class IResult {
69 public:
70 virtual void Wait() = 0;
71 virtual bool IsDone() const = 0;
72
73 struct Deleter {
74 constexpr Deleter() noexcept = default;
75 void operator()(IResult* ptr) const
76 {
77 ptr->Destroy();
78 }
79 };
80 using Ptr = BASE_NS::unique_ptr<IResult, Deleter>;
81
82 protected:
83 virtual ~IResult() = default;
84 virtual void Destroy() = 0;
85 };
86
87 /** Adds a task to be executed.
88 * @param task Pointer to a task instance.
89 * @return Pointer to a result instance which can be waited
90 */
91 virtual IResult::Ptr Push(ITask::Ptr task) = 0;
92
93 /** Adds a task to be executed.
94 * @param task Pointer to a task instance.
95 */
96 virtual void PushNoWait(ITask::Ptr task) = 0;
97
98 /** Get the number of threads this pool has.
99 * @return Total number of threads in the pool.
100 */
101 virtual uint32_t GetNumberOfThreads() const = 0;
102
103 protected:
104 virtual ~IThreadPool() = default;
105 };
106
107 class ITaskQueue {
108 public:
109 /** Adds a task to be executed later.
110 * @param taskIdentifier Identifier for the task.
111 * @param task Pointer to a task instance.
112 */
113 virtual void Submit(uint64_t taskIdentifier, IThreadPool::ITask::Ptr&& task) = 0;
114
115 /** Adds a task to be executed later with a dependency.
116 * @param afterIdentifier Identifier of the task that must be executed prior this task. If the identifier is
117 * unknown, the task will be added without dependency.
118 * @param taskIdentifier Identifier for the task.
119 * @param task Pointer to a task instance.
120 */
121 virtual void SubmitAfter(uint64_t afterIdentifier, uint64_t taskIdentifier, IThreadPool::ITask::Ptr&& task) = 0;
122
123 /** Adds a task to be executed later with multiple dependencies.
124 * @param afterIdentifiers Identifiers of the tasks that must be executed prior this task. Unknown identifiers will
125 * be skipped.
126 * @param taskIdentifier Identifier for the task.
127 * @param task Pointer to a task instance.
128 */
129 virtual void SubmitAfter(BASE_NS::array_view<const uint64_t> afterIdentifiers, uint64_t taskIdentifier,
130 IThreadPool::ITask::Ptr&& task) = 0;
131
132 /** Remove all tasks from queue. */
133 virtual void Clear() = 0;
134
135 /** Execute tasks in queue. */
136 virtual void Execute() = 0;
137 };
138
139 /** Thread safe task dispatcher, executes one task per execute call and removes it once it is finished.
140 */
141 class IDispatcherTaskQueue : public ITaskQueue {
142 public:
143 /** Reports finished tasks, allows to check which tasks have been completed.
144 * @return Task ids of tasks that have finished.
145 */
146 virtual BASE_NS::vector<uint64_t> CollectFinishedTasks() = 0;
147
148 struct Deleter {
149 constexpr Deleter() noexcept = default;
operatorDeleter150 void operator()(IDispatcherTaskQueue* ptr) const
151 {
152 ptr->Destroy();
153 }
154 };
155 using Ptr = BASE_NS::unique_ptr<IDispatcherTaskQueue, Deleter>;
156
157 protected:
158 IDispatcherTaskQueue() = default;
159 virtual ~IDispatcherTaskQueue() = default;
160 IDispatcherTaskQueue(const IDispatcherTaskQueue& other) = delete;
161 virtual void Destroy() = 0;
162 };
163
164 /** Non-thread safe parallel task queue, executes all tasks at once in parallel. This queue type is not thread safe and
165 * should be only used from one thread.
166 */
167 class IParallelTaskQueue : public ITaskQueue {
168 public:
169 struct Deleter {
170 constexpr Deleter() noexcept = default;
operatorDeleter171 void operator()(IParallelTaskQueue* ptr) const
172 {
173 ptr->Destroy();
174 }
175 };
176 using Ptr = BASE_NS::unique_ptr<IParallelTaskQueue, Deleter>;
177
178 protected:
179 IParallelTaskQueue() = default;
180 virtual ~IParallelTaskQueue() = default;
181 IParallelTaskQueue(const IParallelTaskQueue& other) = delete;
182 virtual void Destroy() = 0;
183 };
184
185 /** Non-thread safe sequential task queue, executes tasks sequentially one-by-one. This queue type is not thread safe
186 * and should be only used from one thread. */
187 class ISequentialTaskQueue : public ITaskQueue {
188 public:
189 struct Deleter {
190 constexpr Deleter() noexcept = default;
operatorDeleter191 void operator()(ISequentialTaskQueue* ptr) const
192 {
193 ptr->Destroy();
194 }
195 };
196 using Ptr = BASE_NS::unique_ptr<ISequentialTaskQueue, Deleter>;
197
198 protected:
199 ISequentialTaskQueue() = default;
200 virtual ~ISequentialTaskQueue() = default;
201 ISequentialTaskQueue(const ISequentialTaskQueue& other) = delete;
202 virtual void Destroy() = 0;
203 };
204
205 /** Factory for creating thread pools and task queues.
206 */
207 class ITaskQueueFactory : public IInterface {
208 public:
209 static constexpr BASE_NS::Uid UID { "5b0d3810-cbcf-418a-a2e1-5df69fde1c09" };
210
211 using Ptr = BASE_NS::refcnt_ptr<ITaskQueueFactory>;
212
213 /** Get the number of concurrent threads supported by the device.
214 * @return Number of concurrent threads supported.
215 */
216 virtual uint32_t GetNumberOfCores() const = 0;
217
218 /** Create a thread safe thread pool.
219 * @param threadCount number of threads created in the pool.
220 * @return Thread pool instance.
221 */
222 virtual IThreadPool::Ptr CreateThreadPool(const uint32_t threadCount) const = 0;
223
224 /** Create a thread safe task dispatcher.
225 * @param threadPool Optional thread pool.
226 * @return Task dispatcher instance.
227 */
228 virtual IDispatcherTaskQueue::Ptr CreateDispatcherTaskQueue(const IThreadPool::Ptr& threadPool) const = 0;
229
230 /** Create a non-thread safe parallel task queue.
231 * @param threadPool Thread pool where tasks are executed in parallel.
232 * @return Parallel task queue instance.
233 */
234 virtual IParallelTaskQueue::Ptr CreateParallelTaskQueue(const IThreadPool::Ptr& threadPool) const = 0;
235
236 /** Create a non-thread safe sequential task queue.
237 * @param threadPool Optional thread pool.
238 * @return Sequential task queue instance.
239 */
240 virtual ISequentialTaskQueue::Ptr CreateSequentialTaskQueue(const IThreadPool::Ptr& threadPool) const = 0;
241
242 protected:
243 virtual ~ITaskQueueFactory() = default;
244 };
245 /** @} */
246 CORE_END_NAMESPACE()
247
248 #endif // API_CORE_THREADING_INTF_THREAD_POOL_H
249