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