• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 PANDA_LIBPANDABASE_TASKMANAGER_TASK_QUEUE_INTERFACE_H
17 #define PANDA_LIBPANDABASE_TASKMANAGER_TASK_QUEUE_INTERFACE_H
18 
19 #include "libpandabase/taskmanager/task.h"
20 #include "libpandabase/os/mutex.h"
21 #include <atomic>
22 #include <queue>
23 
24 namespace ark::taskmanager {
25 
26 class TaskQueueId {
27 public:
TaskQueueId()28     constexpr TaskQueueId() : TaskQueueId(TaskType::UNKNOWN, VMType::UNKNOWN) {}
TaskQueueId(TaskType tt,VMType vt)29     constexpr TaskQueueId(TaskType tt, VMType vt)
30         : val_(static_cast<uint16_t>(tt) |
31                static_cast<uint16_t>(static_cast<uint16_t>(vt) << (BITS_PER_BYTE * sizeof(TaskType))))
32     {
33         static_assert(sizeof(TaskType) == sizeof(TaskQueueId) / 2);
34         static_assert(sizeof(VMType) == sizeof(TaskQueueId) / 2);
35     }
36 
37     friend constexpr bool operator==(const TaskQueueId &lv, const TaskQueueId &rv)
38     {
39         return lv.val_ == rv.val_;
40     }
41 
42     friend constexpr bool operator!=(const TaskQueueId &lv, const TaskQueueId &rv)
43     {
44         return lv.val_ != rv.val_;
45     }
46 
47     friend constexpr bool operator<(const TaskQueueId &lv, const TaskQueueId &rv)
48     {
49         return lv.val_ < rv.val_;
50     }
51 
52 private:
53     uint16_t val_;
54 };
55 
56 constexpr TaskQueueId INVALID_TASKQUEUE_ID = TaskQueueId();
57 
58 /**
59  * @brief TaskQueueInteface is an interface of push-thread-safe queue for tasks. Queues can be registered in
60  * TaskScheduler and used to execute tasks on workers. Also, queues can notify other threads when a new task is pushed.
61  */
62 class TaskQueueInterface {
63 public:
64     NO_COPY_SEMANTIC(TaskQueueInterface);
65     NO_MOVE_SEMANTIC(TaskQueueInterface);
66 
67     static constexpr uint8_t MAX_PRIORITY = 10;
68     static constexpr uint8_t MIN_PRIORITY = 1;
69     static constexpr uint8_t DEFAULT_PRIORITY = 5;
70 
TaskQueueInterface(TaskType taskType,VMType vmType,uint8_t priority)71     PANDA_PUBLIC_API TaskQueueInterface(TaskType taskType, VMType vmType, uint8_t priority)
72         : taskType_(taskType), vmType_(vmType), priority_(priority)
73     {
74         ASSERT(priority >= MIN_PRIORITY);
75         ASSERT(priority <= MAX_PRIORITY);
76     }
77     PANDA_PUBLIC_API virtual ~TaskQueueInterface() = default;
78 
79     /**
80      * @brief Adds task in task queue. Operation is thread-safe.
81      * @param task - task that will be added
82      * @return the size of queue after @arg task was added to it.
83      */
84     PANDA_PUBLIC_API virtual size_t AddTask(Task &&task) = 0;
85 
86     [[nodiscard]] PANDA_PUBLIC_API virtual bool IsEmpty() const = 0;
87     [[nodiscard]] PANDA_PUBLIC_API virtual size_t Size() const = 0;
88 
89     /**
90      * @brief Method @returns true if queue does not have queue with specified execution mode
91      * @param mode - execution mode of tasks
92      */
93     [[nodiscard]] PANDA_PUBLIC_API virtual bool HasTaskWithExecutionMode(TaskExecutionMode mode) const = 0;
94 
95     [[nodiscard]] PANDA_PUBLIC_API virtual size_t CountOfTasksWithExecutionMode(TaskExecutionMode mode) const = 0;
96 
GetPriority()97     uint8_t GetPriority() const
98     {
99         // Atomic with acquire order reason: data race with priority_ with dependencies on reads after the
100         // load which should become visible
101         return priority_.load(std::memory_order_acquire);
102     }
103 
SetPriority(uint8_t priority)104     void SetPriority(uint8_t priority)
105     {
106         ASSERT(priority >= MIN_PRIORITY);
107         ASSERT(priority <= MAX_PRIORITY);
108         // Atomic with release order reason: data race with priority_ with no synchronization or ordering constraints
109         // imposed on other reads or writes
110         priority_.store(priority, std::memory_order_release);
111     }
112 
GetTaskType()113     TaskType GetTaskType() const
114     {
115         return taskType_;
116     }
117 
GetVMType()118     VMType GetVMType() const
119     {
120         return vmType_;
121     }
122 
123 private:
124     TaskType taskType_;
125     VMType vmType_;
126     std::atomic_uint8_t priority_;
127 };
128 
129 }  // namespace ark::taskmanager
130 
131 #endif  // PANDA_LIBPANDABASE_TASKMANAGER_TASK_QUEUE_INTERFACE_H
132