• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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