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_SCHEDULER_HPP 17 #define FFRT_SCHEDULER_HPP 18 #include <list> 19 #include <vector> 20 #include <string> 21 #include <map> 22 #include <mutex> 23 #include <array> 24 #include "internal_inc/types.h" 25 #include "core/entity.h" 26 #include "eu/execute_unit.h" 27 #include "sync/sync.h" 28 #include "sched/task_scheduler.h" 29 #include "eu/worker_thread.h" 30 #include "tm/cpu_task.h" 31 #include "util/cb_func.h" 32 #include "dfx/bbox/bbox.h" 33 34 namespace ffrt { 35 class FFRTScheduler { 36 public: 37 FFRTScheduler(const FFRTScheduler&) = delete; 38 FFRTScheduler& operator=(const FFRTScheduler&) = delete; ~FFRTScheduler()39 virtual ~FFRTScheduler() 40 { 41 for (int i = 0; i < QoS::Max(); i++) { 42 SchedulerFactory::Recycle(fifoQue[i]); 43 } 44 } 45 46 // 获取调度器的单例 47 static FFRTScheduler* Instance(); 48 static void RegistInsCb(SingleInsCB<FFRTScheduler>::Instance &&cb); 49 50 #ifdef QOS_DEPENDENCY onWait(const std::vector<VersionCtx * > & waitDatas,int64_t deadline)51 void onWait(const std::vector<VersionCtx*>& waitDatas, int64_t deadline) 52 { 53 for (auto data : waitDatas) { 54 if (!data->childVersions.empty()) { 55 auto waitVersion = data->childVersions.back(); 56 if (waitVersion->status != DataStatus::IDLE) { // 数据已经被生产出来 57 continue; 58 } 59 FFRT_LOGD("wait task=%p deadline=%ld", waitVersion->myProducer, deadline); 60 updateTask(waitVersion->myProducer, deadline); 61 UpdateVersion(waitVersion->preVersion, deadline); 62 } 63 } 64 } 65 #endif 66 GetScheduler(const QoS & qos)67 TaskScheduler& GetScheduler(const QoS& qos) 68 { 69 return *fifoQue[static_cast<unsigned short>(qos)]; 70 } 71 72 virtual bool InsertNode(LinkedList* node, const QoS qos); 73 74 virtual bool RemoveNode(LinkedList* node, const QoS qos); 75 76 virtual bool WakeupTask(CPUEUTask* task); 77 78 protected: FFRTScheduler()79 FFRTScheduler() 80 { 81 TaskState::RegisterOps(TaskState::READY, ([this] (CPUEUTask* task) { return this->WakeupTask(task); })); 82 for (int i = 0; i < QoS::Max(); i++) { 83 fifoQue[i] = SchedulerFactory::Alloc(); 84 fifoQue[i]->qos = i; 85 } 86 } 87 88 private: 89 std::array<TaskScheduler*, QoS::MaxNum()> fifoQue; 90 #ifdef QOS_DEPENDENCY ResetDeadline(CPUEUTask * task,int64_t deadline)91 void ResetDeadline(CPUEUTask* task, int64_t deadline) 92 { 93 auto it = std::find_if(readyTasks.begin(), readyTasks.end(), [task](auto& p) { return p.second == task; }); 94 if (it == readyTasks.end()) { 95 return; 96 } 97 auto node = readyTasks.extract(it); 98 task->qos.deadline.relative += deadline - task->qos.deadline.absolute; 99 task->qos.deadline.absolute = deadline; 100 readyTasks.insert(std::move(node)); 101 } updateTask(CPUEUTask * task,int64_t deadline)102 void updateTask(CPUEUTask* task, int64_t deadline) 103 { 104 if (task == nullptr) { 105 return; 106 } 107 ResetDeadline(task, deadline); 108 onWait(task->ins, deadline); 109 for (auto data : task->outs) { 110 UpdateVersion(data, deadline); 111 } 112 UpdateChildTask(task, deadline); 113 } UpdateChildTask(CPUEUTask * task,int64_t deadline)114 void UpdateChildTask(CPUEUTask* task, int64_t deadline) 115 { 116 (void)task; 117 (void)deadline; 118 } UpdateVersion(VersionCtx * data,int64_t deadline)119 void UpdateVersion(VersionCtx* data, int64_t deadline) 120 { 121 if (data == nullptr) { 122 return; 123 } 124 updateTask(data->myProducer, deadline); 125 for (auto task : data->consumers) { 126 updateTask(task, deadline); 127 } 128 UpdateVersion(data->preVersion, deadline); 129 } 130 #endif 131 }; 132 133 class SFFRTScheduler : public FFRTScheduler { 134 public: Instance()135 static FFRTScheduler& Instance() 136 { 137 static SFFRTScheduler ins; 138 return ins; 139 } 140 private: SFFRTScheduler()141 SFFRTScheduler() 142 { 143 } 144 }; 145 } // namespace ffrt 146 #endif 147