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