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