1 /*
2 * Copyright (c) 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 #include "tm/uv_task.h"
17 #include "eu/func_manager.h"
18 #include "dfx/log/ffrt_log_api.h"
19 #include "dfx/trace_record/ffrt_trace_record.h"
20 #include "dfx/trace/ffrt_trace.h"
21 #include "util/ffrt_facade.h"
22
23 namespace ffrt {
Ready()24 void UVTask::Ready()
25 {
26 QoS taskQos = qos_;
27 FFRTTraceRecord::TaskSubmit<ffrt_uv_task>(taskQos);
28 if (FFRTFacade::GetSchedInstance()->GetScheduler(taskQos).PushUVTaskToWaitingQueue(this)) {
29 FFRTTraceRecord::TaskEnqueue<ffrt_uv_task>(taskQos);
30 return;
31 }
32 SetStatus(TaskStatus::READY);
33 bool isRisingEdge = FFRTFacade::GetSchedInstance()->GetScheduler(taskQos).PushTaskGlobal(this, false);
34 FFRTTraceRecord::TaskEnqueue<ffrt_uv_task>(taskQos);
35 FFRTFacade::GetEUInstance().NotifyTask<TaskNotifyType::TASK_ADDED_RTQ>(taskQos, false, isRisingEdge);
36 }
37
Execute()38 void UVTask::Execute()
39 {
40 if (uvWork == nullptr) {
41 FFRT_SYSEVENT_LOGE("task is nullptr");
42 DecDeleteRef();
43 return;
44 }
45
46 // if the concurrency reaches the upper limit, this worker cannot execute UV tasks.
47 if (!FFRTFacade::GetSchedInstance()->GetScheduler(qos_).CheckUVTaskConcurrency(this)) {
48 return;
49 }
50
51 ffrt_executor_task_func func = FuncManager::Instance()->getFunc(ffrt_uv_task);
52 if (func == nullptr) {
53 FFRT_SYSEVENT_LOGE("Static func is nullptr");
54 DecDeleteRef();
55 return;
56 }
57
58 ExecuteImpl(this, func);
59 }
60
ExecuteImpl(UVTask * task,ffrt_executor_task_func func)61 void UVTask::ExecuteImpl(UVTask* task, ffrt_executor_task_func func)
62 {
63 ExecuteCtx* ctx = ExecuteCtx::Cur();
64 QoS taskQos = task->qos_;
65 while (task != nullptr) {
66 ctx->task = task;
67 ctx->lastGid_ = task->gid;
68 task->SetStatus(TaskStatus::EXECUTING);
69 FFRTTraceRecord::TaskExecute<ffrt_uv_task>(taskQos);
70 FFRT_EXECUTOR_TASK_BEGIN(task->gid);
71 func(task->uvWork, taskQos);
72 FFRT_TASK_END();
73 FFRT_TASKDONE_MARKER(task->gid); // task finish marker for uv task
74 FFRTTraceRecord::TaskDone<ffrt_uv_task>(taskQos);
75 task->DecDeleteRef();
76 task = FFRTFacade::GetSchedInstance()->GetScheduler(taskQos).PickWaitingUVTask();
77 }
78 }
79 } // namespace ffrt
80