• 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 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 <cstdint>
23 #include <queue>
24 
25 namespace panda::taskmanager {
26 
27 class TaskQueueId {
28 public:
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(TaskType::UNKNOWN, VMType::UNKNOWN);
57 
58 /**
59  * @brief TaskQueueInteface is an interface of thread-safe queue for tasks. Queues can be registered in TaskScheduler
60  * 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 
GetPriority()95     uint8_t GetPriority() const
96     {
97         // Atomic with acquire order reason: data race with priority_ with dependencies on reads after the
98         // load which should become visible
99         return priority_.load(std::memory_order_acquire);
100     }
101 
SetPriority(uint8_t priority)102     void SetPriority(uint8_t priority)
103     {
104         ASSERT(priority >= MIN_PRIORITY);
105         ASSERT(priority <= MAX_PRIORITY);
106         // Atomic with release order reason: data race with priority_ with no synchronization or ordering constraints
107         // imposed on other reads or writes
108         priority_.store(priority, std::memory_order_release);
109     }
110 
GetTaskType()111     TaskType GetTaskType() const
112     {
113         return taskType_;
114     }
115 
GetVMType()116     VMType GetVMType() const
117     {
118         return vmType_;
119     }
120 
121     /**
122      * @brief Method waits until internal queue will be empty and finalize using of TaskQueue
123      * After this method TaskQueue will not wait for new tasks.
124      */
125     void virtual WaitForQueueEmptyAndFinish() = 0;
126 
127 private:
128     TaskType taskType_;
129     VMType vmType_;
130     std::atomic_uint8_t priority_;
131 };
132 
133 }  // namespace panda::taskmanager
134 
135 #endif  // PANDA_LIBPANDABASE_TASKMANAGER_TASK_QUEUE_INTERFACE_H
136