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