• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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