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_TASK_SCHEDULER_HPP 17 #define FFRT_TASK_SCHEDULER_HPP 18 #include "core/entity.h" 19 #include "sched/task_runqueue.h" 20 #include "eu/worker_thread.h" 21 #include "sync/sync.h" 22 #include "sync/semaphore.h" 23 #include "ffrt_trace.h" 24 #include "tm/cpu_task.h" 25 26 namespace ffrt { 27 28 class TaskScheduler { 29 public: 30 virtual ~TaskScheduler() = default; 31 PickNextTask()32 CPUEUTask* PickNextTask() 33 { 34 return PickNextTaskImpl(); 35 } 36 WakeupTask(CPUEUTask * task)37 bool WakeupTask(CPUEUTask* task) 38 { 39 bool ret = false; 40 { 41 FFRT_READY_MARKER(task->gid); 42 ret = WakeupTaskImpl(task); 43 } 44 return ret; 45 } 46 WakeupNode(LinkedList * node)47 bool WakeupNode(LinkedList* node) 48 { 49 bool ret = false; 50 { 51 FFRT_EXECUTOR_TASK_READY_MARKER(reinterpret_cast<char*>(node) - offsetof(ffrt_executor_task_t, wq)); 52 ret = WakeupNodeImpl(node); 53 } 54 return ret; 55 } 56 RemoveNode(LinkedList * node)57 bool RemoveNode(LinkedList* node) 58 { 59 bool ret = false; 60 { 61 ret = RemoveNodeImpl(node); 62 } 63 return ret; 64 } 65 RQEmpty()66 bool RQEmpty() 67 { 68 return RQEmptyImpl(); 69 } 70 RQSize()71 int RQSize() 72 { 73 return RQSizeImpl(); 74 } 75 76 private: 77 virtual CPUEUTask* PickNextTaskImpl() = 0; 78 virtual bool WakeupNodeImpl(LinkedList* node) = 0; 79 virtual bool RemoveNodeImpl(LinkedList* node) = 0; 80 virtual bool WakeupTaskImpl(CPUEUTask* task) = 0; 81 virtual bool RQEmptyImpl() = 0; 82 virtual int RQSizeImpl() = 0; 83 84 fast_mutex mutex; 85 semaphore sem; 86 }; 87 88 class SFIFOScheduler : public TaskScheduler { 89 private: PickNextTaskImpl()90 CPUEUTask* PickNextTaskImpl() override 91 { 92 CPUEUTask* task = que.DeQueue(); 93 return task; 94 } 95 WakeupNodeImpl(LinkedList * node)96 bool WakeupNodeImpl(LinkedList* node) override 97 { 98 que.EnQueueNode(node); 99 return true; 100 } 101 RemoveNodeImpl(LinkedList * node)102 bool RemoveNodeImpl(LinkedList* node) override 103 { 104 que.RmQueueNode(node); 105 return true; 106 } 107 WakeupTaskImpl(CPUEUTask * task)108 bool WakeupTaskImpl(CPUEUTask* task) override 109 { 110 que.EnQueue(task); 111 return true; 112 } 113 RQEmptyImpl()114 bool RQEmptyImpl() override 115 { 116 return que.Empty(); 117 } 118 RQSizeImpl()119 int RQSizeImpl() override 120 { 121 return que.Size(); 122 } 123 124 FIFOQueue que; 125 }; 126 127 class SchedulerFactory { 128 public: 129 using AllocCB = std::function<TaskScheduler *()>; 130 using RecycleCB = std::function<void (TaskScheduler *)>; 131 Instance()132 static SchedulerFactory &Instance() 133 { 134 static SchedulerFactory fac; 135 return fac; 136 } 137 Alloc()138 static TaskScheduler *Alloc() 139 { 140 return Instance().alloc_(); 141 } 142 Recycle(TaskScheduler * schd)143 static void Recycle(TaskScheduler *schd) 144 { 145 Instance().recycle_(schd); 146 } 147 RegistCb(const AllocCB & alloc,const RecycleCB & recycle)148 static void RegistCb(const AllocCB &alloc, const RecycleCB &recycle) 149 { 150 Instance().alloc_ = alloc; 151 Instance().recycle_ = recycle; 152 } 153 154 private: 155 AllocCB alloc_; 156 RecycleCB recycle_; 157 }; 158 } // namespace ffrt 159 #endif 160