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