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
16 #ifdef FFRT_CO_BACKTRACE_OH_ENABLE
17 #include <sstream>
18 #include "backtrace_local.h"
19 #endif
20 #include "dfx/trace_record/ffrt_trace_record.h"
21 #include "dm/dependence_manager.h"
22 #include "util/slab.h"
23 #include "internal_inc/osal.h"
24 #include "internal_inc/types.h"
25 #include "tm/cpu_task.h"
26
27 namespace ffrt {
DenpenceStr(Denpence d)28 static inline const char* DenpenceStr(Denpence d)
29 {
30 static const char* m[] = {
31 "DEPENCE_INIT",
32 "DATA_DEPENCE",
33 "CALL_DEPENCE",
34 "CONDITION_DEPENCE",
35 };
36 return m[static_cast<uint64_t>(d)];
37 }
38
SCPUEUTask(const task_attr_private * attr,CPUEUTask * parent,const uint64_t & id,const QoS & qos)39 SCPUEUTask::SCPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id,
40 const QoS &qos)
41 : CPUEUTask(attr, parent, id, qos)
42 {
43 }
44
DecDepRef()45 void SCPUEUTask::DecDepRef()
46 {
47 if (--dataRefCnt.submitDep == 0) {
48 FFRT_LOGD("Undependency completed, enter ready queue, task[%lu], name[%s]", gid, label.c_str());
49 FFRT_WAKE_TRACER(this->gid);
50 FFRTTraceRecord::TaskEnqueue<ffrt_normal_task>(GetQos());
51 this->UpdateState(TaskState::READY);
52 }
53 }
54
DecChildRef()55 void SCPUEUTask::DecChildRef()
56 {
57 SCPUEUTask* parent = reinterpret_cast<SCPUEUTask*>(this->parent);
58 FFRT_TRACE_SCOPE(2, taskDecChildRef);
59 std::unique_lock<decltype(parent->mutex_)> lck(parent->mutex_);
60 parent->childRefCnt--;
61 if (parent->childRefCnt != 0) {
62 return;
63 }
64 if (FFRT_UNLIKELY(parent->IsRoot())) {
65 RootTask *root = static_cast<RootTask *>(parent);
66 if (root->thread_exit) {
67 lck.unlock();
68 delete root;
69 return;
70 }
71 }
72
73 if (!parent->IsRoot() && parent->status == TaskStatus::RELEASED && parent->childRefCnt == 0) {
74 FFRT_LOGD("free CPUEUTask:%s gid=%lu", parent->label.c_str(), parent->gid);
75 lck.unlock();
76 parent->DecDeleteRef();
77 return;
78 }
79 if (parent->denpenceStatus != Denpence::CALL_DEPENCE) {
80 return;
81 }
82 parent->denpenceStatus = Denpence::DEPENCE_INIT;
83
84 if (ThreadNotifyMode(parent) || parent->IsRoot()) {
85 if (BlockThread(parent)) {
86 parent->blockType = BlockType::BLOCK_COROUTINE;
87 }
88 parent->waitCond_.notify_all();
89 } else {
90 FFRT_WAKE_TRACER(parent->gid);
91 parent->UpdateState(TaskState::READY);
92 }
93 }
94
DecWaitDataRef()95 void SCPUEUTask::DecWaitDataRef()
96 {
97 FFRT_TRACE_SCOPE(2, taskDecWaitData);
98 {
99 std::lock_guard<decltype(mutex_)> lck(mutex_);
100 if (--dataRefCnt.waitDep != 0) {
101 return;
102 }
103 if (denpenceStatus != Denpence::DATA_DEPENCE) {
104 return;
105 }
106 denpenceStatus = Denpence::DEPENCE_INIT;
107 }
108
109 if (ThreadNotifyMode(this) || IsRoot()) {
110 if (BlockThread(this)) {
111 blockType = BlockType::BLOCK_COROUTINE;
112 }
113 waitCond_.notify_all();
114 } else {
115 FFRT_WAKE_TRACER(this->gid);
116 FFRTTraceRecord::TaskEnqueue<ffrt_normal_task>(GetQos());
117 this->UpdateState(TaskState::READY);
118 }
119 }
120
RecycleTask()121 void SCPUEUTask::RecycleTask()
122 {
123 std::unique_lock<decltype(mutex_)> lck(mutex_);
124 if (childRefCnt == 0) {
125 FFRT_LOGD("free SCPUEUTask:%s gid=%lu", label.c_str(), gid);
126 lck.unlock();
127 DecDeleteRef();
128 return;
129 } else {
130 status = TaskStatus::RELEASED;
131 }
132 }
133
MultiDepenceAdd(Denpence depType)134 void SCPUEUTask::MultiDepenceAdd(Denpence depType)
135 {
136 FFRT_LOGD("task(%s) ADD_DENPENCE(%s)", this->label.c_str(), DenpenceStr(depType));
137 denpenceStatus = depType;
138 }
139 } /* namespace ffrt */