1 /*
2 * Copyright (C) 2023 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/unique_ptr.h>
22 #include <base/containers/vector.h>
23 #include <core/namespace.h>
24 #include <core/plugin/intf_interface.h>
25
CORE_BEGIN_NAMESPACE()26 CORE_BEGIN_NAMESPACE()
27 /** \addtogroup group_threading
28 * @{
29 */
30 /** Interface for thread safe thread pool.
31 * ITask instances pushed to the queue are executed in different threads and completing can be waited with the returned
32 * IResult.
33 */
34 class IThreadPool : public IInterface {
35 public:
36 static constexpr BASE_NS::Uid UID { "5b0d3810-cbcf-418a-a2e1-5df69fde1c09" };
37
38 using Ptr = BASE_NS::refcnt_ptr<IThreadPool>;
39
40 /** Interface for tasks that can be submitted to execution in the pool. */
41 class ITask {
42 public:
43 virtual void operator()() = 0;
44
45 struct Deleter {
46 constexpr Deleter() noexcept = default;
47 void operator()(ITask* ptr) const
48 {
49 ptr->Destroy();
50 }
51 };
52 using Ptr = BASE_NS::unique_ptr<ITask, Deleter>;
53
54 protected:
55 virtual ~ITask() = default;
56 virtual void Destroy() = 0;
57 };
58
59 /** Interface for result tasks that can be submitted to execution in the pool. */
60 class IResult {
61 public:
62 virtual void Wait() = 0;
63
64 struct Deleter {
65 constexpr Deleter() noexcept = default;
66 void operator()(IResult* ptr) const
67 {
68 ptr->Destroy();
69 }
70 };
71 using Ptr = BASE_NS::unique_ptr<IResult, Deleter>;
72
73 protected:
74 virtual ~IResult() = default;
75 virtual void Destroy() = 0;
76 };
77
78 /** Adds a task to be executed.
79 * @param task Pointer to a task instance.
80 * @return Pointer to a result instance which can be waited
81 */
82 virtual IResult::Ptr Push(ITask::Ptr task) = 0;
83
84 /** Adds a task to be executed.
85 * @param task Pointer to a task instance.
86 */
87 virtual void PushNoWait(ITask::Ptr task) = 0;
88
89 /** Get the number of threads this pool has.
90 * @return Total number of threads in the pool.
91 */
92 virtual uint32_t GetNumberOfThreads() const = 0;
93
94 protected:
95 virtual ~IThreadPool() = default;
96 };
97
98 class ITaskQueue {
99 public:
100 /** Adds a task to be executed later.
101 * @param taskIdentifier Identifier for the task.
102 * @param task Pointer to a task instance.
103 */
104 virtual void Submit(uint64_t taskIdentifier, IThreadPool::ITask::Ptr&& task) = 0;
105
106 /** Adds a task to be executed later with a dependency.
107 * @param afterIdentifier Identifier of the task that must be executed prior this task. If the identifier is
108 * unknown, the task will be added without dependency.
109 * @param taskIdentifier Identifier for the task.
110 * @param task Pointer to a task instance.
111 */
112 virtual void SubmitAfter(uint64_t afterIdentifier, uint64_t taskIdentifier, IThreadPool::ITask::Ptr&& task) = 0;
113
114 /** Remove all tasks from queue. */
115 virtual void Clear() = 0;
116
117 /** Execute tasks in queue. */
118 virtual void Execute() = 0;
119 };
120
121 /** Thread safe task dispatcher, executes one task per execute call and removes it once it is finished.
122 */
123 class IDispatcherTaskQueue : public ITaskQueue {
124 public:
125 /** Reports finished tasks, allows to check which tasks have been completed.
126 * @return Task ids of tasks that have finished.
127 */
128 virtual BASE_NS::vector<uint64_t> CollectFinishedTasks() = 0;
129
130 struct Deleter {
131 constexpr Deleter() noexcept = default;
operatorDeleter132 void operator()(IDispatcherTaskQueue* ptr) const
133 {
134 ptr->Destroy();
135 }
136 };
137 using Ptr = BASE_NS::unique_ptr<IDispatcherTaskQueue, Deleter>;
138
139 protected:
140 IDispatcherTaskQueue() = default;
141 virtual ~IDispatcherTaskQueue() = default;
142 IDispatcherTaskQueue(const IDispatcherTaskQueue& other) = delete;
143 virtual void Destroy() = 0;
144 };
145
146 /** Non-thread safe parallel task queue, executes all tasks at once in parallel. This queue type is not thread safe and
147 * should be only used from one thread.
148 */
149 class IParallelTaskQueue : public ITaskQueue {
150 public:
151 struct Deleter {
152 constexpr Deleter() noexcept = default;
operatorDeleter153 void operator()(IParallelTaskQueue* ptr) const
154 {
155 ptr->Destroy();
156 }
157 };
158 using Ptr = BASE_NS::unique_ptr<IParallelTaskQueue, Deleter>;
159
160 protected:
161 IParallelTaskQueue() = default;
162 virtual ~IParallelTaskQueue() = default;
163 IParallelTaskQueue(const IParallelTaskQueue& other) = delete;
164 virtual void Destroy() = 0;
165 };
166
167 /** Non-thread safe sequential task queue, executes tasks sequentially one-by-one. This queue type is not thread safe
168 * and should be only used from one thread. */
169 class ISequentialTaskQueue : public ITaskQueue {
170 public:
171 struct Deleter {
172 constexpr Deleter() noexcept = default;
operatorDeleter173 void operator()(ISequentialTaskQueue* ptr) const
174 {
175 ptr->Destroy();
176 }
177 };
178 using Ptr = BASE_NS::unique_ptr<ISequentialTaskQueue, Deleter>;
179
180 protected:
181 ISequentialTaskQueue() = default;
182 virtual ~ISequentialTaskQueue() = default;
183 ISequentialTaskQueue(const ISequentialTaskQueue& other) = delete;
184 virtual void Destroy() = 0;
185 };
186
187 /** Factory for creating thread pools and task queues.
188 */
189 class ITaskQueueFactory : public IInterface {
190 public:
191 static constexpr BASE_NS::Uid UID { "5b0d3810-cbcf-418a-a2e1-5df69fde1c09" };
192
193 using Ptr = BASE_NS::refcnt_ptr<ITaskQueueFactory>;
194
195 /** Get the number of concurrent threads supported by the device.
196 * @return Number of concurrent threads supported.
197 */
198 virtual uint32_t GetNumberOfCores() const = 0;
199
200 /** Create a thread safe thread pool.
201 * @param threadCount number of threads created in the pool.
202 * @return Thread pool instance.
203 */
204 virtual IThreadPool::Ptr CreateThreadPool(const uint32_t threadCount) const = 0;
205
206 /** Create a thread safe task dispatcher.
207 * @param threadPool Optional thread pool.
208 * @return Task dispatcher instance.
209 */
210 virtual IDispatcherTaskQueue::Ptr CreateDispatcherTaskQueue(const IThreadPool::Ptr& threadPool) const = 0;
211
212 /** Create a non-thread safe parallel task queue.
213 * @param threadPool Thread pool where tasks are executed in parallel.
214 * @return Parallel task queue instance.
215 */
216 virtual IParallelTaskQueue::Ptr CreateParallelTaskQueue(const IThreadPool::Ptr& threadPool) const = 0;
217
218 /** Create a non-thread safe sequential task queue.
219 * @param threadPool Optional thread pool.
220 * @return Sequential task queue instance.
221 */
222 virtual ISequentialTaskQueue::Ptr CreateSequentialTaskQueue(const IThreadPool::Ptr& threadPool) const = 0;
223
224 protected:
225 virtual ~ITaskQueueFactory() = default;
226 };
227 /** @} */
228 CORE_END_NAMESPACE()
229
230 #endif // API_CORE_THREADING_INTF_THREAD_POOL_H
231