• 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_QUEUE_SET_H
17 #define LIBPANDABASE_TASKMANAGER_TASK_QUEUE_SET_H
18 
19 #include <queue>
20 #include "libpandabase/taskmanager/task_queue.h"
21 
22 namespace ark::taskmanager::internal {
23 
24 class TaskScheduler;
25 
26 class TaskQueueSet {
27 public:
28     explicit TaskQueueSet(TaskWaitList *waitList,
29                           TaskTimeStatsType taskTimeStatsType = TaskTimeStatsType::NO_STATISTICS);
30     ~TaskQueueSet();
31     NO_COPY_SEMANTIC(TaskQueueSet);
32     NO_MOVE_SEMANTIC(TaskQueueSet);
33 
34     template <class Allocator>
35     TaskQueueInterface *CreateQueue(QueuePriority priority);
36     template <class Allocator>
37     void DeleteQueue(TaskQueueInterface *queue);
38     TaskQueueInterface *GetQueue(QueueId id);
39     TaskQueueInterface *SelectQueue();
40     bool AreQueuesEmpty() const;
41     size_t GetCountOfLiveTasks() const;
42 
SetCallbacks(std::function<void ()> signalWorkersCallback)43     void SetCallbacks(std::function<void()> signalWorkersCallback)
44     {
45         signalWorkersCallback_ = std::move(signalWorkersCallback);
46     }
47     TaskTimeStatsBase *GetTaskTimeStats() const;
48 
49 private:
50     TaskWaitList *waitList_ = nullptr;
51     std::function<void()> signalWorkersCallback_;
52     std::function<void()> signalWaitersCallback_;
53     TaskTimeStatsBase *taskTimeStats_ = nullptr;
54     std::atomic_size_t selectionIndex_ {0};
55     std::array<std::atomic<TaskQueueInterface *>, MAX_COUNT_OF_QUEUE> queues_ {};
56     std::queue<std::function<void()>> deleterQueue_;
57 };
58 
59 template <class Allocator>
60 // CC-OFFNXT(G.FUD.06) Splitting this function will degrade readability. Keyword "inline" needs to satisfy ODR rule.
CreateQueue(QueuePriority priority)61 inline TaskQueueInterface *TaskQueueSet::CreateQueue(QueuePriority priority)
62 {
63     size_t i = 0;
64     auto *queue = internal::TaskQueue<Allocator>::Create(priority, waitList_, taskTimeStats_);
65     while (i != MAX_COUNT_OF_QUEUE) {
66         for (i = 0; i < MAX_COUNT_OF_QUEUE; i++) {
67             // Atomic with relaxed order reason: no order dependency with another variables
68             if (queues_[i].load(std::memory_order_relaxed) != nullptr) {
69                 continue;
70             }
71             TaskQueueInterface *nullp = nullptr;
72             // Atomic with relaxed order reason: no order dependency with another variables
73             if (!queues_[i].compare_exchange_weak(nullp, queue, std::memory_order_relaxed)) {
74                 break;
75             }
76             queue->Register(i);
77             ASSERT(signalWorkersCallback_ != nullptr);
78             queue->SetCallbacks(signalWorkersCallback_);
79             return queue;
80         }
81     }
82     internal::TaskQueue<Allocator>::Destroy(queue);
83     return nullptr;
84 }
85 
86 template <class Allocator>
DeleteQueue(TaskQueueInterface * queue)87 inline void TaskQueueSet::DeleteQueue(TaskQueueInterface *queue)
88 {
89     while (!queue->IsEmpty()) {
90         queue->ExecuteTask();
91     }
92     queue->WaitTasks();
93     auto id = queue->GetQueueId();
94     // Atomic with relaxed order reason: no order dependency with another variables
95     ASSERT(queues_[id].load(std::memory_order_relaxed) == queue);
96     // Atomic with relaxed order reason: no order dependency with another variables
97     queues_[id].store(nullptr, std::memory_order_relaxed);
98     deleterQueue_.push([queue] {
99         internal::TaskQueue<Allocator>::Destroy(static_cast<internal::SchedulableTaskQueueInterface *>(queue));
100     });
101 }
102 
103 }  // namespace ark::taskmanager::internal
104 
105 #endif  // LIBPANDABASE_TASKMANAGER_TASK_QUEUE_SET_H
106