1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci#include "queue_handler.h"
16484543d1Sopenharmony_ci#include <sstream>
17484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h"
18484543d1Sopenharmony_ci#include "dfx/trace_record/ffrt_trace_record.h"
19484543d1Sopenharmony_ci#include "queue_monitor.h"
20484543d1Sopenharmony_ci#include "util/event_handler_adapter.h"
21484543d1Sopenharmony_ci#include "util/ffrt_facade.h"
22484543d1Sopenharmony_ci#include "util/slab.h"
23484543d1Sopenharmony_ci#include "tm/queue_task.h"
24484543d1Sopenharmony_ci#include "concurrent_queue.h"
25484543d1Sopenharmony_ci#include "eventhandler_adapter_queue.h"
26484543d1Sopenharmony_ci#include "sched/scheduler.h"
27484543d1Sopenharmony_ci
28484543d1Sopenharmony_cinamespace {
29484543d1Sopenharmony_ciconstexpr int PROCESS_NAME_BUFFER_LENGTH = 1024;
30484543d1Sopenharmony_ciconstexpr uint32_t STRING_SIZE_MAX = 128;
31484543d1Sopenharmony_ciconstexpr uint32_t TASK_DONE_WAIT_UNIT = 10;
32484543d1Sopenharmony_ci}
33484543d1Sopenharmony_ci
34484543d1Sopenharmony_cinamespace ffrt {
35484543d1Sopenharmony_ciQueueHandler::QueueHandler(const char* name, const ffrt_queue_attr_t* attr, const int type)
36484543d1Sopenharmony_ci{
37484543d1Sopenharmony_ci    // parse queue attribute
38484543d1Sopenharmony_ci    if (attr) {
39484543d1Sopenharmony_ci        qos_ = (ffrt_queue_attr_get_qos(attr) >= ffrt_qos_background) ? ffrt_queue_attr_get_qos(attr) : qos_;
40484543d1Sopenharmony_ci        timeout_ = ffrt_queue_attr_get_timeout(attr);
41484543d1Sopenharmony_ci        timeoutCb_ = ffrt_queue_attr_get_callback(attr);
42484543d1Sopenharmony_ci    }
43484543d1Sopenharmony_ci
44484543d1Sopenharmony_ci    // callback reference counting is to ensure life cycle
45484543d1Sopenharmony_ci    if (timeout_ > 0 && timeoutCb_ != nullptr) {
46484543d1Sopenharmony_ci        QueueTask* cbTask = GetQueueTaskByFuncStorageOffset(timeoutCb_);
47484543d1Sopenharmony_ci        cbTask->IncDeleteRef();
48484543d1Sopenharmony_ci    }
49484543d1Sopenharmony_ci
50484543d1Sopenharmony_ci    queue_ = CreateQueue(type, attr);
51484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return, "[queueId=%u] constructed failed", GetQueueId());
52484543d1Sopenharmony_ci
53484543d1Sopenharmony_ci    if (name != nullptr && std::string(name).size() <= STRING_SIZE_MAX) {
54484543d1Sopenharmony_ci        name_ = "sq_" + std::string(name) + "_" + std::to_string(GetQueueId());
55484543d1Sopenharmony_ci    } else {
56484543d1Sopenharmony_ci        name_ += "sq_unnamed_" + std::to_string(GetQueueId());
57484543d1Sopenharmony_ci        FFRT_LOGW("failed to set [queueId=%u] name due to invalid name or length.", GetQueueId());
58484543d1Sopenharmony_ci    }
59484543d1Sopenharmony_ci
60484543d1Sopenharmony_ci    QueueMonitor::GetInstance().RegisterQueueId(GetQueueId(), this);
61484543d1Sopenharmony_ci    FFRT_LOGI("construct %s succ, qos[%d]", name_.c_str(), qos_);
62484543d1Sopenharmony_ci}
63484543d1Sopenharmony_ci
64484543d1Sopenharmony_ciQueueHandler::~QueueHandler()
65484543d1Sopenharmony_ci{
66484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return, "cannot destruct, [queueId=%u] constructed failed", GetQueueId());
67484543d1Sopenharmony_ci    FFRT_LOGI("destruct %s enter", name_.c_str());
68484543d1Sopenharmony_ci    // clear tasks in queue
69484543d1Sopenharmony_ci    queue_->Stop();
70484543d1Sopenharmony_ci    while (QueueMonitor::GetInstance().QueryQueueStatus(GetQueueId()) || queue_->GetActiveStatus()) {
71484543d1Sopenharmony_ci        std::this_thread::sleep_for(std::chrono::microseconds(TASK_DONE_WAIT_UNIT));
72484543d1Sopenharmony_ci    }
73484543d1Sopenharmony_ci    QueueMonitor::GetInstance().ResetQueueStruct(GetQueueId());
74484543d1Sopenharmony_ci
75484543d1Sopenharmony_ci    // release callback resource
76484543d1Sopenharmony_ci    if (timeout_ > 0) {
77484543d1Sopenharmony_ci        // wait for all delayedWorker to complete.
78484543d1Sopenharmony_ci        while (delayedCbCnt_.load() > 0) {
79484543d1Sopenharmony_ci            this_task::sleep_for(std::chrono::microseconds(timeout_));
80484543d1Sopenharmony_ci        }
81484543d1Sopenharmony_ci
82484543d1Sopenharmony_ci        if (timeoutCb_ != nullptr) {
83484543d1Sopenharmony_ci            QueueTask* cbTask = GetQueueTaskByFuncStorageOffset(timeoutCb_);
84484543d1Sopenharmony_ci            cbTask->DecDeleteRef();
85484543d1Sopenharmony_ci        }
86484543d1Sopenharmony_ci    }
87484543d1Sopenharmony_ci    FFRT_LOGI("destruct %s leave", name_.c_str());
88484543d1Sopenharmony_ci}
89484543d1Sopenharmony_ci
90484543d1Sopenharmony_cibool QueueHandler::SetLoop(Loop* loop)
91484543d1Sopenharmony_ci{
92484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return false, "[queueId=%u] constructed failed", GetQueueId());
93484543d1Sopenharmony_ci    if (queue_->GetQueueType() == ffrt_queue_eventhandler_interactive) {
94484543d1Sopenharmony_ci        return true;
95484543d1Sopenharmony_ci    }
96484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_->GetQueueType() != ffrt_queue_concurrent),
97484543d1Sopenharmony_ci        return false, "[queueId=%u] type invalid", GetQueueId());
98484543d1Sopenharmony_ci    return reinterpret_cast<ConcurrentQueue*>(queue_.get())->SetLoop(loop);
99484543d1Sopenharmony_ci}
100484543d1Sopenharmony_ci
101484543d1Sopenharmony_cibool QueueHandler::ClearLoop()
102484543d1Sopenharmony_ci{
103484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return false, "[queueId=%u] constructed failed", GetQueueId());
104484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_->GetQueueType() != ffrt_queue_concurrent),
105484543d1Sopenharmony_ci        return false, "[queueId=%u] type invalid", GetQueueId());
106484543d1Sopenharmony_ci    return reinterpret_cast<ConcurrentQueue*>(queue_.get())->ClearLoop();
107484543d1Sopenharmony_ci}
108484543d1Sopenharmony_ci
109484543d1Sopenharmony_ciQueueTask* QueueHandler::PickUpTask()
110484543d1Sopenharmony_ci{
111484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return nullptr, "[queueId=%u] constructed failed", GetQueueId());
112484543d1Sopenharmony_ci    return queue_->Pull();
113484543d1Sopenharmony_ci}
114484543d1Sopenharmony_ci
115484543d1Sopenharmony_civoid QueueHandler::Submit(QueueTask* task)
116484543d1Sopenharmony_ci{
117484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return, "cannot submit, [queueId=%u] constructed failed", GetQueueId());
118484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((task == nullptr), return, "input invalid, serial task is nullptr");
119484543d1Sopenharmony_ci
120484543d1Sopenharmony_ci    // if qos not specified, qos of the queue is inherited by task
121484543d1Sopenharmony_ci    if (task->GetQos() == qos_inherit || task->GetQos() == qos_default) {
122484543d1Sopenharmony_ci        task->SetQos(qos_);
123484543d1Sopenharmony_ci    }
124484543d1Sopenharmony_ci
125484543d1Sopenharmony_ci    uint64_t gid = task->gid;
126484543d1Sopenharmony_ci    FFRT_SERIAL_QUEUE_TASK_SUBMIT_MARKER(GetQueueId(), gid);
127484543d1Sopenharmony_ci    FFRTTraceRecord::TaskSubmit(&(task->createTime), &(task->fromTid));
128484543d1Sopenharmony_ci#if (FFRT_TRACE_RECORD_LEVEL < FFRT_TRACE_RECORD_LEVEL_1)
129484543d1Sopenharmony_ci    if (queue_->GetQueueType() == ffrt_queue_eventhandler_adapter) {
130484543d1Sopenharmony_ci        task->fromTid = ExecuteCtx::Cur()->tid;
131484543d1Sopenharmony_ci    }
132484543d1Sopenharmony_ci#endif
133484543d1Sopenharmony_ci    int ret = queue_->Push(task);
134484543d1Sopenharmony_ci    if (ret == SUCC) {
135484543d1Sopenharmony_ci        FFRT_LOGD("submit task[%lu] into %s", gid, name_.c_str());
136484543d1Sopenharmony_ci        return;
137484543d1Sopenharmony_ci    }
138484543d1Sopenharmony_ci    if (ret == FAILED) {
139484543d1Sopenharmony_ci        return;
140484543d1Sopenharmony_ci    }
141484543d1Sopenharmony_ci
142484543d1Sopenharmony_ci    if (!isUsed_.load()) {
143484543d1Sopenharmony_ci        isUsed_.store(true);
144484543d1Sopenharmony_ci    }
145484543d1Sopenharmony_ci
146484543d1Sopenharmony_ci    // activate queue
147484543d1Sopenharmony_ci    if (task->GetDelay() == 0) {
148484543d1Sopenharmony_ci        FFRT_LOGD("task [%llu] activate %s", gid, name_.c_str());
149484543d1Sopenharmony_ci        TransferTask(task);
150484543d1Sopenharmony_ci    } else {
151484543d1Sopenharmony_ci        FFRT_LOGD("task [%llu] with delay [%llu] activate %s", gid, task->GetDelay(), name_.c_str());
152484543d1Sopenharmony_ci        if (ret == INACTIVE) {
153484543d1Sopenharmony_ci            queue_->Push(task);
154484543d1Sopenharmony_ci        }
155484543d1Sopenharmony_ci        TransferInitTask();
156484543d1Sopenharmony_ci    }
157484543d1Sopenharmony_ci}
158484543d1Sopenharmony_ci
159484543d1Sopenharmony_civoid QueueHandler::Cancel()
160484543d1Sopenharmony_ci{
161484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return, "cannot cancel, [queueId=%u] constructed failed", GetQueueId());
162484543d1Sopenharmony_ci    queue_->Remove();
163484543d1Sopenharmony_ci}
164484543d1Sopenharmony_ci
165484543d1Sopenharmony_civoid QueueHandler::CancelAndWait()
166484543d1Sopenharmony_ci{
167484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return, "cannot cancelAndWait, [queueId=%u] constructed failed",
168484543d1Sopenharmony_ci        GetQueueId());
169484543d1Sopenharmony_ci    queue_->Remove();
170484543d1Sopenharmony_ci    while (QueueMonitor::GetInstance().QueryQueueStatus(GetQueueId()) != 0 || queue_->GetActiveStatus()) {
171484543d1Sopenharmony_ci        std::this_thread::sleep_for(std::chrono::microseconds(TASK_DONE_WAIT_UNIT));
172484543d1Sopenharmony_ci    }
173484543d1Sopenharmony_ci}
174484543d1Sopenharmony_ci
175484543d1Sopenharmony_ciint QueueHandler::Cancel(const char* name)
176484543d1Sopenharmony_ci{
177484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return INACTIVE,
178484543d1Sopenharmony_ci         "cannot cancel, [queueId=%u] constructed failed", GetQueueId());
179484543d1Sopenharmony_ci    int ret = queue_->Remove(name);
180484543d1Sopenharmony_ci    if (ret != SUCC) {
181484543d1Sopenharmony_ci        FFRT_LOGD("cancel task %s failed, task may have been executed", name);
182484543d1Sopenharmony_ci    }
183484543d1Sopenharmony_ci
184484543d1Sopenharmony_ci    return ret;
185484543d1Sopenharmony_ci}
186484543d1Sopenharmony_ci
187484543d1Sopenharmony_ciint QueueHandler::Cancel(QueueTask* task)
188484543d1Sopenharmony_ci{
189484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return INACTIVE,
190484543d1Sopenharmony_ci         "cannot cancel, [queueId=%u] constructed failed", GetQueueId());
191484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((task == nullptr), return INACTIVE, "input invalid, serial task is nullptr");
192484543d1Sopenharmony_ci
193484543d1Sopenharmony_ci    int ret = queue_->Remove(task);
194484543d1Sopenharmony_ci    if (ret == SUCC) {
195484543d1Sopenharmony_ci        FFRT_LOGD("cancel task[%llu] %s succ", task->gid, task->label.c_str());
196484543d1Sopenharmony_ci        task->Notify();
197484543d1Sopenharmony_ci        task->Destroy();
198484543d1Sopenharmony_ci    } else {
199484543d1Sopenharmony_ci        FFRT_LOGD("cancel task[%llu] %s failed, task may have been executed", task->gid, task->label.c_str());
200484543d1Sopenharmony_ci    }
201484543d1Sopenharmony_ci    return ret;
202484543d1Sopenharmony_ci}
203484543d1Sopenharmony_ci
204484543d1Sopenharmony_civoid QueueHandler::Dispatch(QueueTask* inTask)
205484543d1Sopenharmony_ci{
206484543d1Sopenharmony_ci    QueueTask* nextTask = nullptr;
207484543d1Sopenharmony_ci    for (QueueTask* task = inTask; task != nullptr; task = nextTask) {
208484543d1Sopenharmony_ci        // dfx watchdog
209484543d1Sopenharmony_ci        SetTimeoutMonitor(task);
210484543d1Sopenharmony_ci        QueueMonitor::GetInstance().UpdateQueueInfo(GetQueueId(), task->gid);
211484543d1Sopenharmony_ci
212484543d1Sopenharmony_ci        // run user task
213484543d1Sopenharmony_ci        FFRT_LOGD("run task [gid=%llu], queueId=%u", task->gid, GetQueueId());
214484543d1Sopenharmony_ci        auto f = reinterpret_cast<ffrt_function_header_t*>(task->func_storage);
215484543d1Sopenharmony_ci        FFRT_SERIAL_QUEUE_TASK_EXECUTE_MARKER(task->gid);
216484543d1Sopenharmony_ci        FFRTTraceRecord::TaskExecute(&(task->executeTime));
217484543d1Sopenharmony_ci        uint64_t triggerTime{0};
218484543d1Sopenharmony_ci        if (queue_->GetQueueType() == ffrt_queue_eventhandler_adapter) {
219484543d1Sopenharmony_ci            triggerTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
220484543d1Sopenharmony_ci                std::chrono::steady_clock::now().time_since_epoch()).count());
221484543d1Sopenharmony_ci        }
222484543d1Sopenharmony_ci
223484543d1Sopenharmony_ci        f->exec(f);
224484543d1Sopenharmony_ci        FFRTTraceRecord::TaskDone<ffrt_queue_task>(task->GetQos(), task);
225484543d1Sopenharmony_ci        if (queue_->GetQueueType() == ffrt_queue_eventhandler_adapter) {
226484543d1Sopenharmony_ci            uint64_t completeTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
227484543d1Sopenharmony_ci                std::chrono::steady_clock::now().time_since_epoch()).count());
228484543d1Sopenharmony_ci            reinterpret_cast<EventHandlerAdapterQueue*>(queue_.get())->PushHistoryTask(task, triggerTime, completeTime);
229484543d1Sopenharmony_ci        }
230484543d1Sopenharmony_ci
231484543d1Sopenharmony_ci        f->destroy(f);
232484543d1Sopenharmony_ci        task->Notify();
233484543d1Sopenharmony_ci        RemoveTimeoutMonitor(task);
234484543d1Sopenharmony_ci
235484543d1Sopenharmony_ci        // run task batch
236484543d1Sopenharmony_ci        nextTask = task->GetNextTask();
237484543d1Sopenharmony_ci        if (nextTask == nullptr) {
238484543d1Sopenharmony_ci            QueueMonitor::GetInstance().ResetQueueInfo(GetQueueId());
239484543d1Sopenharmony_ci            if (!queue_->IsOnLoop()) {
240484543d1Sopenharmony_ci                Deliver();
241484543d1Sopenharmony_ci            }
242484543d1Sopenharmony_ci        }
243484543d1Sopenharmony_ci        task->DecDeleteRef();
244484543d1Sopenharmony_ci    }
245484543d1Sopenharmony_ci}
246484543d1Sopenharmony_ci
247484543d1Sopenharmony_civoid QueueHandler::Deliver()
248484543d1Sopenharmony_ci{
249484543d1Sopenharmony_ci    QueueTask* task = queue_->Pull();
250484543d1Sopenharmony_ci    if (task != nullptr) {
251484543d1Sopenharmony_ci        TransferTask(task);
252484543d1Sopenharmony_ci    }
253484543d1Sopenharmony_ci}
254484543d1Sopenharmony_ci
255484543d1Sopenharmony_civoid QueueHandler::TransferTask(QueueTask* task)
256484543d1Sopenharmony_ci{
257484543d1Sopenharmony_ci    auto entry = &task->fq_we;
258484543d1Sopenharmony_ci    if (queue_->GetQueueType() == ffrt_queue_eventhandler_adapter) {
259484543d1Sopenharmony_ci        reinterpret_cast<EventHandlerAdapterQueue*>(queue_.get())->SetCurrentRunningTask(task);
260484543d1Sopenharmony_ci    }
261484543d1Sopenharmony_ci    FFRTScheduler* sch = FFRTFacade::GetSchedInstance();
262484543d1Sopenharmony_ci    FFRT_READY_MARKER(task->gid); // ffrt queue task ready to enque
263484543d1Sopenharmony_ci    if (!sch->InsertNode(&entry->node, task->GetQos())) {
264484543d1Sopenharmony_ci        FFRT_LOGE("failed to insert task [%llu] into %s", task->gid, name_.c_str());
265484543d1Sopenharmony_ci        return;
266484543d1Sopenharmony_ci    }
267484543d1Sopenharmony_ci}
268484543d1Sopenharmony_ci
269484543d1Sopenharmony_civoid QueueHandler::TransferInitTask()
270484543d1Sopenharmony_ci{
271484543d1Sopenharmony_ci    std::function<void()> initFunc = [] {};
272484543d1Sopenharmony_ci    auto f = create_function_wrapper(initFunc, ffrt_function_kind_queue);
273484543d1Sopenharmony_ci    QueueTask* initTask = GetQueueTaskByFuncStorageOffset(f);
274484543d1Sopenharmony_ci    new (initTask)ffrt::QueueTask(this);
275484543d1Sopenharmony_ci    initTask->SetQos(qos_);
276484543d1Sopenharmony_ci    TransferTask(initTask);
277484543d1Sopenharmony_ci}
278484543d1Sopenharmony_ci
279484543d1Sopenharmony_civoid QueueHandler::SetTimeoutMonitor(QueueTask* task)
280484543d1Sopenharmony_ci{
281484543d1Sopenharmony_ci    if (timeout_ <= 0) {
282484543d1Sopenharmony_ci        return;
283484543d1Sopenharmony_ci    }
284484543d1Sopenharmony_ci
285484543d1Sopenharmony_ci    task->IncDeleteRef();
286484543d1Sopenharmony_ci    timeoutWe_ = new (SimpleAllocator<WaitUntilEntry>::AllocMem()) WaitUntilEntry();
287484543d1Sopenharmony_ci    // set delayed worker callback
288484543d1Sopenharmony_ci    timeoutWe_->cb = ([this, task](WaitEntry* timeoutWe_) {
289484543d1Sopenharmony_ci        if (!task->GetFinishStatus()) {
290484543d1Sopenharmony_ci            RunTimeOutCallback(task);
291484543d1Sopenharmony_ci        }
292484543d1Sopenharmony_ci        delayedCbCnt_.fetch_sub(1);
293484543d1Sopenharmony_ci        task->DecDeleteRef();
294484543d1Sopenharmony_ci        SimpleAllocator<WaitUntilEntry>::FreeMem(static_cast<WaitUntilEntry*>(timeoutWe_));
295484543d1Sopenharmony_ci    });
296484543d1Sopenharmony_ci
297484543d1Sopenharmony_ci    // set delayed worker wakeup time
298484543d1Sopenharmony_ci    std::chrono::microseconds timeout(timeout_);
299484543d1Sopenharmony_ci    auto now = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::steady_clock::now());
300484543d1Sopenharmony_ci    timeoutWe_->tp = std::chrono::time_point_cast<std::chrono::steady_clock::duration>(now + timeout);
301484543d1Sopenharmony_ci
302484543d1Sopenharmony_ci    if (!DelayedWakeup(timeoutWe_->tp, timeoutWe_, timeoutWe_->cb)) {
303484543d1Sopenharmony_ci        task->DecDeleteRef();
304484543d1Sopenharmony_ci        SimpleAllocator<WaitUntilEntry>::FreeMem(timeoutWe_);
305484543d1Sopenharmony_ci        FFRT_LOGW("failed to set watchdog for task gid=%llu in %s with timeout [%llu us] ", task->gid,
306484543d1Sopenharmony_ci            name_.c_str(), timeout_);
307484543d1Sopenharmony_ci        return;
308484543d1Sopenharmony_ci    }
309484543d1Sopenharmony_ci
310484543d1Sopenharmony_ci    delayedCbCnt_.fetch_add(1);
311484543d1Sopenharmony_ci    FFRT_LOGD("set watchdog of task gid=%llu of %s succ", task->gid, name_.c_str());
312484543d1Sopenharmony_ci}
313484543d1Sopenharmony_ci
314484543d1Sopenharmony_civoid QueueHandler::RemoveTimeoutMonitor(QueueTask* task)
315484543d1Sopenharmony_ci{
316484543d1Sopenharmony_ci    if (timeout_ <= 0) {
317484543d1Sopenharmony_ci        return;
318484543d1Sopenharmony_ci    }
319484543d1Sopenharmony_ci
320484543d1Sopenharmony_ci    WaitEntry* dwe = static_cast<WaitEntry*>(timeoutWe_);
321484543d1Sopenharmony_ci    if (DelayedRemove(timeoutWe_->tp, dwe)) {
322484543d1Sopenharmony_ci        delayedCbCnt_.fetch_sub(1);
323484543d1Sopenharmony_ci        SimpleAllocator<WaitUntilEntry>::FreeMem(static_cast<WaitUntilEntry*>(timeoutWe_));
324484543d1Sopenharmony_ci    }
325484543d1Sopenharmony_ci    return;
326484543d1Sopenharmony_ci}
327484543d1Sopenharmony_ci
328484543d1Sopenharmony_civoid QueueHandler::RunTimeOutCallback(QueueTask* task)
329484543d1Sopenharmony_ci{
330484543d1Sopenharmony_ci    std::stringstream ss;
331484543d1Sopenharmony_ci    static std::once_flag flag;
332484543d1Sopenharmony_ci    static char processName[PROCESS_NAME_BUFFER_LENGTH];
333484543d1Sopenharmony_ci    std::call_once(flag, []() {
334484543d1Sopenharmony_ci        GetProcessName(processName, PROCESS_NAME_BUFFER_LENGTH);
335484543d1Sopenharmony_ci    });
336484543d1Sopenharmony_ci    std::string processNameStr = std::string(processName);
337484543d1Sopenharmony_ci    ss << "[Serial_Queue_Timeout_Callback] process name:[" << processNameStr << "], serial queue:[" <<
338484543d1Sopenharmony_ci        name_ << "], queueId:[" << GetQueueId() << "], serial task gid:[" << task->gid << "], task name:["
339484543d1Sopenharmony_ci        << task->label << "], execution time exceeds[" << timeout_ << "] us";
340484543d1Sopenharmony_ci    FFRT_LOGE("%s", ss.str().c_str());
341484543d1Sopenharmony_ci    if (timeoutCb_ != nullptr) {
342484543d1Sopenharmony_ci        timeoutCb_->exec(timeoutCb_);
343484543d1Sopenharmony_ci    }
344484543d1Sopenharmony_ci}
345484543d1Sopenharmony_ci
346484543d1Sopenharmony_cistd::string QueueHandler::GetDfxInfo() const
347484543d1Sopenharmony_ci{
348484543d1Sopenharmony_ci    std::stringstream ss;
349484543d1Sopenharmony_ci    ss << " queue name [" << name_ << "]";
350484543d1Sopenharmony_ci    if (queue_ != nullptr) {
351484543d1Sopenharmony_ci        ss << ", remaining tasks count=" << queue_->GetMapSize();
352484543d1Sopenharmony_ci    }
353484543d1Sopenharmony_ci    return ss.str();
354484543d1Sopenharmony_ci}
355484543d1Sopenharmony_ci
356484543d1Sopenharmony_cibool QueueHandler::IsIdle()
357484543d1Sopenharmony_ci{
358484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return false, "[queueId=%u] constructed failed", GetQueueId());
359484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_->GetQueueType() != ffrt_queue_eventhandler_adapter),
360484543d1Sopenharmony_ci        return false, "[queueId=%u] type invalid", GetQueueId());
361484543d1Sopenharmony_ci
362484543d1Sopenharmony_ci    return reinterpret_cast<EventHandlerAdapterQueue*>(queue_.get())->IsIdle();
363484543d1Sopenharmony_ci}
364484543d1Sopenharmony_ci
365484543d1Sopenharmony_civoid QueueHandler::SetEventHandler(void* eventHandler)
366484543d1Sopenharmony_ci{
367484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return, "[queueId=%u] constructed failed", GetQueueId());
368484543d1Sopenharmony_ci
369484543d1Sopenharmony_ci    bool typeInvalid = (queue_->GetQueueType() != ffrt_queue_eventhandler_interactive) &&
370484543d1Sopenharmony_ci        (queue_->GetQueueType() != ffrt_queue_eventhandler_adapter);
371484543d1Sopenharmony_ci    FFRT_COND_DO_ERR(typeInvalid, return, "[queueId=%u] type invalid", GetQueueId());
372484543d1Sopenharmony_ci
373484543d1Sopenharmony_ci    reinterpret_cast<EventHandlerInteractiveQueue*>(queue_.get())->SetEventHandler(eventHandler);
374484543d1Sopenharmony_ci}
375484543d1Sopenharmony_ci
376484543d1Sopenharmony_civoid* QueueHandler::GetEventHandler()
377484543d1Sopenharmony_ci{
378484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return nullptr, "[queueId=%u] constructed failed", GetQueueId());
379484543d1Sopenharmony_ci
380484543d1Sopenharmony_ci    bool typeInvalid = (queue_->GetQueueType() != ffrt_queue_eventhandler_interactive) &&
381484543d1Sopenharmony_ci        (queue_->GetQueueType() != ffrt_queue_eventhandler_adapter);
382484543d1Sopenharmony_ci    FFRT_COND_DO_ERR(typeInvalid, return nullptr, "[queueId=%u] type invalid", GetQueueId());
383484543d1Sopenharmony_ci
384484543d1Sopenharmony_ci    return reinterpret_cast<EventHandlerInteractiveQueue*>(queue_.get())->GetEventHandler();
385484543d1Sopenharmony_ci}
386484543d1Sopenharmony_ci
387484543d1Sopenharmony_ciint QueueHandler::Dump(const char* tag, char* buf, uint32_t len, bool historyInfo)
388484543d1Sopenharmony_ci{
389484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return -1, "[queueId=%u] constructed failed", GetQueueId());
390484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_->GetQueueType() != ffrt_queue_eventhandler_adapter),
391484543d1Sopenharmony_ci        return -1, "[queueId=%u] type invalid", GetQueueId());
392484543d1Sopenharmony_ci    return reinterpret_cast<EventHandlerAdapterQueue*>(queue_.get())->Dump(tag, buf, len, historyInfo);
393484543d1Sopenharmony_ci}
394484543d1Sopenharmony_ci
395484543d1Sopenharmony_ciint QueueHandler::DumpSize(ffrt_inner_queue_priority_t priority)
396484543d1Sopenharmony_ci{
397484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_ == nullptr), return -1, "[queueId=%u] constructed failed", GetQueueId());
398484543d1Sopenharmony_ci    FFRT_COND_DO_ERR((queue_->GetQueueType() != ffrt_queue_eventhandler_adapter),
399484543d1Sopenharmony_ci        return -1, "[queueId=%u] type invalid", GetQueueId());
400484543d1Sopenharmony_ci    return reinterpret_cast<EventHandlerAdapterQueue*>(queue_.get())->DumpSize(priority);
401484543d1Sopenharmony_ci}
402484543d1Sopenharmony_ci
403484543d1Sopenharmony_ci} // namespace ffrt
404