• 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 #ifndef FFRT_TASK_CTX_H
17 #define FFRT_TASK_CTX_H
18 
19 #include <string>
20 #include <functional>
21 #include <unordered_set>
22 #include <vector>
23 #include <mutex>
24 #include <atomic>
25 #include <string>
26 #include <set>
27 #include <list>
28 #include <memory>
29 #include "internal_inc/types.h"
30 #include "sched/task_state.h"
31 #include "sched/interval.h"
32 #include "eu/co_routine.h"
33 #include "task_attr_private.h"
34 #include "util/slab.h"
35 #include "util/task_deleter.h"
36 #include "dfx/bbox/bbox.h"
37 
38 namespace ffrt {
39 struct TaskCtx;
40 struct VersionCtx;
41 
42 /*
43 TaskCtx 必须是数据结构ffrt_executor_task_t的子类
44 */
45 struct TaskCtx : public TaskDeleter {
46     TaskCtx(const task_attr_private* attr,
47         TaskCtx* parent, const uint64_t& id, const char *identity = nullptr, const QoS& qos = QoS());
48     WaitUntilEntry* wue;
49     bool wakeupTimeOut = false;
50     bool is_native_func = false;
51     SkipStatus skipped = SkipStatus::SUBMITTED;
52 
53     uint8_t func_storage[ffrt_auto_managed_function_storage_size]; // 函数闭包、指针或函数对象
54     TaskCtx* parent = nullptr;
55     const uint64_t rank = 0x0;
56     std::unordered_set<VersionCtx*> ins;
57     std::unordered_set<VersionCtx*> outs;
58     std::vector<TaskCtx*> in_handles;
59     CoRoutine* coRoutine = nullptr;
60     std::vector<std::string> traceTag;
61 
62 #ifdef MUTEX_PERF // Mutex Lock&Unlock Cycles Statistic
63     xx::mutex lock {"TaskCtx::lock"};
64 #else
65     std::mutex lock; // used in coroute
66 #endif
67     uint64_t myRefCnt = 0;
68 
69     TaskState state;
70 #ifdef MUTEX_PERF // Mutex Lock&Unlock Cycles Statistic
71     xx::mutex denpenceStatusLock {"TaskCtx::denpenceStatusLock"};
72 #else
73     std::mutex denpenceStatusLock;
74 #endif
75     uint64_t pmuCntBegin = 0;
76     uint64_t pmuCnt = 0;
77     Denpence denpenceStatus {Denpence::DEPENCE_INIT};
78     /* The current number of child nodes does not represent the real number of child nodes,
79      * because the dynamic graph child nodes will grow to assist in the generation of id
80      */
81     std::atomic<uint64_t> childNum {0};
82     std::atomic_uint64_t depRefCnt {0};
83 
84     std::atomic_uint64_t childWaitRefCnt {0};
85     std::condition_variable childWaitCond_;
86 
87     uint64_t dataWaitRefCnt {0}; // waited data count called by ffrt_wait()
88     std::condition_variable dataWaitCond_; // wait data cond
89     TaskStatus status = TaskStatus::PENDING;
90 
91     void InitRelatedIntervals(TaskCtx* curr);
92     std::unordered_set<Interval*> relatedIntervals;
93 
94     const char* identity;
95     int64_t ddlSlack = INT64_MAX;
96     uint64_t load = 0;
97     int64_t ddl = INT64_MAX;
98 
99     QoS qos;
100     void SetQos(QoS& qos);
101 
freeMemTaskCtx102     inline void freeMem() override
103     {
104         BboxCheckAndFreeze();
105         SimpleAllocator<TaskCtx>::freeMem(this);
106     }
107 
IncDepRefTaskCtx108     inline void IncDepRef()
109     {
110         ++depRefCnt;
111     }
112     void DecDepRef();
113 
IncChildRefTaskCtx114     inline void IncChildRef()
115     {
116         ++(parent->childWaitRefCnt);
117     }
118     void DecChildRef();
119 
IncWaitDataRefTaskCtx120     inline void IncWaitDataRef()
121     {
122         ++dataWaitRefCnt;
123     }
124     void DecWaitDataRef();
125 
126     void DealChildWait();
127     void DealDataWait();
128     void RecycleTask();
129     bool IsPrevTask(const TaskCtx* task) const;
130     void MultiDepenceAdd(Denpence depType);
131 
132     std::string label; // used for debug
133 
IsRootTaskCtx134     inline bool IsRoot()
135     {
136         if (parent == nullptr) {
137             return true;
138         }
139         return false;
140     }
141 
UpdateStateTaskCtx142     int UpdateState(TaskState::State taskState)
143     {
144         return TaskState::OnTransition(taskState, this);
145     }
146 
UpdateStateTaskCtx147     int UpdateState(TaskState::State taskState, TaskState::Op&& op)
148     {
149         return TaskState::OnTransition(taskState, this, std::move(op));
150     }
151 
SetTraceTagTaskCtx152     void SetTraceTag(const std::string& name)
153     {
154         traceTag.push_back(name);
155     }
156 
ClearTraceTagTaskCtx157     void ClearTraceTag()
158     {
159         if (!traceTag.empty()) {
160             traceTag.pop_back();
161         }
162     }
163 
164 #ifdef FFRT_CO_BACKTRACE_OH_ENABLE
165     static void DumpTask(TaskCtx* task, std::string& stackInfo, uint8_t flag = 0); /* 0:hilog others:hiview */
166 #endif
167 };
168 
169 class RootTaskCtx : public TaskCtx {
170 public:
171     RootTaskCtx(const task_attr_private* attr, TaskCtx* parent, const uint64_t& id,
TaskCtx(attr,parent,id,identity,qos)172         const char *identity = nullptr, const QoS& qos = QoS()) : TaskCtx(attr, parent, id, identity, qos)
173     {
174     }
175 public:
176     bool thread_exit = false;
177 };
178 
179 class RootTaskCtxWrapper {
180 public:
RootTaskCtxWrapper()181     RootTaskCtxWrapper()
182     {
183         task_attr_private task_attr;
184         root = new RootTaskCtx {&task_attr, nullptr, 0, nullptr};
185     }
~RootTaskCtxWrapper()186     ~RootTaskCtxWrapper()
187     {
188         std::unique_lock<decltype(root->lock) > lck(root->lock);
189         if (root->childWaitRefCnt == 0) {
190             lck.unlock();
191             delete root;
192         } else {
193             root->thread_exit = true ;
194         }
195     }
Root()196     TaskCtx* Root()
197     {
198         return root;
199     }
200 private:
201     RootTaskCtx *root = nullptr;
202 };
203 } /* namespace ffrt */
204 #endif
205