• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 LIBPANDABASE_TASKMANAGER_TASK_MANAGER_H
17 #define LIBPANDABASE_TASKMANAGER_TASK_MANAGER_H
18 
19 #include "libpandabase/taskmanager/task_queue_set.h"
20 #include "libpandabase/taskmanager/task_scheduler.h"
21 #include "libpandabase/taskmanager/utils/task_time_stats.h"
22 #include "libpandabase/macros.h"
23 
24 namespace ark::taskmanager {
25 
26 using TaskPtr = internal::TaskPtr;
27 
28 /**
29  * @brief TaskManager it's singletone that provide interfaces for usage of multithreading subsystem. You can create
30  * TaskQueue by CreateTaskQueue method and use it to push-in your functors.
31  *
32  * Base usage scenario:
33  * 1. You start scope of TaskManager usage this TaskManager::Start method;
34  * 2. Next you create queue for pushing tasks. Use TaskManager::CreateTaskQueue method;
35  * 3. Now you are free to use mutlithreading subsutem. Try to reduce usage of sync tools like mutexes in your tasks;
36  * 4. If you want to finish usage of TaskManager, first you need to be sure that all queues are empty.
37  *    You can do this only by wait method in TaskQueue;
38  * 5. When you are sure that queues are empty use TaskManager:Finish to finilize usage of threads.
39  */
40 class TaskManager {
41 public:
42     /**
43      * @brief Method creates task manager with specified count of workers. Also you can specify usage of execution time
44      * stats collection. Method creates count of workers that can execute tasks from TaskQueue. This method can be
45      * called next time only after execution of the TaskManager::Finish() method.
46      * @see TaskManager::Finish()
47      */
48     static PANDA_PUBLIC_API void Start(size_t workerCount,
49                                        TaskTimeStatsType statsType = TaskTimeStatsType::NO_STATISTICS);
50     /**
51      * @brief Method finishs usage of TaskManager. All TaskQueues should be deleted before calling. This method can be
52      * called after TaskManager::Start(...) method.
53      */
54     static PANDA_PUBLIC_API void Finish();
55     /// @returns true if task manager exists, otherwise false
56     static PANDA_PUBLIC_API bool IsUsed();
57     /**
58      * @brief Method allocates TaskQueue. It's importent that lifetime of Allocator should be more then TaskMananger
59      * usage scope!
60      * @return TaskQueueInterface pointer that can be used to interact with TaskQueue. This pointer should be freed by
61      * TaskManager::DestroyTaskQueue method.
62      * @see class TaskQueueInterface, @see TaskManager::DestroyTaskQueue
63      */
64     template <class Allocator = std::allocator<TaskPtr>>
65     static PANDA_PUBLIC_API TaskQueueInterface *CreateTaskQueue(QueuePriority priority = DEFAULT_QUEUE_PRIORITY);
66     /// @brief Method returns pointer to TaskQueue by queue id.
67     static PANDA_PUBLIC_API TaskQueueInterface *GetTaskQueue(QueueId id);
68     /**
69      * @brief Method creates callback that will delete queue. It's importent that lifetime of Allocator should be more
70      * then TaskMananger usage scope!
71      */
72     template <class Allocator = std::allocator<TaskPtr>>
73     static PANDA_PUBLIC_API void DestroyTaskQueue(TaskQueueInterface *queue);
74     /**
75      * @brief Method chages count of currect workers.
76      *  - if new count is more then current one, method will create new workers;
77      *  - if new count is less then current one, method will wait for finish excess workers;
78      *  - if new count is equel to current one, method to nothing;
79      *  - if you set 0, all workers will be disabled, and existed tasks will wait in queues.
80      */
81     static PANDA_PUBLIC_API void SetWorkersCount(size_t count);
82     /// @returns count of workers
83     static PANDA_PUBLIC_API size_t GetWorkersCount();
84 
85     NO_COPY_SEMANTIC(TaskManager);
86     NO_MOVE_SEMANTIC(TaskManager);
87 
88 private:
89     TaskManager(size_t workerCount, TaskTimeStatsType statsType);
90     ~TaskManager() = default;
91 
92     TaskWaitList waitList_;
93     internal::TaskQueueSet queueSet_;
94     internal::TaskScheduler scheduler_;
95 
96     PANDA_PUBLIC_API static TaskManager *inst_;
97 };
98 
99 template <class Allocator>
CreateTaskQueue(QueuePriority priority)100 inline PANDA_PUBLIC_API TaskQueueInterface *TaskManager::CreateTaskQueue(QueuePriority priority)
101 {
102     ASSERT(inst_ != nullptr);
103     return inst_->queueSet_.CreateQueue<Allocator>(priority);
104 }
105 
106 template <class Allocator>
DestroyTaskQueue(TaskQueueInterface * queue)107 inline PANDA_PUBLIC_API void TaskManager::DestroyTaskQueue(TaskQueueInterface *queue)
108 {
109     ASSERT(inst_ != nullptr);
110     inst_->queueSet_.DeleteQueue<Allocator>(queue);
111 }
112 
113 }  // namespace ark::taskmanager
114 
115 #endif  // LIBPANDABASE_TASKMANAGER_TASK_MANAGER_H
116