136fd0130Shoumkh use core::{
236fd0130Shoumkh fmt::Debug,
336fd0130Shoumkh intrinsics::unlikely,
436fd0130Shoumkh sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering},
5fbd63a30SSMALLC time::Duration,
636fd0130Shoumkh };
7bacd691cSlogin
8bacd691cSlogin use alloc::{
9bacd691cSlogin boxed::Box,
10bacd691cSlogin sync::{Arc, Weak},
11b8ed3825SDonkey Kane vec::Vec,
12bacd691cSlogin };
132eab6dd7S曾俊 use log::{error, info, warn};
1491e9d4abSLoGin use system_error::SystemError;
15bacd691cSlogin
16bacd691cSlogin use crate::{
17f0c87a89SGnoCiYeH arch::CurrentIrqArch,
1836fd0130Shoumkh exception::{
1936fd0130Shoumkh softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
2036fd0130Shoumkh InterruptArch,
21bacd691cSlogin },
220d6cf65aSLoGin libs::spinlock::{SpinLock, SpinLockGuard},
231496ba7bSLoGin process::{ProcessControlBlock, ProcessManager},
24f0c87a89SGnoCiYeH sched::{schedule, SchedMode},
25bacd691cSlogin };
26bacd691cSlogin
27b8ed3825SDonkey Kane use super::{jiffies::NSEC_PER_JIFFY, timekeeping::update_wall_time};
2836fd0130Shoumkh
29bacd691cSlogin const MAX_TIMEOUT: i64 = i64::MAX;
30bacd691cSlogin const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
3136fd0130Shoumkh static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0);
32bacd691cSlogin
33bacd691cSlogin lazy_static! {
34b8ed3825SDonkey Kane pub static ref TIMER_LIST: SpinLock<Vec<(u64, Arc<Timer>)>> = SpinLock::new(Vec::new());
35bacd691cSlogin }
36bacd691cSlogin
37bacd691cSlogin /// 定时器要执行的函数的特征
3836fd0130Shoumkh pub trait TimerFunction: Send + Sync + Debug {
run(&mut self) -> Result<(), SystemError>3936fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError>;
40bacd691cSlogin }
41fbd63a30SSMALLC // # Jiffies结构体(注意这是一段时间的jiffies数而不是某一时刻的定时器时间片)
42fbd63a30SSMALLC
43fbd63a30SSMALLC int_like!(Jiffies, u64);
44fbd63a30SSMALLC
45fbd63a30SSMALLC impl Jiffies {
46fbd63a30SSMALLC /// ## 返回接下来的n_jiffies对应的定时器时间片
timer_jiffies(&self) -> u6447fbd63a30SSMALLC pub fn timer_jiffies(&self) -> u64 {
48fbd63a30SSMALLC let result = TIMER_JIFFIES.load(Ordering::SeqCst) + self.data();
49fbd63a30SSMALLC result
50fbd63a30SSMALLC }
51fbd63a30SSMALLC }
52fbd63a30SSMALLC
53fbd63a30SSMALLC impl From<Jiffies> for Duration {
54fbd63a30SSMALLC /// # Jiffies转Duration
55fbd63a30SSMALLC ///
56fbd63a30SSMALLC /// ## 参数
57fbd63a30SSMALLC ///
58fbd63a30SSMALLC /// jiffies: 一段时间的jiffies数
59fbd63a30SSMALLC ///
60fbd63a30SSMALLC /// ### 返回值
61fbd63a30SSMALLC ///
62fbd63a30SSMALLC /// Duration: 这段时间的Duration形式
from(jiffies: Jiffies) -> Self63fbd63a30SSMALLC fn from(jiffies: Jiffies) -> Self {
64fbd63a30SSMALLC let ms = jiffies.data() / 1_000_000 * NSEC_PER_JIFFY as u64;
65fbd63a30SSMALLC let result = Duration::from_millis(ms);
66fbd63a30SSMALLC result
67fbd63a30SSMALLC }
68fbd63a30SSMALLC }
69fbd63a30SSMALLC
70fbd63a30SSMALLC impl From<Duration> for Jiffies {
71fbd63a30SSMALLC /// # Duration 转 Jiffies
72fbd63a30SSMALLC ///
73fbd63a30SSMALLC /// ## 参数
74fbd63a30SSMALLC ///
75fbd63a30SSMALLC /// ms: 表示一段时间的Duration类型
76fbd63a30SSMALLC ///
77fbd63a30SSMALLC /// ### 返回值
78fbd63a30SSMALLC ///
79fbd63a30SSMALLC /// Jiffies结构体: 这段时间的Jiffies数
from(ms: Duration) -> Self80fbd63a30SSMALLC fn from(ms: Duration) -> Self {
81fbd63a30SSMALLC let jiffies = ms.as_millis() as u64 * 1_000_000 / NSEC_PER_JIFFY as u64;
82fbd63a30SSMALLC let result = Jiffies::new(jiffies);
83fbd63a30SSMALLC result
84fbd63a30SSMALLC }
85fbd63a30SSMALLC }
86bacd691cSlogin
8736fd0130Shoumkh #[derive(Debug)]
88bacd691cSlogin /// WakeUpHelper函数对应的结构体
89bacd691cSlogin pub struct WakeUpHelper {
901496ba7bSLoGin pcb: Arc<ProcessControlBlock>,
91bacd691cSlogin }
92bacd691cSlogin
93bacd691cSlogin impl WakeUpHelper {
new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper>941496ba7bSLoGin pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> {
95bacd691cSlogin return Box::new(WakeUpHelper { pcb });
96bacd691cSlogin }
97bacd691cSlogin }
98bacd691cSlogin
99bacd691cSlogin impl TimerFunction for WakeUpHelper {
run(&mut self) -> Result<(), SystemError>10036fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> {
1011496ba7bSLoGin ProcessManager::wakeup(&self.pcb).ok();
10236fd0130Shoumkh return Ok(());
103bacd691cSlogin }
104bacd691cSlogin }
105bacd691cSlogin
10636fd0130Shoumkh #[derive(Debug)]
1070d6cf65aSLoGin pub struct Timer {
1080d6cf65aSLoGin inner: SpinLock<InnerTimer>,
1090d6cf65aSLoGin }
110bacd691cSlogin
111bacd691cSlogin impl Timer {
112bacd691cSlogin /// @brief 创建一个定时器(单位:ms)
113bacd691cSlogin ///
114bacd691cSlogin /// @param timer_func 定时器需要执行的函数对应的结构体
115bacd691cSlogin ///
116bacd691cSlogin /// @param expire_jiffies 定时器结束时刻
117bacd691cSlogin ///
118bacd691cSlogin /// @return 定时器结构体
new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self>119bacd691cSlogin pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
1200d6cf65aSLoGin let result: Arc<Timer> = Arc::new(Timer {
1210d6cf65aSLoGin inner: SpinLock::new(InnerTimer {
122bacd691cSlogin expire_jiffies,
1230d6cf65aSLoGin timer_func: Some(timer_func),
124bacd691cSlogin self_ref: Weak::default(),
125971462beSGnoCiYeH triggered: false,
1260d6cf65aSLoGin }),
1270d6cf65aSLoGin });
128bacd691cSlogin
1290d6cf65aSLoGin result.inner.lock().self_ref = Arc::downgrade(&result);
130bacd691cSlogin
131bacd691cSlogin return result;
132bacd691cSlogin }
133bacd691cSlogin
inner(&self) -> SpinLockGuard<InnerTimer>1340d6cf65aSLoGin pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
1350d6cf65aSLoGin return self.inner.lock_irqsave();
1360d6cf65aSLoGin }
1370d6cf65aSLoGin
138bacd691cSlogin /// @brief 将定时器插入到定时器链表中
activate(&self)139bacd691cSlogin pub fn activate(&self) {
1400d6cf65aSLoGin let mut timer_list = TIMER_LIST.lock_irqsave();
1410d6cf65aSLoGin let inner_guard = self.inner();
142cde5492fSlogin
143bacd691cSlogin // 链表为空,则直接插入
144bacd691cSlogin if timer_list.is_empty() {
145bacd691cSlogin // FIXME push_timer
146b8ed3825SDonkey Kane timer_list.push((
147b8ed3825SDonkey Kane inner_guard.expire_jiffies,
148b8ed3825SDonkey Kane inner_guard.self_ref.upgrade().unwrap(),
149b8ed3825SDonkey Kane ));
150cde5492fSlogin
151cde5492fSlogin drop(inner_guard);
152cde5492fSlogin drop(timer_list);
153cde5492fSlogin compiler_fence(Ordering::SeqCst);
154cde5492fSlogin
155bacd691cSlogin return;
156bacd691cSlogin }
157b8ed3825SDonkey Kane let expire_jiffies = inner_guard.expire_jiffies;
158b8ed3825SDonkey Kane let self_arc = inner_guard.self_ref.upgrade().unwrap();
159b8ed3825SDonkey Kane drop(inner_guard);
160bacd691cSlogin let mut split_pos: usize = 0;
161bacd691cSlogin for (pos, elt) in timer_list.iter().enumerate() {
162b8ed3825SDonkey Kane if Arc::ptr_eq(&self_arc, &elt.1) {
1632eab6dd7S曾俊 warn!("Timer already in list");
164b8ed3825SDonkey Kane }
165b8ed3825SDonkey Kane if elt.0 > expire_jiffies {
166bacd691cSlogin split_pos = pos;
167bacd691cSlogin break;
168bacd691cSlogin }
169bacd691cSlogin }
170b8ed3825SDonkey Kane timer_list.insert(split_pos, (expire_jiffies, self_arc));
171b8ed3825SDonkey Kane
172cde5492fSlogin drop(timer_list);
173bacd691cSlogin }
174bacd691cSlogin
175bacd691cSlogin #[inline]
run(&self)176bacd691cSlogin fn run(&self) {
1770d6cf65aSLoGin let mut timer = self.inner();
178971462beSGnoCiYeH timer.triggered = true;
1790d6cf65aSLoGin let func = timer.timer_func.take();
1800d6cf65aSLoGin drop(timer);
1810d6cf65aSLoGin let r = func.map(|mut f| f.run()).unwrap_or(Ok(()));
18236fd0130Shoumkh if unlikely(r.is_err()) {
1832eab6dd7S曾俊 error!(
18436fd0130Shoumkh "Failed to run timer function: {self:?} {:?}",
1858d72b68dSJomo r.as_ref().err().unwrap()
18636fd0130Shoumkh );
18736fd0130Shoumkh }
188bacd691cSlogin }
189971462beSGnoCiYeH
190971462beSGnoCiYeH /// ## 判断定时器是否已经触发
timeout(&self) -> bool191971462beSGnoCiYeH pub fn timeout(&self) -> bool {
1920d6cf65aSLoGin self.inner().triggered
193971462beSGnoCiYeH }
194971462beSGnoCiYeH
195971462beSGnoCiYeH /// ## 取消定时器任务
cancel(&self) -> bool196971462beSGnoCiYeH pub fn cancel(&self) -> bool {
1970d6cf65aSLoGin let this_arc = self.inner().self_ref.upgrade().unwrap();
198971462beSGnoCiYeH TIMER_LIST
1990d6cf65aSLoGin .lock_irqsave()
200b8ed3825SDonkey Kane .extract_if(|x| Arc::ptr_eq(&this_arc, &x.1))
201840045afSLoGin .for_each(drop);
202971462beSGnoCiYeH true
203971462beSGnoCiYeH }
204bacd691cSlogin }
205bacd691cSlogin
206bacd691cSlogin /// 定时器类型
20736fd0130Shoumkh #[derive(Debug)]
208bacd691cSlogin pub struct InnerTimer {
209bacd691cSlogin /// 定时器结束时刻
210bacd691cSlogin pub expire_jiffies: u64,
211bacd691cSlogin /// 定时器需要执行的函数结构体
2120d6cf65aSLoGin pub timer_func: Option<Box<dyn TimerFunction>>,
213bacd691cSlogin /// self_ref
214bacd691cSlogin self_ref: Weak<Timer>,
215971462beSGnoCiYeH /// 判断该计时器是否触发
216971462beSGnoCiYeH triggered: bool,
217bacd691cSlogin }
218bacd691cSlogin
219bacd691cSlogin #[derive(Debug)]
220bacd691cSlogin pub struct DoTimerSoftirq {
221bacd691cSlogin running: AtomicBool,
222bacd691cSlogin }
223bacd691cSlogin
224bacd691cSlogin impl DoTimerSoftirq {
new() -> Self225bacd691cSlogin pub fn new() -> Self {
226bacd691cSlogin return DoTimerSoftirq {
227bacd691cSlogin running: AtomicBool::new(false),
228bacd691cSlogin };
229bacd691cSlogin }
230bacd691cSlogin
set_run(&self) -> bool231bacd691cSlogin fn set_run(&self) -> bool {
232bacd691cSlogin let x = self
233bacd691cSlogin .running
234bacd691cSlogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
235840045afSLoGin return x.is_ok();
236bacd691cSlogin }
237bacd691cSlogin
clear_run(&self)238bacd691cSlogin fn clear_run(&self) {
239bacd691cSlogin self.running.store(false, Ordering::Release);
240bacd691cSlogin }
241bacd691cSlogin }
242bacd691cSlogin impl SoftirqVec for DoTimerSoftirq {
run(&self)243bacd691cSlogin fn run(&self) {
244840045afSLoGin if !self.set_run() {
245bacd691cSlogin return;
246bacd691cSlogin }
247bacd691cSlogin // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
248bacd691cSlogin for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
2492eab6dd7S曾俊 // debug!("DoTimerSoftirq run");
2500d6cf65aSLoGin let timer_list = TIMER_LIST.try_lock_irqsave();
251cde5492fSlogin if timer_list.is_err() {
252cde5492fSlogin continue;
253cde5492fSlogin }
254cde5492fSlogin let mut timer_list = timer_list.unwrap();
255bacd691cSlogin
256bacd691cSlogin if timer_list.is_empty() {
257bacd691cSlogin break;
258bacd691cSlogin }
259bacd691cSlogin
260b8ed3825SDonkey Kane let (front_jiffies, timer_list_front) = timer_list.first().unwrap().clone();
2612eab6dd7S曾俊 // debug!("to lock timer_list_front");
262b8ed3825SDonkey Kane
263b8ed3825SDonkey Kane if front_jiffies >= TIMER_JIFFIES.load(Ordering::SeqCst) {
264cde5492fSlogin break;
265cde5492fSlogin }
266b8ed3825SDonkey Kane timer_list.remove(0);
267cde5492fSlogin drop(timer_list);
268cde5492fSlogin timer_list_front.run();
269bacd691cSlogin }
270bacd691cSlogin
271bacd691cSlogin self.clear_run();
272bacd691cSlogin }
273bacd691cSlogin }
274bacd691cSlogin
2755b59005fSLoGin /// 初始化系统定时器
2765b59005fSLoGin #[inline(never)]
timer_init()277bacd691cSlogin pub fn timer_init() {
278bacd691cSlogin // FIXME 调用register_trap
279bacd691cSlogin let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
280bacd691cSlogin softirq_vectors()
281bacd691cSlogin .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
282bacd691cSlogin .expect("Failed to register timer softirq");
2832eab6dd7S曾俊 info!("timer initialized successfully");
284bacd691cSlogin }
285bacd691cSlogin
286bacd691cSlogin /// 计算接下来n毫秒对应的定时器时间片
next_n_ms_timer_jiffies(expire_ms: u64) -> u64287bacd691cSlogin pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
288b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_ms * 1000000 / NSEC_PER_JIFFY as u64;
289bacd691cSlogin }
290bacd691cSlogin /// 计算接下来n微秒对应的定时器时间片
next_n_us_timer_jiffies(expire_us: u64) -> u64291bacd691cSlogin pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
292b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_us * 1000 / NSEC_PER_JIFFY as u64;
293bacd691cSlogin }
294bacd691cSlogin
295bacd691cSlogin /// @brief 让pcb休眠timeout个jiffies
296bacd691cSlogin ///
297bacd691cSlogin /// @param timeout 需要休眠的时间(单位:jiffies)
298bacd691cSlogin ///
299bacd691cSlogin /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
300bacd691cSlogin ///
301bacd691cSlogin /// @return Err(SystemError) 错误码
schedule_timeout(mut timeout: i64) -> Result<i64, SystemError>302bacd691cSlogin pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
3032eab6dd7S曾俊 // debug!("schedule_timeout");
304bacd691cSlogin if timeout == MAX_TIMEOUT {
3058cb2e9b3SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
306be8cdf4bSLoGin ProcessManager::mark_sleep(true).ok();
3078cb2e9b3SLoGin drop(irq_guard);
3083959e94dS曾俊 schedule(SchedMode::SM_NONE);
309bacd691cSlogin return Ok(MAX_TIMEOUT);
310bacd691cSlogin } else if timeout < 0 {
3112eab6dd7S曾俊 error!("timeout can't less than 0");
312bacd691cSlogin return Err(SystemError::EINVAL);
313bacd691cSlogin } else {
314bacd691cSlogin // 禁用中断,防止在这段期间发生调度,造成死锁
31536fd0130Shoumkh let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
31636fd0130Shoumkh
31736fd0130Shoumkh timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
3181496ba7bSLoGin let timer = Timer::new(
3191496ba7bSLoGin WakeUpHelper::new(ProcessManager::current_pcb()),
3201496ba7bSLoGin timeout as u64,
3211496ba7bSLoGin );
3221496ba7bSLoGin ProcessManager::mark_sleep(true).ok();
323bacd691cSlogin timer.activate();
32436fd0130Shoumkh
32536fd0130Shoumkh drop(irq_guard);
326bacd691cSlogin
3273959e94dS曾俊 schedule(SchedMode::SM_NONE);
32836fd0130Shoumkh let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
329bacd691cSlogin if time_remaining >= 0 {
330bacd691cSlogin // 被提前唤醒,返回剩余时间
331bacd691cSlogin return Ok(time_remaining);
332bacd691cSlogin } else {
333bacd691cSlogin return Ok(0);
334bacd691cSlogin }
335bacd691cSlogin }
336bacd691cSlogin }
337bacd691cSlogin
timer_get_first_expire() -> Result<u64, SystemError>338bacd691cSlogin pub fn timer_get_first_expire() -> Result<u64, SystemError> {
339bacd691cSlogin // FIXME
3402eab6dd7S曾俊 // debug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
341bacd691cSlogin for _ in 0..10 {
342be8cdf4bSLoGin match TIMER_LIST.try_lock_irqsave() {
343bacd691cSlogin Ok(timer_list) => {
3442eab6dd7S曾俊 // debug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
345bacd691cSlogin if timer_list.is_empty() {
3462eab6dd7S曾俊 // debug!("timer_list is empty");
347bacd691cSlogin return Ok(0);
348bacd691cSlogin } else {
3492eab6dd7S曾俊 // debug!("timer_list not empty");
350b8ed3825SDonkey Kane return Ok(timer_list.first().unwrap().0);
351bacd691cSlogin }
352bacd691cSlogin }
353bacd691cSlogin // 加锁失败返回啥??
354bacd691cSlogin Err(_) => continue,
355bacd691cSlogin }
356bacd691cSlogin }
35779a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
358bacd691cSlogin }
359bacd691cSlogin
3600722a06aSLoGin /// 检查是否需要触发定时器软中断,如果需要则触发
try_raise_timer_softirq()3610722a06aSLoGin pub fn try_raise_timer_softirq() {
3620722a06aSLoGin if let Ok(first_expire) = timer_get_first_expire() {
3630722a06aSLoGin if first_expire <= clock() {
3640722a06aSLoGin softirq_vectors().raise_softirq(SoftirqNumber::TIMER);
3650722a06aSLoGin }
3660722a06aSLoGin }
3670722a06aSLoGin }
3680722a06aSLoGin
369*af097f9fS黄铭涛 /// 处理本地定时器中断
run_local_timer()370*af097f9fS黄铭涛 pub fn run_local_timer() {
371*af097f9fS黄铭涛 assert!(!CurrentIrqArch::is_irq_enabled());
372*af097f9fS黄铭涛 try_raise_timer_softirq();
373*af097f9fS黄铭涛 }
374*af097f9fS黄铭涛
375be8cdf4bSLoGin /// 更新系统时间片
update_timer_jiffies(add_jiffies: u64) -> u64376*af097f9fS黄铭涛 pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
37736fd0130Shoumkh let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
37836fd0130Shoumkh compiler_fence(Ordering::SeqCst);
379*af097f9fS黄铭涛 update_wall_time();
38036fd0130Shoumkh
38136fd0130Shoumkh compiler_fence(Ordering::SeqCst);
38236fd0130Shoumkh return prev + add_jiffies;
383bacd691cSlogin }
38436fd0130Shoumkh
clock() -> u64385bacd691cSlogin pub fn clock() -> u64 {
38636fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst);
387bacd691cSlogin }
388bacd691cSlogin
389bacd691cSlogin // ====== 以下为给C提供的接口 ======
390bacd691cSlogin
391bacd691cSlogin #[no_mangle]
rs_timer_init()392bacd691cSlogin pub extern "C" fn rs_timer_init() {
393bacd691cSlogin timer_init();
394bacd691cSlogin }
395