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