• 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_INTERVAL_HPP
17 #define FFRT_INTERVAL_HPP
18 
19 #include <deque>
20 
21 #include "sched/qos.h"
22 #include "sched/load_predictor.h"
23 #include "sched/load_tracking.h"
24 #include "eu/thread_group.h"
25 #include "sync/sync.h"
26 
27 namespace ffrt {
28 class Interval;
29 constexpr uint64_t NS_PER_US = 1000;
30 constexpr uint64_t NS_PER_MS = 1000000;
31 class Deadline {
32 public:
Deadline(uint64_t deadlineUs)33     Deadline(uint64_t deadlineUs)
34     {
35         Update(deadlineUs);
36     }
37 
ToNs()38     uint64_t ToNs() const
39     {
40         return deadlineNs;
41     }
42 
ToUs()43     uint64_t ToUs() const
44     {
45         uint64_t us = deadlineNs / NS_PER_US;
46         return us > 0 ? us : 1;
47     }
48 
ToMs()49     uint64_t ToMs() const
50     {
51         uint64_t ms = deadlineNs / NS_PER_MS;
52         return ms > 0 ? ms : 1;
53     }
54 
LeftNs()55     uint64_t LeftNs() const
56     {
57         uint64_t nowNs = AbsNowNs();
58         uint64_t left = (absDeadlineNs > nowNs) ? (absDeadlineNs - nowNs) : 1;
59         return left;
60     }
61 
62     void Update(uint64_t deadlineUs);
63 
64 private:
65     static uint64_t AbsNowNs();
66 
67     uint64_t deadlineNs = 0;
68     uint64_t absDeadlineNs = 0;
69 };
70 
71 class PerfCtrl {
72 public:
73     PerfCtrl(const QoS& qos);
74     ~PerfCtrl();
75 
Qos()76     const QoS& Qos() const
77     {
78         return qos;
79     }
80 
TG()81     ThreadGroup* TG()
82     {
83         return tg;
84     }
85 
isBusy()86     bool isBusy()
87     {
88         if (tg) {
89             return tg->isBegin();
90         }
91 
92         return false;
93     }
94 
Begin()95     void Begin()
96     {
97         if (tg) {
98             tg->Begin();
99         }
100     }
101 
End()102     void End()
103     {
104         if (tg) {
105             tg->End();
106         }
107     }
108 
GetLoad()109     uint64_t GetLoad()
110     {
111         return tg ? tg->GetLoad().load : 0;
112     }
113 
SetWindowSize(uint64_t size)114     void SetWindowSize(uint64_t size)
115     {
116         if (tg) {
117             tg->SetWindowSize(size);
118         }
119     }
120 
SetInvalidInterval(uint64_t interval)121     void SetInvalidInterval(uint64_t interval)
122     {
123         if (tg) {
124             tg->SetInvalidInterval(interval);
125         }
126     }
127 
Join()128     bool Join()
129     {
130         return tg ? tg->Join() : false;
131     }
132 
Leave()133     bool Leave()
134     {
135         return tg ? tg->Leave() : false;
136     }
137 
clear()138     void clear()
139     {
140         predUtil = 0;
141         curUtil = 0;
142     }
143 
144     void Update(bool force = false);
145     void Update(uint64_t deadlineNs, uint64_t load, bool force = false);
146 
147 private:
148     static constexpr int SCHED_CAPACITY_SHIFT = 10;
149     static constexpr int SCHED_MAX_CAPACITY = 1 << SCHED_CAPACITY_SHIFT;
150 
151     QoS qos;
152     ThreadGroup* tg = nullptr;
153 
154     uint64_t predUtil = 0;
155     uint64_t curUtil = 0;
156 };
157 
158 class IntervalLoadPredictor {
159 public:
IntervalLoadPredictor()160     IntervalLoadPredictor()
161     {
162         cpLoad.resize(1);
163     }
164 
ResetCPIndex()165     void ResetCPIndex()
166     {
167         cpLoadIndex = 0;
168     }
169 
170     void UpdateTotalLoad(uint64_t load);
171     void UpdateCPLoad(uint64_t load);
172 
173     uint64_t GetTotalLoad();
174     uint64_t GetCPLoad();
175 
176 private:
177     SimpleLoadPredictor totalLoad;
178     std::deque<SimpleLoadPredictor> cpLoad;
179     uint32_t cpLoadIndex = 0;
180 };
181 
182 class Interval {
183 public:
184 
Interval(uint64_t deadlineUs,const QoS & qos)185     Interval(uint64_t deadlineUs, const QoS& qos) : dl(deadlineUs)
186     {
187         (void)qos;
188     }
189     virtual ~Interval() = default;
190 
191     virtual int Begin() = 0;
192 
193     virtual void Update(uint64_t deadlineUs) = 0;
194 
195     virtual void End() = 0;
196 
197     virtual void CheckPoint() = 0;
198 
199     virtual void Join() = 0;
200 
201     virtual void Leave() = 0;
202 
203     virtual const QoS& Qos() const = 0;
204 
UpdateTaskSwitch(TaskSwitchState state)205     virtual void UpdateTaskSwitch(TaskSwitchState state)
206     {
207     }
208 
Ddl()209     Deadline& Ddl()
210     {
211         return dl;
212     }
213 private:
214     Deadline dl;
215 };
216 
217 class DefaultInterval : public Interval {
218 public:
219     DefaultInterval(uint64_t deadlineUs, const QoS& qos);
220     ~DefaultInterval() override;
221 
Enabled()222     bool Enabled() const
223     {
224         return enabled;
225     }
226 
Qos()227     const QoS& Qos() const override
228     {
229         return ctrl.Qos();
230     }
231 
Ctrl()232     PerfCtrl& Ctrl()
233     {
234         return ctrl;
235     }
236 
237     int Begin() override;
238 
239     void Update(uint64_t deadlineUs) override;
240 
241     void End() override;
242 
243     void CheckPoint() override;
244 
245     void Join() override;
246 
247     void Leave() override;
248 
249     void UpdateTaskSwitch(TaskSwitchState state) override;
250 
251 private:
252     bool enabled = false;
253 
254     KernelLoadTracking lt;
255     IntervalLoadPredictor lp;
256     PerfCtrl ctrl;
257 
258     fast_mutex mutex;
259 };
260 } // namespace ffrt
261 
262 #endif
263