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 #ifndef FFRT_QUEUE_HANDLER_H 16 #define FFRT_QUEUE_HANDLER_H 17 18 #include <atomic> 19 #include <memory> 20 #include <string> 21 #include <unordered_map> 22 #include "c/queue.h" 23 #include "c/queue_ext.h" 24 #include "cpp/task.h" 25 #include "base_queue.h" 26 #include "sched/execute_ctx.h" 27 28 namespace ffrt { 29 class QueueTask; 30 class SerialQueue; 31 class Loop; 32 33 class QueueHandler { 34 public: 35 QueueHandler(const char* name, const ffrt_queue_attr_t* attr, const int type = ffrt_queue_serial); 36 ~QueueHandler(); 37 38 void Cancel(); 39 void CancelAndWait(); 40 int Cancel(const char* name); 41 int Cancel(QueueTask* task); 42 void Dispatch(QueueTask* inTask); 43 void Submit(QueueTask* task); 44 void TransferTask(QueueTask* task); 45 46 std::string GetDfxInfo() const; 47 48 bool SetLoop(Loop* loop); 49 bool ClearLoop(); 50 51 QueueTask* PickUpTask(); 52 IsValidForLoop()53 inline bool IsValidForLoop() 54 { 55 return !isUsed_.load() && (queue_->GetQueueType() == ffrt_queue_concurrent 56 || queue_->GetQueueType() == ffrt_queue_eventhandler_interactive); 57 } 58 GetName()59 inline std::string GetName() 60 { 61 return name_; 62 } 63 GetQueueId()64 inline uint32_t GetQueueId() 65 { 66 FFRT_COND_DO_ERR((queue_ == nullptr), return 0, "queue construct failed"); 67 return queue_->GetQueueId(); 68 } 69 GetExecTaskId()70 inline uint32_t GetExecTaskId() const 71 { 72 return execTaskId_.load(); 73 } 74 HasTask(const char * name)75 inline bool HasTask(const char* name) 76 { 77 FFRT_COND_DO_ERR((queue_ == nullptr), return false, "[queueId=%u] constructed failed", GetQueueId()); 78 return queue_->HasTask(name); 79 } 80 GetTaskCnt()81 inline uint64_t GetTaskCnt() 82 { 83 FFRT_COND_DO_ERR((queue_ == nullptr), return false, "[queueId=%u] constructed failed", GetQueueId()); 84 return queue_->GetMapSize(); 85 } 86 87 bool IsIdle(); 88 void SetEventHandler(void* eventHandler); 89 void* GetEventHandler(); 90 91 int Dump(const char* tag, char* buf, uint32_t len, bool historyInfo = true); 92 int DumpSize(ffrt_inner_queue_priority_t priority); 93 GetQueue()94 inline const std::unique_ptr<BaseQueue>& GetQueue() 95 { 96 return queue_; 97 } 98 99 private: 100 void Deliver(); 101 void TransferInitTask(); 102 void SetTimeoutMonitor(QueueTask* task); 103 void RunTimeOutCallback(QueueTask* task); 104 105 void CheckOverload(); 106 void ReportTimeout(const std::vector<uint64_t>& timeoutTaskId); 107 void CheckSchedDeadline(); 108 void SendSchedTimer(TimePoint delay); 109 void AddSchedDeadline(QueueTask* task); 110 void RemoveSchedDeadline(QueueTask* task); 111 112 // queue info 113 std::string name_; 114 int qos_ = qos_default; 115 std::unique_ptr<BaseQueue> queue_ = nullptr; 116 std::atomic_bool isUsed_ = false; 117 std::atomic_uint64_t execTaskId_ = 0; 118 119 // for timeout watchdog 120 uint64_t timeout_ = 0; 121 std::atomic_int delayedCbCnt_ = {0}; 122 ffrt_function_header_t* timeoutCb_ = nullptr; 123 124 std::mutex mutex_; 125 bool initSchedTimer_ = false; 126 WaitUntilEntry* we_ = nullptr; 127 std::atomic_uint32_t overloadTimes_ = {1}; 128 std::unordered_map<QueueTask*, uint64_t> schedDeadline_; 129 }; 130 } // namespace ffrt 131 132 #endif // FFRT_QUEUE_HANDLER_H 133