• 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 #ifndef _CPU_TASK_H_
16 #define _CPU_TASK_H_
17 
18 #include <string>
19 #include <functional>
20 #include <unordered_set>
21 #include <vector>
22 #include <mutex>
23 #include <atomic>
24 #include <string>
25 #include <set>
26 #include <list>
27 #include <memory>
28 #include <unistd.h>
29 #include "task_base.h"
30 #include "sched/task_state.h"
31 #include "eu/co_routine.h"
32 #include "core/task_attr_private.h"
33 #include "core/task_io.h"
34 #include "dfx/log/ffrt_log_api.h"
35 #include "eu/func_manager.h"
36 #ifdef FFRT_ASYNC_STACKTRACE
37 #include "dfx/async_stack/ffrt_async_stack.h"
38 #endif
39 
40 namespace ffrt {
41 constexpr int CO_CREATE_RETRY_INTERVAL = 500 * 1000;
42 struct VersionCtx;
43 class SCPUEUTask;
44 
45 class CPUEUTask : public CoTask {
46 public:
47     CPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id, const QoS &qos);
48     SkipStatus skipped = SkipStatus::SUBMITTED;
49     TaskStatus status = TaskStatus::PENDING;
50 
51     uint8_t func_storage[ffrt_auto_managed_function_storage_size]; // 函数闭包、指针或函数对象
52     CPUEUTask* parent = nullptr;
53     const uint64_t rank = 0x0;
54     std::mutex lock; // used in coroute
55     std::vector<CPUEUTask*> in_handles;
56     TaskState state;
57 
58     /* The current number of child nodes does not represent the real number of child nodes,
59      * because the dynamic graph child nodes will grow to assist in the generation of id
60      */
61     std::atomic<uint64_t> childNum {0};
62     bool isWatchdogEnable = false;
63     bool notifyWorker_ = true;
64 
65     void** threadTsd = nullptr;
66     void** tsd = nullptr;
67     bool taskLocal = false;
68 
69     bool pollerEnable = false; // set true if task call ffrt_epoll_ctl
70 
71     void SetQos(const QoS& newQos);
72     uint64_t reserved[8];
73 
74     void FreeMem() override;
75     void Execute() override;
76 
77     virtual void RecycleTask() = 0;
78 
IsRoot()79     inline bool IsRoot()
80     {
81         return parent == nullptr;
82     }
83 
UpdateState(TaskState::State taskState)84     int UpdateState(TaskState::State taskState)
85     {
86         return TaskState::OnTransition(taskState, this);
87     }
88 
UpdateState(TaskState::State taskState,TaskState::Op && op)89     int UpdateState(TaskState::State taskState, TaskState::Op&& op)
90     {
91         return TaskState::OnTransition(taskState, this, std::move(op));
92     }
93 };
94 
ExecutedOnWorker(CPUEUTask * task)95 inline bool ExecutedOnWorker(CPUEUTask* task)
96 {
97     return task && (task->type != ffrt_normal_task || !task->IsRoot());
98 }
99 
LegacyMode(CPUEUTask * task)100 inline bool LegacyMode(CPUEUTask* task)
101 {
102     return task && (task->legacyCountNum > 0);
103 }
104 
BlockThread(CPUEUTask * task)105 inline bool BlockThread(CPUEUTask* task)
106 {
107     return task && task->blockType == BlockType::BLOCK_THREAD;
108 }
109 
ThreadWaitMode(CPUEUTask * task)110 inline bool ThreadWaitMode(CPUEUTask* task)
111 {
112     if constexpr(!USE_COROUTINE) {
113         // static switch controlled by macro
114         return true;
115     }
116     if (!ExecutedOnWorker(task)) {
117         // task is executed on user thread
118         return true;
119     }
120     if (LegacyMode(task)) {
121         // set_legacy_mode controlled by user
122         return true;
123     }
124     return false;
125 }
126 
ThreadNotifyMode(CPUEUTask * task)127 inline bool ThreadNotifyMode(CPUEUTask* task)
128 {
129     if constexpr(!USE_COROUTINE) {
130         // static switch controlled by macro
131         return true;
132     }
133     if (BlockThread(task)) {
134         // thread wait happended when task in legacy mode
135         return true;
136     }
137     return false;
138 }
139 
IsCoTask(TaskBase * task)140 inline bool IsCoTask(TaskBase* task)
141 {
142     return task->type == ffrt_normal_task || task->type == ffrt_queue_task;
143 }
144 
NeedNotifyWorker(TaskBase * task)145 inline bool NeedNotifyWorker(TaskBase* task)
146 {
147     if (task == nullptr) {
148         return false;
149     }
150     bool needNotify = true;
151     if (task->type == ffrt_normal_task) {
152         CPUEUTask* cpuTask = static_cast<CPUEUTask*>(task);
153         needNotify = cpuTask->notifyWorker_;
154         cpuTask->notifyWorker_ = true;
155     }
156     return needNotify;
157 }
158 
159 void ExecuteTask(TaskBase* task, QoS qos);
160 } /* namespace ffrt */
161 #endif
162