xref: /DragonOS/kernel/src/sched/fair.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 use core::intrinsics::likely;
2 use core::intrinsics::unlikely;
3 use core::mem::swap;
4 use core::sync::atomic::fence;
5 use core::sync::atomic::{AtomicU64, Ordering};
6 
7 use crate::libs::rbtree::RBTree;
8 use crate::libs::spinlock::SpinLock;
9 use crate::process::ProcessControlBlock;
10 use crate::process::ProcessFlags;
11 use crate::sched::clock::ClockUpdataFlag;
12 use crate::sched::{cpu_rq, SchedFeature, SCHED_FEATURES};
13 use crate::smp::core::smp_get_processor_id;
14 use crate::time::jiffies::TICK_NESC;
15 use crate::time::timer::clock;
16 use crate::time::NSEC_PER_MSEC;
17 use alloc::sync::{Arc, Weak};
18 
19 use super::idle::IdleScheduler;
20 use super::pelt::{add_positive, sub_positive, SchedulerAvg, UpdateAvgFlags, PELT_MIN_DIVIDER};
21 use super::{
22     CpuRunQueue, DequeueFlag, EnqueueFlag, LoadWeight, OnRq, SchedPolicy, Scheduler, TaskGroup,
23     WakeupFlags, SCHED_CAPACITY_SHIFT,
24 };
25 
26 /// 用于设置 CPU-bound 任务的最小抢占粒度的参数。
27 /// 默认值为 0.75 毫秒乘以(1 加上 CPU 数量的二进制对数),单位为纳秒。
28 /// 这个值影响到任务在 CPU-bound 情况下的抢占行为。
29 static SYSCTL_SHCED_MIN_GRANULARITY: AtomicU64 = AtomicU64::new(750000);
30 /// 规范化最小抢占粒度参数
31 #[allow(dead_code)]
32 static NORMALIZED_SYSCTL_SCHED_MIN_GRANULARITY: AtomicU64 = AtomicU64::new(750000);
33 
34 static SYSCTL_SHCED_BASE_SLICE: AtomicU64 = AtomicU64::new(750000);
35 #[allow(dead_code)]
36 static NORMALIZED_SYSCTL_SHCED_BASE_SLICE: AtomicU64 = AtomicU64::new(750000);
37 
38 /// 预设的调度延迟任务数量
39 static SCHED_NR_LATENCY: AtomicU64 = AtomicU64::new(8);
40 
41 /// 调度实体单位,一个调度实体可以是一个进程、一个进程组或者是一个用户等等划分
42 #[derive(Debug)]
43 pub struct FairSchedEntity {
44     /// 负载相关
45     pub load: LoadWeight,
46     pub deadline: u64,
47     pub min_deadline: u64,
48 
49     /// 是否在运行队列中
50     pub on_rq: OnRq,
51     /// 当前调度实体的开始执行时间
52     pub exec_start: u64,
53     /// 总运行时长
54     pub sum_exec_runtime: u64,
55     /// 虚拟运行时间
56     pub vruntime: u64,
57     /// 进程的调度延迟 它等于进程的权重(weight)乘以(V - v_i),其中V是系统当前的时间,v_i是进程的运行时间
58     pub vlag: i64,
59     // 运行时间片
60     pub slice: u64,
61     /// 上一个调度实体运行总时间
62     pub prev_sum_exec_runtime: u64,
63 
64     pub avg: SchedulerAvg,
65 
66     /// 父节点
67     parent: Weak<FairSchedEntity>,
68 
69     pub depth: u32,
70 
71     /// 指向自身
72     self_ref: Weak<FairSchedEntity>,
73 
74     /// 所在的CFS运行队列
75     cfs_rq: Weak<CfsRunQueue>,
76 
77     /// group持有的私有cfs队列
78     my_cfs_rq: Option<Arc<CfsRunQueue>>,
79 
80     runnable_weight: u64,
81 
82     pcb: Weak<ProcessControlBlock>,
83 }
84 
85 impl FairSchedEntity {
86     pub fn new() -> Arc<Self> {
87         let ret = Arc::new(Self {
88             parent: Weak::new(),
89             self_ref: Weak::new(),
90             pcb: Weak::new(),
91             cfs_rq: Weak::new(),
92             my_cfs_rq: None,
93             on_rq: OnRq::None,
94             slice: SYSCTL_SHCED_BASE_SLICE.load(Ordering::SeqCst),
95             load: Default::default(),
96             deadline: Default::default(),
97             min_deadline: Default::default(),
98             exec_start: Default::default(),
99             sum_exec_runtime: Default::default(),
100             vruntime: Default::default(),
101             vlag: Default::default(),
102             prev_sum_exec_runtime: Default::default(),
103             avg: Default::default(),
104             depth: Default::default(),
105             runnable_weight: Default::default(),
106         });
107 
108         ret.force_mut().self_ref = Arc::downgrade(&ret);
109 
110         ret
111     }
112 }
113 
114 impl FairSchedEntity {
115     pub fn self_arc(&self) -> Arc<FairSchedEntity> {
116         self.self_ref.upgrade().unwrap()
117     }
118 
119     #[inline]
120     pub fn on_rq(&self) -> bool {
121         self.on_rq != OnRq::None
122     }
123 
124     pub fn pcb(&self) -> Arc<ProcessControlBlock> {
125         self.pcb.upgrade().unwrap()
126     }
127 
128     pub fn set_pcb(&mut self, pcb: Weak<ProcessControlBlock>) {
129         self.pcb = pcb
130     }
131 
132     #[inline]
133     pub fn cfs_rq(&self) -> Arc<CfsRunQueue> {
134         self.cfs_rq.upgrade().unwrap()
135     }
136 
137     pub fn set_cfs(&mut self, cfs: Weak<CfsRunQueue>) {
138         self.cfs_rq = cfs;
139     }
140 
141     pub fn parent(&self) -> Option<Arc<FairSchedEntity>> {
142         self.parent.upgrade()
143     }
144 
145     #[allow(clippy::mut_from_ref)]
146     pub fn force_mut(&self) -> &mut Self {
147         unsafe {
148             let p = self as *const Self as usize;
149             (p as *mut Self).as_mut().unwrap()
150         }
151     }
152 
153     /// 判断是否是进程持有的调度实体
154     #[inline]
155     pub fn is_task(&self) -> bool {
156         // TODO: 调度组
157         true
158     }
159 
160     #[inline]
161     pub fn is_idle(&self) -> bool {
162         if self.is_task() {
163             return self.pcb().sched_info().policy() == SchedPolicy::IDLE;
164         }
165 
166         return self.cfs_rq().is_idle();
167     }
168 
169     pub fn clear_buddies(&self) {
170         let mut se = self.self_arc();
171 
172         Self::for_each_in_group(&mut se, |se| {
173             let binding = se.cfs_rq();
174             let cfs_rq = binding.force_mut();
175 
176             if let Some(next) = cfs_rq.next.upgrade() {
177                 if !Arc::ptr_eq(&next, &se) {
178                     return (false, true);
179                 }
180             }
181             cfs_rq.next = Weak::new();
182             return (true, true);
183         });
184     }
185 
186     pub fn calculate_delta_fair(&self, delta: u64) -> u64 {
187         if unlikely(self.load.weight != LoadWeight::NICE_0_LOAD_SHIFT as u64) {
188             return self
189                 .force_mut()
190                 .load
191                 .calculate_delta(delta, LoadWeight::NICE_0_LOAD_SHIFT as u64);
192         };
193 
194         delta
195     }
196 
197     /// 更新组内的权重信息
198     pub fn update_cfs_group(&self) {
199         if self.my_cfs_rq.is_none() {
200             return;
201         }
202 
203         let group_cfs = self.my_cfs_rq.clone().unwrap();
204 
205         let shares = group_cfs.task_group().shares;
206 
207         if unlikely(self.load.weight != shares) {
208             // TODO: reweight
209             self.cfs_rq()
210                 .force_mut()
211                 .reweight_entity(self.self_arc(), shares);
212         }
213     }
214 
215     /// 遍历se组,如果返回false则需要调用的函数return,
216     /// 会将se指向其顶层parent
217     /// 该函数会改变se指向
218     /// 参数:
219     /// - se: 对应调度实体
220     /// - f: 对调度实体执行操作的闭包,返回值对应(no_break,should_continue),no_break为假时,退出循环,should_continue为假时表示需要将调用者return
221     ///
222     /// 返回值:
223     /// - bool: 是否需要调度者return
224     /// - Option<Arc<FairSchedEntity>>:最终se的指向
225     pub fn for_each_in_group(
226         se: &mut Arc<FairSchedEntity>,
227         mut f: impl FnMut(Arc<FairSchedEntity>) -> (bool, bool),
228     ) -> (bool, Option<Arc<FairSchedEntity>>) {
229         let mut should_continue;
230         let ret;
231         // 这一步是循环计算,直到根节点
232         // 比如有任务组 A ,有进程B,B属于A任务组,那么B的时间分配依赖于A组的权重以及B进程自己的权重
233         loop {
234             let (no_break, flag) = f(se.clone());
235             should_continue = flag;
236             if !no_break || !should_continue {
237                 ret = Some(se.clone());
238                 break;
239             }
240 
241             let parent = se.parent();
242             if parent.is_none() {
243                 ret = None;
244                 break;
245             }
246 
247             *se = parent.unwrap();
248         }
249 
250         (should_continue, ret)
251     }
252 
253     pub fn runnable(&self) -> u64 {
254         if self.is_task() {
255             return self.on_rq as u64;
256         } else {
257             self.runnable_weight
258         }
259     }
260 
261     /// 更新task和其cfsrq的负载均值
262     pub fn propagate_entity_load_avg(&mut self) -> bool {
263         if self.is_task() {
264             return false;
265         }
266 
267         let binding = self.my_cfs_rq.clone().unwrap();
268         let gcfs_rq = binding.force_mut();
269 
270         if gcfs_rq.propagate == 0 {
271             return false;
272         }
273 
274         gcfs_rq.propagate = 0;
275 
276         let binding = self.cfs_rq();
277         let cfs_rq = binding.force_mut();
278 
279         cfs_rq.add_task_group_propagate(gcfs_rq.prop_runnable_sum);
280 
281         cfs_rq.update_task_group_util(self.self_arc(), gcfs_rq);
282         cfs_rq.update_task_group_runnable(self.self_arc(), gcfs_rq);
283         cfs_rq.update_task_group_load(self.self_arc(), gcfs_rq);
284 
285         return true;
286     }
287 
288     /// 更新runnable_weight
289     pub fn update_runnable(&mut self) {
290         if !self.is_task() {
291             self.runnable_weight = self.my_cfs_rq.clone().unwrap().h_nr_running;
292         }
293     }
294 
295     /// 初始化实体运行均值
296     pub fn init_entity_runnable_average(&mut self) {
297         self.avg = SchedulerAvg::default();
298 
299         if self.is_task() {
300             self.avg.load_avg = LoadWeight::scale_load_down(self.load.weight) as usize;
301         }
302     }
303 }
304 
305 /// CFS的运行队列,这个队列需确保是percpu的
306 #[allow(dead_code)]
307 #[derive(Debug)]
308 pub struct CfsRunQueue {
309     load: LoadWeight,
310 
311     /// 全局运行的调度实体计数器,用于负载均衡
312     nr_running: u64,
313     /// 针对特定 CPU 核心的任务计数器
314     pub h_nr_running: u64,
315     /// 运行时间
316     exec_clock: u64,
317     /// 最少虚拟运行时间
318     min_vruntime: u64,
319     /// remain runtime
320     runtime_remaining: u64,
321 
322     /// 存放调度实体的红黑树
323     pub(super) entities: RBTree<u64, Arc<FairSchedEntity>>,
324 
325     /// IDLE
326     idle: usize,
327 
328     idle_nr_running: u64,
329 
330     pub idle_h_nr_running: u64,
331 
332     /// 当前运行的调度实体
333     current: Weak<FairSchedEntity>,
334     /// 下一个调度的实体
335     next: Weak<FairSchedEntity>,
336     /// 最后的调度实体
337     last: Weak<FairSchedEntity>,
338     /// 跳过运行的调度实体
339     skip: Weak<FairSchedEntity>,
340 
341     avg_load: i64,
342     avg_vruntime: i64,
343 
344     last_update_time_copy: u64,
345 
346     pub avg: SchedulerAvg,
347 
348     rq: Weak<CpuRunQueue>,
349     /// 拥有此队列的taskgroup
350     task_group: Weak<TaskGroup>,
351 
352     pub throttled_clock: u64,
353     pub throttled_clock_pelt: u64,
354     pub throttled_clock_pelt_time: u64,
355     pub throttled_pelt_idle: u64,
356 
357     pub throttled: bool,
358     pub throttled_count: u64,
359 
360     pub removed: SpinLock<CfsRemoved>,
361 
362     pub propagate: isize,
363     pub prop_runnable_sum: isize,
364 }
365 
366 #[derive(Debug, Default)]
367 pub struct CfsRemoved {
368     pub nr: u32,
369     pub load_avg: usize,
370     pub util_avg: usize,
371     pub runnable_avg: usize,
372 }
373 
374 impl CfsRunQueue {
375     pub fn new() -> Self {
376         Self {
377             load: LoadWeight::default(),
378             nr_running: 0,
379             h_nr_running: 0,
380             exec_clock: 0,
381             min_vruntime: 1 << 20,
382             entities: RBTree::new(),
383             idle: 0,
384             idle_nr_running: 0,
385             idle_h_nr_running: 0,
386             current: Weak::new(),
387             next: Weak::new(),
388             last: Weak::new(),
389             skip: Weak::new(),
390             avg_load: 0,
391             avg_vruntime: 0,
392             last_update_time_copy: 0,
393             avg: SchedulerAvg::default(),
394             rq: Weak::new(),
395             task_group: Weak::new(),
396             throttled_clock: 0,
397             throttled_clock_pelt: 0,
398             throttled_clock_pelt_time: 0,
399             throttled_pelt_idle: 0,
400             throttled: false,
401             throttled_count: 0,
402             removed: SpinLock::new(CfsRemoved::default()),
403             propagate: 0,
404             prop_runnable_sum: 0,
405             runtime_remaining: 0,
406         }
407     }
408 
409     #[inline]
410     pub fn rq(&self) -> Arc<CpuRunQueue> {
411         self.rq.upgrade().unwrap()
412     }
413 
414     #[inline]
415     pub fn set_rq(&mut self, rq: Weak<CpuRunQueue>) {
416         self.rq = rq;
417     }
418 
419     #[inline]
420     #[allow(clippy::mut_from_ref)]
421     pub fn force_mut(&self) -> &mut Self {
422         unsafe {
423             (self as *const Self as usize as *mut Self)
424                 .as_mut()
425                 .unwrap()
426         }
427     }
428 
429     #[inline]
430     pub fn is_idle(&self) -> bool {
431         self.idle > 0
432     }
433 
434     #[inline]
435     pub fn current(&self) -> Option<Arc<FairSchedEntity>> {
436         self.current.upgrade()
437     }
438 
439     #[inline]
440     pub fn set_current(&mut self, curr: Weak<FairSchedEntity>) {
441         self.current = curr
442     }
443 
444     #[inline]
445     pub fn next(&self) -> Option<Arc<FairSchedEntity>> {
446         self.next.upgrade()
447     }
448 
449     pub fn task_group(&self) -> Arc<TaskGroup> {
450         self.task_group.upgrade().unwrap()
451     }
452 
453     #[allow(dead_code)]
454     #[inline]
455     pub const fn bandwidth_used() -> bool {
456         false
457     }
458 
459     /// ## 计算调度周期,基本思想是在一个周期内让每个任务都至少运行一次。
460     /// 这样可以确保所有的任务都能够得到执行,而且可以避免某些任务被长时间地阻塞。
461     pub fn sched_period(nr_running: u64) -> u64 {
462         if unlikely(nr_running > SCHED_NR_LATENCY.load(Ordering::SeqCst)) {
463             // 如果当前活跃的任务数量超过了预设的调度延迟任务数量
464             // 调度周期的长度将直接设置为活跃任务数量乘以最小抢占粒度
465             return nr_running * SYSCTL_SHCED_MIN_GRANULARITY.load(Ordering::SeqCst);
466         } else {
467             // 如果活跃任务数量未超过预设的延迟任务数量,那么调度周期的长度将设置为SCHED_NR_LATENCY
468             return SCHED_NR_LATENCY.load(Ordering::SeqCst);
469         }
470     }
471 
472     /// ## 计算调度任务的虚拟运行时间片大小
473     ///
474     /// vruntime = runtime / weight
475     #[allow(dead_code)]
476     pub fn sched_vslice(&self, entity: Arc<FairSchedEntity>) -> u64 {
477         let slice = self.sched_slice(entity.clone());
478         return entity.calculate_delta_fair(slice);
479     }
480 
481     /// ## 计算调度任务的实际运行时间片大小
482     #[allow(dead_code)]
483     pub fn sched_slice(&self, mut entity: Arc<FairSchedEntity>) -> u64 {
484         let mut nr_running = self.nr_running;
485         if SCHED_FEATURES.contains(SchedFeature::ALT_PERIOD) {
486             nr_running = self.h_nr_running;
487         }
488 
489         // 计算一个调度周期的整个slice
490         let mut slice = Self::sched_period(nr_running + (!entity.on_rq()) as u64);
491 
492         // 这一步是循环计算,直到根节点
493         // 比如有任务组 A ,有进程B,B属于A任务组,那么B的时间分配依赖于A组的权重以及B进程自己的权重
494         FairSchedEntity::for_each_in_group(&mut entity, |se| {
495             if unlikely(!se.on_rq()) {
496                 se.cfs_rq().force_mut().load.update_load_add(se.load.weight);
497             }
498             slice = se
499                 .cfs_rq()
500                 .force_mut()
501                 .load
502                 .calculate_delta(slice, se.load.weight);
503 
504             (true, true)
505         });
506 
507         if SCHED_FEATURES.contains(SchedFeature::BASE_SLICE) {
508             // TODO: IDLE?
509             let min_gran = SYSCTL_SHCED_MIN_GRANULARITY.load(Ordering::SeqCst);
510 
511             slice = min_gran.max(slice)
512         }
513 
514         slice
515     }
516 
517     /// ## 在时间片到期时检查当前任务是否需要被抢占,
518     /// 如果需要,则抢占当前任务,并确保不会由于与其他任务的“好友偏爱(buddy favours)”而重新选举为下一个运行的任务。
519     #[allow(dead_code)]
520     pub fn check_preempt_tick(&mut self, curr: Arc<FairSchedEntity>) {
521         // 计算理想状态下该调度实体的理想运行时间
522         let ideal_runtime = self.sched_slice(curr.clone());
523 
524         let delta_exec = curr.sum_exec_runtime - curr.prev_sum_exec_runtime;
525 
526         if delta_exec > ideal_runtime {
527             // 表明实际运行时间长于理想运行时间
528             self.rq().resched_current();
529 
530             self.clear_buddies(&curr);
531             return;
532         }
533 
534         if delta_exec < SYSCTL_SHCED_MIN_GRANULARITY.load(Ordering::SeqCst) {
535             return;
536         }
537 
538         todo!()
539     }
540 
541     pub fn clear_buddies(&mut self, se: &Arc<FairSchedEntity>) {
542         if let Some(next) = self.next.upgrade() {
543             if Arc::ptr_eq(&next, se) {
544                 se.clear_buddies();
545             }
546         }
547     }
548 
549     /// 处理调度实体的时间片到期事件
550     pub fn entity_tick(&mut self, curr: Arc<FairSchedEntity>, queued: bool) {
551         // 更新当前调度实体的运行时间统计信息
552         self.update_current();
553 
554         self.update_load_avg(&curr, UpdateAvgFlags::UPDATE_TG);
555 
556         // 更新组调度相关
557         curr.update_cfs_group();
558 
559         if queued {
560             self.rq().resched_current();
561             return;
562         }
563     }
564 
565     /// 更新当前调度实体的运行时间统计信息
566     pub fn update_current(&mut self) {
567         let curr = self.current();
568         if unlikely(curr.is_none()) {
569             return;
570         }
571 
572         let now = self.rq().clock_task();
573         let curr = curr.unwrap();
574 
575         fence(Ordering::SeqCst);
576         if unlikely(now <= curr.exec_start) {
577             // warn!(
578             //     "update_current return now <= curr.exec_start now {now} execstart {}",
579             //     curr.exec_start
580             // );
581             return;
582         }
583 
584         fence(Ordering::SeqCst);
585         let delta_exec = now - curr.exec_start;
586 
587         let curr = curr.force_mut();
588 
589         curr.exec_start = now;
590 
591         curr.sum_exec_runtime += delta_exec;
592 
593         // 根据实际运行时长加权增加虚拟运行时长
594         curr.vruntime += curr.calculate_delta_fair(delta_exec);
595         fence(Ordering::SeqCst);
596         self.update_deadline(&curr.self_arc());
597         self.update_min_vruntime();
598 
599         self.account_cfs_rq_runtime(delta_exec);
600     }
601 
602     /// 计算当前cfs队列的运行时间是否到期
603     fn account_cfs_rq_runtime(&mut self, delta_exec: u64) {
604         if likely(self.runtime_remaining > delta_exec) {
605             self.runtime_remaining -= delta_exec;
606             // error!("runtime_remaining {}", self.runtime_remaining);
607             return;
608         }
609 
610         // warn!(
611         //     "runtime_remaining {} delta exec {delta_exec} nr_running {}",
612         //     self.runtime_remaining,
613         //     self.nr_running
614         // );
615         // fixme: 目前只是简单分配一个时间片
616         self.runtime_remaining = 5000 * NSEC_PER_MSEC as u64;
617 
618         if likely(self.current().is_some()) && self.nr_running > 1 {
619             // error!("account_cfs_rq_runtime");
620             self.rq().resched_current();
621         }
622     }
623 
624     /// 计算deadline,如果vruntime到期会重调度
625     pub fn update_deadline(&mut self, se: &Arc<FairSchedEntity>) {
626         // error!("vruntime {} deadline {}", se.vruntime, se.deadline);
627         if se.vruntime < se.deadline {
628             return;
629         }
630 
631         se.force_mut().slice = SYSCTL_SHCED_BASE_SLICE.load(Ordering::SeqCst);
632 
633         se.force_mut().deadline = se.vruntime + se.calculate_delta_fair(se.slice);
634 
635         if self.nr_running > 1 {
636             self.rq().resched_current();
637             self.clear_buddies(se);
638         }
639     }
640 
641     /// ## 更新最小虚拟运行时间
642     pub fn update_min_vruntime(&mut self) {
643         let curr = self.current();
644 
645         let mut vruntime = self.min_vruntime;
646 
647         if curr.is_some() {
648             let curr = curr.as_ref().unwrap();
649             if curr.on_rq() {
650                 vruntime = curr.vruntime;
651             } else {
652                 self.set_current(Weak::default());
653             }
654         }
655 
656         // 找到最小虚拟运行时间的调度实体
657         let leftmost = self.entities.get_first();
658         if let Some(leftmost) = leftmost {
659             let se = leftmost.1;
660 
661             if curr.is_none() {
662                 vruntime = se.vruntime;
663             } else {
664                 vruntime = vruntime.min(se.vruntime);
665             }
666         }
667 
668         self.min_vruntime = self.__update_min_vruntime(vruntime);
669     }
670 
671     fn __update_min_vruntime(&mut self, vruntime: u64) -> u64 {
672         let mut min_vruntime = self.min_vruntime;
673 
674         let delta = vruntime as i64 - min_vruntime as i64;
675         if delta > 0 {
676             self.avg_vruntime -= self.avg_load * delta;
677             min_vruntime = vruntime;
678         }
679 
680         return min_vruntime;
681     }
682 
683     // 判断是否为当前任务
684     pub fn is_curr(&self, se: &Arc<FairSchedEntity>) -> bool {
685         if self.current().is_none() {
686             false
687         } else {
688             // 判断当前和传入的se是否相等
689             Arc::ptr_eq(se, self.current().as_ref().unwrap())
690         }
691     }
692 
693     // 修改后
694     pub fn reweight_entity(&mut self, se: Arc<FairSchedEntity>, weight: u64) {
695         // 判断是否为当前任务
696         let is_curr = self.is_curr(&se);
697 
698         // 如果se在队列中
699         if se.on_rq() {
700             // 如果是当前任务
701             if is_curr {
702                 self.update_current();
703             } else {
704                 // 否则,出队
705                 self.inner_dequeue_entity(&se);
706             }
707 
708             // 减去该权重
709             self.load.update_load_sub(se.load.weight);
710         }
711 
712         self.dequeue_load_avg(&se);
713 
714         if !se.on_rq() {
715             se.force_mut().vlag = se.vlag * se.load.weight as i64 / weight as i64;
716         } else {
717             self.reweight_eevdf(&se, weight);
718         }
719         se.force_mut().load.update_load_set(weight);
720 
721         // SMP
722         let divider = se.avg.get_pelt_divider();
723         se.force_mut().avg.load_avg = LoadWeight::scale_load_down(se.load.weight) as usize
724             * se.avg.load_sum as usize
725             / divider;
726 
727         self.enqueue_load_avg(se.clone());
728 
729         if se.on_rq() {
730             self.load.update_load_add(se.load.weight);
731             if !is_curr {
732                 self.inner_enqueue_entity(&se);
733             }
734 
735             self.update_min_vruntime();
736         }
737     }
738 
739     /// 用于重新计算调度实体(sched_entity)的权重(weight)和虚拟运行时间(vruntime)
740     fn reweight_eevdf(&mut self, se: &Arc<FairSchedEntity>, weight: u64) {
741         let old_weight = se.load.weight;
742         let avg_vruntime = self.avg_vruntime();
743         let mut vlag;
744         if avg_vruntime != se.vruntime {
745             vlag = avg_vruntime as i64 - se.vruntime as i64;
746             vlag = vlag * old_weight as i64 / weight as i64;
747             se.force_mut().vruntime = (avg_vruntime as i64 - vlag) as u64;
748         }
749 
750         let mut vslice = se.deadline as i64 - avg_vruntime as i64;
751         vslice = vslice * old_weight as i64 / weight as i64;
752         se.force_mut().deadline = avg_vruntime + vslice as u64;
753     }
754 
755     fn avg_vruntime(&self) -> u64 {
756         let curr = self.current();
757         let mut avg = self.avg_vruntime;
758         let mut load = self.avg_load;
759 
760         if let Some(curr) = curr {
761             if curr.on_rq() {
762                 let weight = LoadWeight::scale_load_down(curr.load.weight);
763                 avg += self.entity_key(&curr) * weight as i64;
764                 load += weight as i64;
765             }
766         }
767 
768         if load > 0 {
769             if avg < 0 {
770                 avg -= load - 1;
771             }
772 
773             avg /= load;
774         }
775 
776         return self.min_vruntime + avg as u64;
777     }
778 
779     #[inline]
780     pub fn entity_key(&self, se: &Arc<FairSchedEntity>) -> i64 {
781         return se.vruntime as i64 - self.min_vruntime as i64;
782     }
783 
784     pub fn avg_vruntime_add(&mut self, se: &Arc<FairSchedEntity>) {
785         let weight = LoadWeight::scale_load_down(se.load.weight);
786 
787         let key = self.entity_key(se);
788 
789         let avg_vruntime = self.avg_vruntime + key * weight as i64;
790 
791         self.avg_vruntime = avg_vruntime;
792         self.avg_load += weight as i64;
793     }
794 
795     pub fn avg_vruntime_sub(&mut self, se: &Arc<FairSchedEntity>) {
796         let weight = LoadWeight::scale_load_down(se.load.weight);
797 
798         let key = self.entity_key(se);
799 
800         let avg_vruntime = self.avg_vruntime - key * weight as i64;
801 
802         self.avg_vruntime = avg_vruntime;
803         self.avg_load -= weight as i64;
804     }
805 
806     /// 为调度实体计算初始vruntime等信息
807     fn place_entity(&mut self, se: Arc<FairSchedEntity>, flags: EnqueueFlag) {
808         let vruntime = self.avg_vruntime();
809         let mut lag = 0;
810 
811         let se = se.force_mut();
812         se.slice = SYSCTL_SHCED_BASE_SLICE.load(Ordering::SeqCst);
813 
814         let mut vslice = se.calculate_delta_fair(se.slice);
815 
816         if self.nr_running > 0 {
817             let curr = self.current();
818 
819             lag = se.vlag;
820 
821             let mut load = self.avg_load;
822 
823             if let Some(curr) = curr {
824                 if curr.on_rq() {
825                     load += LoadWeight::scale_load_down(curr.load.weight) as i64;
826                 }
827             }
828 
829             lag *= load + LoadWeight::scale_load_down(se.load.weight) as i64;
830 
831             if load == 0 {
832                 load = 1;
833             }
834 
835             lag /= load;
836         }
837 
838         se.vruntime = vruntime - lag as u64;
839 
840         if flags.contains(EnqueueFlag::ENQUEUE_INITIAL) {
841             vslice /= 2;
842         }
843 
844         se.deadline = se.vruntime + vslice;
845     }
846 
847     /// 更新负载均值
848     fn update_load_avg(&mut self, se: &Arc<FairSchedEntity>, flags: UpdateAvgFlags) {
849         let now = self.cfs_rq_clock_pelt();
850 
851         if se.avg.last_update_time > 0 && !flags.contains(UpdateAvgFlags::SKIP_AGE_LOAD) {
852             se.force_mut().update_load_avg(self, now);
853         }
854 
855         let mut decayed = self.update_self_load_avg(now);
856         decayed |= se.force_mut().propagate_entity_load_avg() as u32;
857 
858         if se.avg.last_update_time > 0 && flags.contains(UpdateAvgFlags::DO_ATTACH) {
859             todo!()
860         } else if flags.contains(UpdateAvgFlags::DO_ATTACH) {
861             self.detach_entity_load_avg(se);
862         } else if decayed > 0 {
863             // cfs_rq_util_change
864 
865             todo!()
866         }
867     }
868 
869     /// 将实体的负载均值与对应cfs分离
870     fn detach_entity_load_avg(&mut self, se: &Arc<FairSchedEntity>) {
871         self.dequeue_load_avg(se);
872 
873         sub_positive(&mut self.avg.util_avg, se.avg.util_avg);
874         sub_positive(&mut (self.avg.util_sum as usize), se.avg.util_sum as usize);
875         self.avg.util_sum = self
876             .avg
877             .util_sum
878             .max((self.avg.util_avg * PELT_MIN_DIVIDER) as u64);
879 
880         sub_positive(&mut self.avg.runnable_avg, se.avg.runnable_avg);
881         sub_positive(
882             &mut (self.avg.runnable_sum as usize),
883             se.avg.runnable_sum as usize,
884         );
885         self.avg.runnable_sum = self
886             .avg
887             .runnable_sum
888             .max((self.avg.runnable_avg * PELT_MIN_DIVIDER) as u64);
889 
890         self.propagate = 1;
891         self.prop_runnable_sum += se.avg.load_sum as isize;
892     }
893 
894     fn update_self_load_avg(&mut self, now: u64) -> u32 {
895         let mut removed_load = 0;
896         let mut removed_util = 0;
897         let mut removed_runnable = 0;
898 
899         let mut decayed = 0;
900 
901         if self.removed.lock().nr > 0 {
902             let mut removed_guard = self.removed.lock();
903             let divider = self.avg.get_pelt_divider();
904 
905             swap::<usize>(&mut removed_guard.util_avg, &mut removed_util);
906             swap::<usize>(&mut removed_guard.load_avg, &mut removed_load);
907             swap::<usize>(&mut removed_guard.runnable_avg, &mut removed_runnable);
908 
909             removed_guard.nr = 0;
910 
911             let mut r = removed_load;
912 
913             sub_positive(&mut self.avg.load_avg, r);
914             sub_positive(&mut (self.avg.load_sum as usize), r * divider);
915 
916             self.avg.load_sum = self
917                 .avg
918                 .load_sum
919                 .max((self.avg.load_avg * PELT_MIN_DIVIDER) as u64);
920 
921             r = removed_util;
922             sub_positive(&mut self.avg.util_avg, r);
923             sub_positive(&mut (self.avg.util_sum as usize), r * divider);
924             self.avg.util_sum = self
925                 .avg
926                 .util_sum
927                 .max((self.avg.util_avg * PELT_MIN_DIVIDER) as u64);
928 
929             r = removed_runnable;
930             sub_positive(&mut self.avg.runnable_avg, r);
931             sub_positive(&mut (self.avg.runnable_sum as usize), r * divider);
932             self.avg.runnable_sum = self
933                 .avg
934                 .runnable_sum
935                 .max((self.avg.runnable_avg * PELT_MIN_DIVIDER) as u64);
936 
937             drop(removed_guard);
938             self.add_task_group_propagate(
939                 -(removed_runnable as isize * divider as isize) >> SCHED_CAPACITY_SHIFT,
940             );
941 
942             decayed = 1;
943         }
944 
945         decayed |= self.__update_load_avg(now) as u32;
946 
947         self.last_update_time_copy = self.avg.last_update_time;
948 
949         return decayed;
950     }
951 
952     fn __update_load_avg(&mut self, now: u64) -> bool {
953         if self.avg.update_load_sum(
954             now,
955             LoadWeight::scale_load_down(self.load.weight) as u32,
956             self.h_nr_running as u32,
957             self.current().is_some() as u32,
958         ) {
959             self.avg.update_load_avg(1);
960             return true;
961         }
962 
963         return false;
964     }
965 
966     fn add_task_group_propagate(&mut self, runnable_sum: isize) {
967         self.propagate = 1;
968         self.prop_runnable_sum += runnable_sum;
969     }
970 
971     /// 将实体加入队列
972     pub fn enqueue_entity(&mut self, se: &Arc<FairSchedEntity>, flags: EnqueueFlag) {
973         let is_curr = self.is_curr(se);
974 
975         if is_curr {
976             self.place_entity(se.clone(), flags);
977         }
978 
979         self.update_current();
980 
981         self.update_load_avg(se, UpdateAvgFlags::UPDATE_TG | UpdateAvgFlags::DO_ATTACH);
982 
983         se.force_mut().update_runnable();
984 
985         se.update_cfs_group();
986 
987         if !is_curr {
988             self.place_entity(se.clone(), flags);
989         }
990 
991         self.account_entity_enqueue(se);
992 
993         if flags.contains(EnqueueFlag::ENQUEUE_MIGRATED) {
994             se.force_mut().exec_start = 0;
995         }
996 
997         if !is_curr {
998             self.inner_enqueue_entity(se);
999         }
1000 
1001         se.force_mut().on_rq = OnRq::Queued;
1002 
1003         if self.nr_running == 1 {
1004             // 只有上面加入的
1005             // TODO: throttle
1006         }
1007     }
1008 
1009     pub fn dequeue_entity(&mut self, se: &Arc<FairSchedEntity>, flags: DequeueFlag) {
1010         let mut action = UpdateAvgFlags::UPDATE_TG;
1011 
1012         if se.is_task() && se.on_rq == OnRq::Migrating {
1013             action |= UpdateAvgFlags::DO_DETACH;
1014         }
1015 
1016         self.update_current();
1017 
1018         self.update_load_avg(se, action);
1019 
1020         se.force_mut().update_runnable();
1021 
1022         self.clear_buddies(se);
1023 
1024         self.update_entity_lag(se);
1025 
1026         if let Some(curr) = self.current() {
1027             if !Arc::ptr_eq(&curr, se) {
1028                 self.inner_dequeue_entity(se);
1029             }
1030         } else {
1031             self.inner_dequeue_entity(se);
1032         }
1033 
1034         se.force_mut().on_rq = OnRq::None;
1035 
1036         self.account_entity_dequeue(se);
1037 
1038         // return_cfs_rq_runtime
1039 
1040         se.update_cfs_group();
1041 
1042         if flags & (DequeueFlag::DEQUEUE_SAVE | DequeueFlag::DEQUEUE_MOVE)
1043             != DequeueFlag::DEQUEUE_SAVE
1044         {
1045             self.update_min_vruntime();
1046         }
1047 
1048         if self.nr_running == 0 {
1049             self.update_idle_clock_pelt()
1050         }
1051     }
1052 
1053     /// 将前一个调度的task放回队列
1054     pub fn put_prev_entity(&mut self, prev: Arc<FairSchedEntity>) {
1055         if prev.on_rq() {
1056             self.update_current();
1057         }
1058 
1059         if prev.on_rq() {
1060             self.inner_enqueue_entity(&prev);
1061         }
1062 
1063         self.set_current(Weak::default());
1064     }
1065 
1066     /// 将下一个运行的task设置为current
1067     pub fn set_next_entity(&mut self, se: &Arc<FairSchedEntity>) {
1068         self.clear_buddies(se);
1069 
1070         if se.on_rq() {
1071             self.inner_dequeue_entity(se);
1072             self.update_load_avg(se, UpdateAvgFlags::UPDATE_TG);
1073             se.force_mut().vlag = se.deadline as i64;
1074         }
1075 
1076         self.set_current(Arc::downgrade(se));
1077 
1078         se.force_mut().prev_sum_exec_runtime = se.sum_exec_runtime;
1079     }
1080 
1081     fn update_idle_clock_pelt(&mut self) {
1082         let throttled = if unlikely(self.throttled_count > 0) {
1083             u64::MAX
1084         } else {
1085             self.throttled_clock_pelt_time
1086         };
1087 
1088         self.throttled_clock_pelt = throttled;
1089     }
1090 
1091     fn update_entity_lag(&mut self, se: &Arc<FairSchedEntity>) {
1092         let lag = self.avg_vruntime() as i64 - se.vruntime as i64;
1093 
1094         let limit = se.calculate_delta_fair((TICK_NESC as u64).max(2 * se.slice)) as i64;
1095 
1096         se.force_mut().vlag = if lag < -limit {
1097             -limit
1098         } else if lag > limit {
1099             limit
1100         } else {
1101             lag
1102         }
1103     }
1104 
1105     fn account_entity_enqueue(&mut self, se: &Arc<FairSchedEntity>) {
1106         self.load.update_load_add(se.load.weight);
1107 
1108         if se.is_task() {
1109             let rq = self.rq();
1110             let (rq, _guard) = rq.self_lock();
1111             // TODO:numa
1112             rq.cfs_tasks.push_back(se.clone());
1113         }
1114         self.nr_running += 1;
1115         if se.is_idle() {
1116             self.idle_nr_running += 1;
1117         }
1118     }
1119 
1120     fn account_entity_dequeue(&mut self, se: &Arc<FairSchedEntity>) {
1121         self.load.update_load_sub(se.load.weight);
1122 
1123         if se.is_task() {
1124             let rq = self.rq();
1125             let (rq, _guard) = rq.self_lock();
1126 
1127             // TODO:numa
1128             let _ = rq.cfs_tasks.extract_if(|x| Arc::ptr_eq(x, se));
1129         }
1130 
1131         self.nr_running -= 1;
1132         if se.is_idle() {
1133             self.idle_nr_running -= 1;
1134         }
1135     }
1136 
1137     pub fn inner_enqueue_entity(&mut self, se: &Arc<FairSchedEntity>) {
1138         self.avg_vruntime_add(se);
1139         se.force_mut().min_deadline = se.deadline;
1140         self.entities.insert(se.vruntime, se.clone());
1141         // warn!(
1142         //     "enqueue pcb {:?} cfsrq {:?}",
1143         //     se.pcb().pid(),
1144         //     self.entities
1145         //         .iter()
1146         //         .map(|x| (x.0, x.1.pcb().pid()))
1147         //         .collect::<Vec<_>>()
1148         // );
1149         // send_to_default_serial8250_port(
1150         //     format!(
1151         //         "enqueue pcb {:?} cfsrq {:?}\n",
1152         //         se.pcb().pid(),
1153         //         self.entities
1154         //             .iter()
1155         //             .map(|x| (x.0, x.1.pcb().pid()))
1156         //             .collect::<Vec<_>>()
1157         //     )
1158         //     .as_bytes(),
1159         // );
1160     }
1161 
1162     fn inner_dequeue_entity(&mut self, se: &Arc<FairSchedEntity>) {
1163         // warn!(
1164         //     "before dequeue pcb {:?} cfsrq {:?}",
1165         //     se.pcb().pid(),
1166         //     self.entities
1167         //         .iter()
1168         //         .map(|x| (x.0, x.1.pcb().pid()))
1169         //         .collect::<Vec<_>>()
1170         // );
1171 
1172         // send_to_default_serial8250_port(
1173         //     format!(
1174         //         "before dequeue pcb {:?} cfsrq {:?}\n",
1175         //         se.pcb().pid(),
1176         //         self.entities
1177         //             .iter()
1178         //             .map(|x| (x.0, x.1.pcb().pid()))
1179         //             .collect::<Vec<_>>()
1180         //     )
1181         //     .as_bytes(),
1182         // );
1183 
1184         let mut i = 1;
1185         while let Some(rm) = self.entities.remove(&se.vruntime) {
1186             if Arc::ptr_eq(&rm, se) {
1187                 break;
1188             }
1189             rm.force_mut().vruntime += i;
1190             self.entities.insert(rm.vruntime, rm);
1191 
1192             i += 1;
1193         }
1194         // send_to_default_serial8250_port(
1195         //     format!(
1196         //         "after dequeue pcb {:?}(real: {:?}) cfsrq {:?}\n",
1197         //         se.pcb().pid(),
1198         //         remove.pcb().pid(),
1199         //         self.entities
1200         //             .iter()
1201         //             .map(|x| (x.0, x.1.pcb().pid()))
1202         //             .collect::<Vec<_>>()
1203         //     )
1204         //     .as_bytes(),
1205         // );
1206         // warn!(
1207         //     "after dequeue pcb {:?}(real: {:?}) cfsrq {:?}",
1208         //     se.pcb().pid(),
1209         //     remove.pcb().pid(),
1210         //     self.entities
1211         //         .iter()
1212         //         .map(|x| (x.0, x.1.pcb().pid()))
1213         //         .collect::<Vec<_>>()
1214         // );
1215         self.avg_vruntime_sub(se);
1216     }
1217 
1218     pub fn enqueue_load_avg(&mut self, se: Arc<FairSchedEntity>) {
1219         self.avg.load_avg += se.avg.load_avg;
1220         self.avg.load_sum += LoadWeight::scale_load_down(se.load.weight) * se.avg.load_sum;
1221     }
1222 
1223     pub fn dequeue_load_avg(&mut self, se: &Arc<FairSchedEntity>) {
1224         if self.avg.load_avg > se.avg.load_avg {
1225             self.avg.load_avg -= se.avg.load_avg;
1226         } else {
1227             self.avg.load_avg = 0;
1228         };
1229 
1230         let se_load = LoadWeight::scale_load_down(se.load.weight) * se.avg.load_sum;
1231 
1232         if self.avg.load_sum > se_load {
1233             self.avg.load_sum -= se_load;
1234         } else {
1235             self.avg.load_sum = 0;
1236         }
1237 
1238         self.avg.load_sum = self
1239             .avg
1240             .load_sum
1241             .max((self.avg.load_avg * PELT_MIN_DIVIDER) as u64)
1242     }
1243 
1244     pub fn update_task_group_util(&mut self, se: Arc<FairSchedEntity>, gcfs_rq: &CfsRunQueue) {
1245         let mut delta_sum = gcfs_rq.avg.load_avg as isize - se.avg.load_avg as isize;
1246         let delta_avg = delta_sum;
1247 
1248         if delta_avg == 0 {
1249             return;
1250         }
1251 
1252         let divider = self.avg.get_pelt_divider();
1253 
1254         let se = se.force_mut();
1255         se.avg.util_avg = gcfs_rq.avg.util_avg;
1256         let new_sum = se.avg.util_avg * divider;
1257         delta_sum = new_sum as isize - se.avg.util_sum as isize;
1258 
1259         se.avg.util_sum = new_sum as u64;
1260 
1261         add_positive(&mut (self.avg.util_avg as isize), delta_avg);
1262         add_positive(&mut (self.avg.util_sum as isize), delta_sum);
1263 
1264         self.avg.util_sum = self
1265             .avg
1266             .util_sum
1267             .max((self.avg.util_avg * PELT_MIN_DIVIDER) as u64);
1268     }
1269 
1270     pub fn update_task_group_runnable(&mut self, se: Arc<FairSchedEntity>, gcfs_rq: &CfsRunQueue) {
1271         let mut delta_sum = gcfs_rq.avg.runnable_avg as isize - se.avg.runnable_avg as isize;
1272         let delta_avg = delta_sum;
1273 
1274         if delta_avg == 0 {
1275             return;
1276         }
1277 
1278         let divider = self.avg.get_pelt_divider();
1279 
1280         let se = se.force_mut();
1281         se.avg.runnable_avg = gcfs_rq.avg.runnable_avg;
1282         let new_sum = se.avg.runnable_sum * divider as u64;
1283         delta_sum = new_sum as isize - se.avg.runnable_sum as isize;
1284 
1285         se.avg.runnable_sum = new_sum;
1286 
1287         add_positive(&mut (self.avg.runnable_avg as isize), delta_avg);
1288         add_positive(&mut (self.avg.runnable_sum as isize), delta_sum);
1289 
1290         self.avg.runnable_sum = self
1291             .avg
1292             .runnable_sum
1293             .max((self.avg.runnable_avg * PELT_MIN_DIVIDER) as u64);
1294     }
1295 
1296     pub fn update_task_group_load(&mut self, se: Arc<FairSchedEntity>, gcfs_rq: &mut CfsRunQueue) {
1297         let mut runnable_sum = gcfs_rq.prop_runnable_sum;
1298 
1299         let mut load_sum = 0;
1300 
1301         if runnable_sum == 0 {
1302             return;
1303         }
1304 
1305         gcfs_rq.prop_runnable_sum = 0;
1306 
1307         let divider = self.avg.get_pelt_divider();
1308 
1309         if runnable_sum >= 0 {
1310             runnable_sum += se.avg.load_sum as isize;
1311             runnable_sum = runnable_sum.min(divider as isize);
1312         } else {
1313             if LoadWeight::scale_load_down(gcfs_rq.load.weight) > 0 {
1314                 load_sum = gcfs_rq.avg.load_sum / LoadWeight::scale_load_down(gcfs_rq.load.weight);
1315             }
1316 
1317             runnable_sum = se.avg.load_sum.min(load_sum) as isize;
1318         }
1319 
1320         let running_sum = se.avg.util_sum as isize >> SCHED_CAPACITY_SHIFT;
1321         runnable_sum = runnable_sum.max(running_sum);
1322 
1323         load_sum = LoadWeight::scale_load_down(se.load.weight) * runnable_sum as u64;
1324         let load_avg = load_sum / divider as u64;
1325 
1326         let delta_avg = load_avg as isize - se.avg.load_avg as isize;
1327         if delta_avg == 0 {
1328             return;
1329         }
1330 
1331         let delta_sum = load_sum as isize
1332             - LoadWeight::scale_load_down(se.load.weight) as isize * se.avg.load_sum as isize;
1333 
1334         let se = se.force_mut();
1335         se.avg.load_sum = runnable_sum as u64;
1336         se.avg.load_avg = load_avg as usize;
1337 
1338         add_positive(&mut (self.avg.load_avg as isize), delta_avg);
1339         add_positive(&mut (self.avg.util_sum as isize), delta_sum);
1340 
1341         self.avg.load_sum = self
1342             .avg
1343             .load_sum
1344             .max((self.avg.load_avg * PELT_MIN_DIVIDER) as u64);
1345     }
1346 
1347     /// pick下一个运行的task
1348     pub fn pick_next_entity(&self) -> Option<Arc<FairSchedEntity>> {
1349         if SCHED_FEATURES.contains(SchedFeature::NEXT_BUDDY)
1350             && self.next().is_some()
1351             && self.entity_eligible(&self.next().unwrap())
1352         {
1353             return self.next();
1354         }
1355         self.entities.get_first().map(|val| val.1.clone())
1356     }
1357 
1358     pub fn entity_eligible(&self, se: &Arc<FairSchedEntity>) -> bool {
1359         let curr = self.current();
1360         let mut avg = self.avg_vruntime;
1361         let mut load = self.avg_load;
1362 
1363         if let Some(curr) = curr {
1364             if curr.on_rq() {
1365                 let weight = LoadWeight::scale_load_down(curr.load.weight);
1366 
1367                 avg += self.entity_key(&curr) * weight as i64;
1368                 load += weight as i64;
1369             }
1370         }
1371 
1372         return avg >= self.entity_key(se) * load;
1373     }
1374 }
1375 
1376 impl Default for CfsRunQueue {
1377     fn default() -> Self {
1378         Self::new()
1379     }
1380 }
1381 pub struct CompletelyFairScheduler;
1382 
1383 impl CompletelyFairScheduler {
1384     /// 寻找到最近公共组长
1385     fn find_matching_se(se: &mut Arc<FairSchedEntity>, pse: &mut Arc<FairSchedEntity>) {
1386         let mut se_depth = se.depth;
1387         let mut pse_depth = pse.depth;
1388 
1389         while se_depth > pse_depth {
1390             se_depth -= 1;
1391             *se = se.parent().unwrap();
1392         }
1393 
1394         while pse_depth > se_depth {
1395             pse_depth -= 1;
1396             *pse = pse.parent().unwrap();
1397         }
1398 
1399         while !Arc::ptr_eq(&se.cfs_rq(), &pse.cfs_rq()) {
1400             *se = se.parent().unwrap();
1401             *pse = pse.parent().unwrap();
1402         }
1403     }
1404 }
1405 
1406 impl Scheduler for CompletelyFairScheduler {
1407     fn enqueue(
1408         rq: &mut CpuRunQueue,
1409         pcb: Arc<crate::process::ProcessControlBlock>,
1410         mut flags: EnqueueFlag,
1411     ) {
1412         let mut se = pcb.sched_info().sched_entity();
1413         let mut idle_h_nr_running = pcb.sched_info().policy() == SchedPolicy::IDLE;
1414         let (should_continue, se) = FairSchedEntity::for_each_in_group(&mut se, |se| {
1415             if se.on_rq() {
1416                 return (false, true);
1417             }
1418 
1419             let binding = se.cfs_rq();
1420             let cfs_rq = binding.force_mut();
1421             cfs_rq.enqueue_entity(&se, flags);
1422 
1423             cfs_rq.h_nr_running += 1;
1424             cfs_rq.idle_h_nr_running += idle_h_nr_running as u64;
1425 
1426             if cfs_rq.is_idle() {
1427                 idle_h_nr_running = true;
1428             }
1429 
1430             // TODO: cfs_rq_throttled
1431 
1432             flags = EnqueueFlag::ENQUEUE_WAKEUP;
1433 
1434             return (true, true);
1435         });
1436 
1437         if !should_continue {
1438             return;
1439         }
1440 
1441         if let Some(mut se) = se {
1442             FairSchedEntity::for_each_in_group(&mut se, |se| {
1443                 let binding = se.cfs_rq();
1444                 let cfs_rq = binding.force_mut();
1445 
1446                 cfs_rq.update_load_avg(&se, UpdateAvgFlags::UPDATE_TG);
1447 
1448                 let se = se.force_mut();
1449                 se.update_runnable();
1450 
1451                 se.update_cfs_group();
1452 
1453                 cfs_rq.h_nr_running += 1;
1454                 cfs_rq.idle_h_nr_running += idle_h_nr_running as u64;
1455 
1456                 if cfs_rq.is_idle() {
1457                     idle_h_nr_running = true;
1458                 }
1459 
1460                 // TODO: cfs_rq_throttled
1461 
1462                 return (true, true);
1463             });
1464         }
1465 
1466         rq.add_nr_running(1);
1467     }
1468 
1469     fn dequeue(
1470         rq: &mut CpuRunQueue,
1471         pcb: Arc<crate::process::ProcessControlBlock>,
1472         mut flags: DequeueFlag,
1473     ) {
1474         let mut se = pcb.sched_info().sched_entity();
1475         let mut idle_h_nr_running = pcb.sched_info().policy() == SchedPolicy::IDLE;
1476         let task_sleep = flags.contains(DequeueFlag::DEQUEUE_SLEEP);
1477         let was_sched_idle = rq.sched_idle_rq();
1478 
1479         let (should_continue, se) = FairSchedEntity::for_each_in_group(&mut se, |se| {
1480             let binding = se.cfs_rq();
1481             let cfs_rq = binding.force_mut();
1482             cfs_rq.dequeue_entity(&se, flags);
1483 
1484             cfs_rq.h_nr_running -= 1;
1485             cfs_rq.idle_h_nr_running -= idle_h_nr_running as u64;
1486 
1487             if cfs_rq.is_idle() {
1488                 idle_h_nr_running = true;
1489             }
1490 
1491             // TODO: cfs_rq_throttled
1492 
1493             if cfs_rq.load.weight > 0 {
1494                 let sep = se.parent();
1495 
1496                 if task_sleep && sep.is_some() {
1497                     todo!()
1498                 }
1499             }
1500 
1501             flags |= DequeueFlag::DEQUEUE_SLEEP;
1502 
1503             return (true, true);
1504         });
1505 
1506         if !should_continue {
1507             return;
1508         }
1509 
1510         if let Some(mut se) = se {
1511             FairSchedEntity::for_each_in_group(&mut se, |se| {
1512                 let binding = se.cfs_rq();
1513                 let cfs_rq = binding.force_mut();
1514 
1515                 cfs_rq.update_load_avg(&se, UpdateAvgFlags::UPDATE_TG);
1516 
1517                 let se = se.force_mut();
1518                 se.update_runnable();
1519 
1520                 se.update_cfs_group();
1521 
1522                 cfs_rq.h_nr_running -= 1;
1523                 cfs_rq.idle_h_nr_running -= idle_h_nr_running as u64;
1524 
1525                 if cfs_rq.is_idle() {
1526                     idle_h_nr_running = true;
1527                 }
1528 
1529                 // TODO: cfs_rq_throttled
1530 
1531                 return (true, true);
1532             });
1533         }
1534 
1535         rq.sub_nr_running(1);
1536 
1537         if unlikely(!was_sched_idle && rq.sched_idle_rq()) {
1538             rq.next_balance = clock();
1539         }
1540     }
1541 
1542     fn yield_task(rq: &mut CpuRunQueue) {
1543         let curr = rq.current();
1544         let se = curr.sched_info().sched_entity();
1545         let binding = se.cfs_rq();
1546         let cfs_rq = binding.force_mut();
1547 
1548         if unlikely(rq.nr_running == 1) {
1549             return;
1550         }
1551 
1552         cfs_rq.clear_buddies(&se);
1553 
1554         rq.update_rq_clock();
1555 
1556         cfs_rq.update_current();
1557 
1558         rq.clock_updata_flags |= ClockUpdataFlag::RQCF_REQ_SKIP;
1559 
1560         se.force_mut().deadline += se.calculate_delta_fair(se.slice);
1561     }
1562 
1563     fn check_preempt_currnet(
1564         rq: &mut CpuRunQueue,
1565         pcb: &Arc<crate::process::ProcessControlBlock>,
1566         wake_flags: WakeupFlags,
1567     ) {
1568         let curr = rq.current();
1569         let mut se = curr.sched_info().sched_entity();
1570         let mut pse = pcb.sched_info().sched_entity();
1571 
1572         if unlikely(Arc::ptr_eq(&se, &pse)) {
1573             return;
1574         }
1575 
1576         // TODO:https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/sched/fair.c#8160
1577 
1578         let _next_buddy_mark = if SCHED_FEATURES.contains(SchedFeature::NEXT_BUDDY)
1579             && !wake_flags.contains(WakeupFlags::WF_FORK)
1580         {
1581             FairSchedEntity::for_each_in_group(&mut pse, |se| {
1582                 if !se.on_rq() {
1583                     return (false, true);
1584                 }
1585 
1586                 if se.is_idle() {
1587                     return (false, true);
1588                 }
1589 
1590                 se.cfs_rq().force_mut().next = Arc::downgrade(&se);
1591 
1592                 return (true, true);
1593             });
1594             true
1595         } else {
1596             false
1597         };
1598 
1599         if curr.flags().contains(ProcessFlags::NEED_SCHEDULE) {
1600             return;
1601         }
1602 
1603         if unlikely(curr.sched_info().policy() == SchedPolicy::IDLE)
1604             && likely(pcb.sched_info().policy() != SchedPolicy::IDLE)
1605         {
1606             rq.resched_current();
1607             return;
1608         }
1609 
1610         if unlikely(pcb.sched_info().policy() != SchedPolicy::CFS)
1611             || !SCHED_FEATURES.contains(SchedFeature::WAKEUP_PREEMPTION)
1612         {
1613             return;
1614         }
1615 
1616         Self::find_matching_se(&mut se, &mut pse);
1617 
1618         let cse_is_idle = se.is_idle();
1619         let pse_is_idle = pse.is_idle();
1620 
1621         if cse_is_idle && !pse_is_idle {
1622             rq.resched_current();
1623             return;
1624         }
1625 
1626         if cse_is_idle != pse_is_idle {
1627             return;
1628         }
1629 
1630         let cfs_rq = se.cfs_rq();
1631         cfs_rq.force_mut().update_current();
1632 
1633         if let Some((_, pick_se)) = cfs_rq.entities.get_first() {
1634             if Arc::ptr_eq(pick_se, &pse) {
1635                 rq.resched_current();
1636                 return;
1637             }
1638         }
1639     }
1640 
1641     fn pick_task(rq: &mut CpuRunQueue) -> Option<Arc<crate::process::ProcessControlBlock>> {
1642         let mut cfs_rq = Some(rq.cfs_rq());
1643         if cfs_rq.as_ref().unwrap().nr_running == 0 {
1644             return None;
1645         }
1646 
1647         let mut se;
1648         loop {
1649             let cfs = cfs_rq.unwrap();
1650             let cfs = cfs.force_mut();
1651             let curr = cfs.current();
1652             if let Some(curr) = curr {
1653                 if curr.on_rq() {
1654                     cfs.update_current();
1655                 } else {
1656                     cfs.set_current(Weak::default());
1657                 }
1658             }
1659 
1660             se = cfs.pick_next_entity();
1661             match se.clone() {
1662                 Some(val) => cfs_rq = val.my_cfs_rq.clone(),
1663                 None => {
1664                     break;
1665                 }
1666             }
1667 
1668             if cfs_rq.is_none() {
1669                 break;
1670             }
1671         }
1672 
1673         se.map(|se| se.pcb())
1674     }
1675 
1676     fn tick(_rq: &mut CpuRunQueue, pcb: Arc<crate::process::ProcessControlBlock>, queued: bool) {
1677         let mut se = pcb.sched_info().sched_entity();
1678 
1679         FairSchedEntity::for_each_in_group(&mut se, |se| {
1680             let binding = se.clone();
1681             let binding = binding.cfs_rq();
1682             let cfs_rq = binding.force_mut();
1683 
1684             cfs_rq.entity_tick(se, queued);
1685             (true, true)
1686         });
1687     }
1688 
1689     fn task_fork(pcb: Arc<ProcessControlBlock>) {
1690         let rq = cpu_rq(smp_get_processor_id().data() as usize);
1691         let se = pcb.sched_info().sched_entity();
1692 
1693         let (rq, _guard) = rq.self_lock();
1694 
1695         rq.update_rq_clock();
1696 
1697         let binding = se.cfs_rq();
1698         let cfs_rq = binding.force_mut();
1699 
1700         if cfs_rq.current().is_some() {
1701             cfs_rq.update_current();
1702         }
1703 
1704         cfs_rq.place_entity(se.clone(), EnqueueFlag::ENQUEUE_INITIAL);
1705     }
1706 
1707     fn pick_next_task(
1708         rq: &mut CpuRunQueue,
1709         prev: Option<Arc<ProcessControlBlock>>,
1710     ) -> Option<Arc<ProcessControlBlock>> {
1711         let mut cfs_rq = rq.cfs_rq();
1712         if rq.nr_running == 0 {
1713             return None;
1714         }
1715 
1716         if prev.is_none()
1717             || (prev.is_some() && prev.as_ref().unwrap().sched_info().policy() != SchedPolicy::CFS)
1718         {
1719             if let Some(prev) = prev {
1720                 match prev.sched_info().policy() {
1721                     SchedPolicy::RT => todo!(),
1722                     SchedPolicy::FIFO => todo!(),
1723                     SchedPolicy::CFS => todo!(),
1724                     SchedPolicy::IDLE => IdleScheduler::put_prev_task(rq, prev),
1725                 }
1726             }
1727             let mut se;
1728             loop {
1729                 match cfs_rq.pick_next_entity() {
1730                     Some(s) => se = s,
1731                     None => return None,
1732                 }
1733 
1734                 cfs_rq.force_mut().set_next_entity(&se);
1735 
1736                 match &se.my_cfs_rq {
1737                     Some(q) => cfs_rq = q.clone(),
1738                     None => break,
1739                 }
1740             }
1741 
1742             return Some(se.pcb());
1743         }
1744 
1745         let prev = prev.unwrap();
1746         let se = cfs_rq.pick_next_entity();
1747 
1748         if let Some(mut se) = se {
1749             loop {
1750                 let curr = cfs_rq.current();
1751                 if let Some(current) = curr {
1752                     if current.on_rq() {
1753                         cfs_rq.force_mut().update_current()
1754                     } else {
1755                         cfs_rq.force_mut().set_current(Weak::default());
1756                     }
1757                 }
1758 
1759                 match cfs_rq.pick_next_entity() {
1760                     Some(e) => se = e,
1761                     None => break,
1762                 }
1763 
1764                 if let Some(q) = se.my_cfs_rq.clone() {
1765                     cfs_rq = q;
1766                 } else {
1767                     break;
1768                 }
1769             }
1770 
1771             let p = se.pcb();
1772 
1773             if !Arc::ptr_eq(&prev, &p) {
1774                 let mut pse = prev.sched_info().sched_entity();
1775 
1776                 while !(Arc::ptr_eq(&se.cfs_rq(), &pse.cfs_rq())
1777                     && Arc::ptr_eq(&se.cfs_rq(), &cfs_rq))
1778                 {
1779                     let se_depth = se.depth;
1780                     let pse_depth = pse.depth;
1781 
1782                     if se_depth <= pse_depth {
1783                         pse.cfs_rq().force_mut().put_prev_entity(pse.clone());
1784                         pse = pse.parent().unwrap();
1785                     }
1786 
1787                     if se_depth >= pse_depth {
1788                         se.cfs_rq().force_mut().set_next_entity(&se);
1789                         se = se.parent().unwrap();
1790                     }
1791                 }
1792 
1793                 cfs_rq.force_mut().put_prev_entity(pse);
1794                 cfs_rq.force_mut().set_next_entity(&se);
1795             }
1796 
1797             return Some(p);
1798         } else {
1799             return None;
1800         }
1801     }
1802 
1803     fn put_prev_task(_rq: &mut CpuRunQueue, prev: Arc<ProcessControlBlock>) {
1804         let mut se = prev.sched_info().sched_entity();
1805 
1806         FairSchedEntity::for_each_in_group(&mut se, |se| {
1807             let cfs = se.cfs_rq();
1808             cfs.force_mut().put_prev_entity(se);
1809 
1810             return (true, true);
1811         });
1812     }
1813 }
1814