1 use core::sync::atomic::{compiler_fence, AtomicUsize, Ordering};
2
3 use crate::{
4 arch::CurrentIrqArch, exception::InterruptArch, process::ProcessControlBlock,
5 smp::core::smp_get_processor_id, time::jiffies::TICK_NESC,
6 };
7 use alloc::sync::Arc;
8
9 use super::{clock::SchedClock, cpu_irq_time};
10
irq_time_read(cpu: usize) -> u6411 pub fn irq_time_read(cpu: usize) -> u64 {
12 compiler_fence(Ordering::SeqCst);
13 let irqtime = cpu_irq_time(cpu);
14
15 let mut total;
16
17 loop {
18 let seq = irqtime.sync.load(Ordering::SeqCst);
19 total = irqtime.total;
20
21 if seq == irqtime.sync.load(Ordering::SeqCst) {
22 break;
23 }
24 }
25 compiler_fence(Ordering::SeqCst);
26 total
27 }
28
29 #[derive(Debug, Default)]
30 pub struct IrqTime {
31 pub total: u64,
32 pub tick_delta: u64,
33 pub irq_start_time: u64,
34 pub sync: AtomicUsize,
35 }
36
37 impl IrqTime {
account_delta(&mut self, delta: u64)38 pub fn account_delta(&mut self, delta: u64) {
39 // 开始更改时增加序列号
40 self.sync.fetch_add(1, Ordering::SeqCst);
41 self.total += delta;
42 self.tick_delta += delta;
43 }
44
irqtime_tick_accounted(&mut self, max: u64) -> u6445 pub fn irqtime_tick_accounted(&mut self, max: u64) -> u64 {
46 let delta = self.tick_delta.min(max);
47 self.tick_delta -= delta;
48 return delta;
49 }
50
irqtime_start()51 pub fn irqtime_start() {
52 let cpu = smp_get_processor_id().data() as usize;
53 let irq_time = cpu_irq_time(cpu);
54 compiler_fence(Ordering::SeqCst);
55 irq_time.irq_start_time = SchedClock::sched_clock_cpu(cpu) as u64;
56 compiler_fence(Ordering::SeqCst);
57 }
58
irqtime_account_irq(_pcb: Arc<ProcessControlBlock>)59 pub fn irqtime_account_irq(_pcb: Arc<ProcessControlBlock>) {
60 compiler_fence(Ordering::SeqCst);
61 let cpu = smp_get_processor_id().data() as usize;
62 let irq_time = cpu_irq_time(cpu);
63 compiler_fence(Ordering::SeqCst);
64 let delta = SchedClock::sched_clock_cpu(cpu) as u64 - irq_time.irq_start_time;
65 compiler_fence(Ordering::SeqCst);
66
67 irq_time.account_delta(delta);
68 compiler_fence(Ordering::SeqCst);
69 }
70 }
71
72 pub struct CpuTimeFunc;
73 impl CpuTimeFunc {
irqtime_account_process_tick( _pcb: &Arc<ProcessControlBlock>, _user_tick: bool, ticks: u64, )74 pub fn irqtime_account_process_tick(
75 _pcb: &Arc<ProcessControlBlock>,
76 _user_tick: bool,
77 ticks: u64,
78 ) {
79 let cputime = TICK_NESC as u64 * ticks;
80
81 let other = Self::account_other_time(u64::MAX);
82
83 if other >= cputime {
84 return;
85 }
86
87 // TODO: update process time
88 }
89
account_other_time(max: u64) -> u6490 pub fn account_other_time(max: u64) -> u64 {
91 assert!(!CurrentIrqArch::is_irq_enabled());
92
93 let mut accounted = Self::steal_account_process_time(max);
94
95 if accounted < max {
96 let irqtime = cpu_irq_time(smp_get_processor_id().data() as usize);
97 accounted += irqtime.irqtime_tick_accounted(max - accounted);
98 }
99
100 accounted
101 }
102
steal_account_process_time(_max: u64) -> u64103 pub fn steal_account_process_time(_max: u64) -> u64 {
104 // 这里未考虑虚拟机时间窃取
105 0
106 }
107 }
108