• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
DependenceStr(Dependence d)28 static inline const char* DependenceStr(Dependence d)
29 {
30     static const char* m[] = {
31         "DEPENDENCE_INIT",
32         "DATA_DEPENDENCE",
33         "CALL_DEPENDENCE",
34         "CONDITION_DEPENDENCE",
35     };
36     return m[static_cast<uint64_t>(d)];
37 }
38 
SCPUEUTask(const task_attr_private * attr,CPUEUTask * parent,const uint64_t & id)39 SCPUEUTask::SCPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id)
40     : CPUEUTask(attr, parent, id)
41 {
42 }
43 
DecDepRef()44 void SCPUEUTask::DecDepRef()
45 {
46     if (--dataRefCnt.submitDep == 0) {
47         FFRT_LOGD("Undependency completed, enter ready queue, task[%lu], name[%s]", gid, label.c_str());
48         FFRT_WAKE_TRACER(gid);
49         Ready();
50     }
51 }
52 
DecChildRef()53 void SCPUEUTask::DecChildRef()
54 {
55     SCPUEUTask* parent = reinterpret_cast<SCPUEUTask*>(this->parent);
56     FFRT_TRACE_SCOPE(2, taskDecChildRef);
57     std::unique_lock<decltype(parent->mutex_)> lck(parent->mutex_);
58     parent->childRefCnt--;
59     if (parent->childRefCnt != 0) {
60         return;
61     }
62     if (FFRT_UNLIKELY(parent->IsRoot())) {
63         RootTask *root = static_cast<RootTask *>(parent);
64         if (root->thread_exit) {
65             lck.unlock();
66             delete root;
67             return;
68         }
69     }
70 
71     if (!parent->IsRoot() && parent->curStatus == TaskStatus::WAIT_RELEASING && parent->childRefCnt == 0) {
72         FFRT_LOGD("free CPUEUTask:%s gid=%lu", parent->GetLabel().c_str(), parent->gid);
73         lck.unlock();
74         parent->DecDeleteRef();
75         return;
76     }
77     if (parent->dependenceStatus != Dependence::CALL_DEPENDENCE) {
78         return;
79     }
80     parent->dependenceStatus = Dependence::DEPENDENCE_INIT;
81 
82     if (parent->GetBlockType() == BlockType::BLOCK_THREAD) {
83         parent->waitCond_.notify_all();
84     } else {
85         FFRT_WAKE_TRACER(parent->gid);
86         parent->Ready();
87     }
88 }
89 
DecWaitDataRef()90 void SCPUEUTask::DecWaitDataRef()
91 {
92     FFRT_TRACE_SCOPE(2, taskDecWaitData);
93     {
94         std::lock_guard<decltype(mutex_)> lck(mutex_);
95         if (--dataRefCnt.waitDep != 0) {
96             return;
97         }
98         if (dependenceStatus != Dependence::DATA_DEPENDENCE) {
99             return;
100         }
101         dependenceStatus = Dependence::DEPENDENCE_INIT;
102     }
103 
104     if (GetBlockType() == BlockType::BLOCK_THREAD) {
105         waitCond_.notify_all();
106     } else {
107         FFRT_WAKE_TRACER(gid);
108         Ready();
109     }
110 }
111 
Finish()112 void SCPUEUTask::Finish()
113 {
114     std::unique_lock<decltype(mutex_)> lck(mutex_);
115     if (childRefCnt == 0) {
116         FFRT_LOGD("free SCPUEUTask:%s gid=%lu", label.c_str(), gid);
117         lck.unlock();
118         DecDeleteRef();
119     } else {
120         SetStatus(TaskStatus::WAIT_RELEASING);
121     }
122 }
123 
MultiDependenceAdd(Dependence depType)124 void SCPUEUTask::MultiDependenceAdd(Dependence depType)
125 {
126     FFRT_LOGD("task(%s) ADD_DENPENCE(%s)", label.c_str(), DependenceStr(depType));
127     dependenceStatus = depType;
128 }
129 } /* namespace ffrt */
130