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 "eu/co_routine.h" 31 #include "core/task_attr_private.h" 32 #include "dfx/log/ffrt_log_api.h" 33 #include "eu/func_manager.h" 34 #ifdef FFRT_ASYNC_STACKTRACE 35 #include "dfx/async_stack/ffrt_async_stack.h" 36 #endif 37 38 namespace ffrt { 39 constexpr int CO_CREATE_RETRY_INTERVAL = 500 * 1000; 40 constexpr uint64_t MASK_FOR_HCS_TASK = 0xFF000000000000; 41 struct VersionCtx; 42 class SCPUEUTask; 43 44 #ifdef FFRT_TASK_LOCAL_ENABLE 45 struct TaskLocalAttr { 46 bool taskLocal = false; // 是否开启taskLocal特性 47 void** threadTsd = nullptr; // 指向保存线程tsd数据内存空间的指针 48 void** tsd = nullptr; // 指向task自身tsd数据内存空间的指针 49 }; 50 #endif 51 52 class CPUEUTask : public CoTask { 53 public: 54 CPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id); 55 ~CPUEUTask() override; 56 SkipStatus skipped = SkipStatus::SUBMITTED; 57 58 CPUEUTask* parent = nullptr; 59 uint64_t delayTime = 0; 60 TimeoutTask timeoutTask; 61 62 std::vector<CPUEUTask*>* in_handles_ = nullptr; 63 /* The current number of child nodes does not represent the real number of child nodes, 64 * because the dynamic graph child nodes will grow to assist in the generation of id 65 */ 66 std::atomic<uint64_t> childNum {0}; 67 bool isWatchdogEnable = false; 68 bool notifyWorker_ = true; 69 bool isDelaying = false; 70 71 #ifdef FFRT_TASK_LOCAL_ENABLE 72 TaskLocalAttr* tlsAttr = nullptr; 73 #endif 74 IsRoot()75 inline bool IsRoot() const 76 { 77 return parent == nullptr; 78 } 79 SetInHandles(std::vector<CPUEUTask * > & in_handles)80 inline void SetInHandles(std::vector<CPUEUTask*>& in_handles) 81 { 82 if (in_handles.empty()) { 83 return; 84 } 85 in_handles_ = new std::vector<CPUEUTask*>(in_handles); 86 } 87 GetInHandles()88 inline const std::vector<CPUEUTask*>& GetInHandles() 89 { 90 static const std::vector<CPUEUTask*> empty; 91 if (!in_handles_) { 92 return empty; 93 } 94 return *in_handles_; 95 } 96 97 void Prepare() override; 98 void Ready() override; 99 Pop()100 void Pop() override 101 { 102 SetStatus(TaskStatus::POPPED); 103 } 104 105 void Execute() override; 106 Block()107 BlockType Block() override 108 { 109 if (USE_COROUTINE && !IsRoot() && legacyCountNum <= 0) { 110 blockType = BlockType::BLOCK_COROUTINE; 111 SetStatus(TaskStatus::COROUTINE_BLOCK); 112 } else { 113 blockType = BlockType::BLOCK_THREAD; 114 SetStatus(TaskStatus::THREAD_BLOCK); 115 } 116 return blockType; 117 } 118 Wake()119 void Wake() override 120 { 121 SetStatus(TaskStatus::EXECUTING); 122 blockType = BlockType::BLOCK_COROUTINE; 123 } 124 Cancel()125 void Cancel() override 126 { 127 SetStatus(TaskStatus::CANCELED); 128 } 129 130 void FreeMem() override; 131 void SetQos(const QoS& newQos) override; 132 GetBlockType()133 BlockType GetBlockType() const override 134 { 135 if (IsRoot()) { 136 return BlockType::BLOCK_THREAD; 137 } 138 return blockType; 139 } 140 }; 141 NeedNotifyWorker(TaskBase * task)142inline bool NeedNotifyWorker(TaskBase* task) 143 { 144 if (task == nullptr) { 145 return false; 146 } 147 bool needNotify = true; 148 if (task->type == ffrt_normal_task) { 149 CPUEUTask* cpuTask = static_cast<CPUEUTask*>(task); 150 needNotify = cpuTask->notifyWorker_; 151 cpuTask->notifyWorker_ = true; 152 } 153 return needNotify; 154 } 155 isDelayingTask(CPUEUTask * task)156inline bool isDelayingTask(CPUEUTask* task) 157 { 158 return task->isDelaying; 159 } 160 } /* namespace ffrt */ 161 #endif 162