• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::convert::TryInto;
15 use std::fmt::Error;
16 use std::ops::Deref;
17 use std::ptr::NonNull;
18 use std::sync::{Arc, Mutex};
19 use std::task::Waker;
20 use std::time::{Duration, Instant};
21 
22 use crate::time::wheel::{TimeOut, Wheel};
23 use crate::time::Clock;
24 
25 // Time Driver
26 pub(crate) struct TimeDriver {
27     start_time: Instant,
28     pub(crate) wheel: Mutex<Wheel>,
29 }
30 
31 pub(crate) struct TimeHandle {
32     inner: Arc<TimeDriver>,
33 }
34 
35 impl TimeDriver {
initialize() -> (TimeHandle, Arc<TimeDriver>)36     pub(crate) fn initialize() -> (TimeHandle, Arc<TimeDriver>) {
37         let driver = Arc::new(TimeDriver {
38             start_time: Instant::now(),
39             wheel: Mutex::new(Wheel::new()),
40         });
41         (
42             TimeHandle {
43                 inner: driver.clone(),
44             },
45             driver,
46         )
47     }
48 
start_time(&self) -> Instant49     pub(crate) fn start_time(&self) -> Instant {
50         self.start_time
51     }
52 
timer_register(&self, clock_entry: NonNull<Clock>) -> Result<u64, Error>53     pub(crate) fn timer_register(&self, clock_entry: NonNull<Clock>) -> Result<u64, Error> {
54         let mut lock = self.wheel.lock().unwrap();
55         lock.insert(clock_entry)
56     }
57 
timer_cancel(&self, clock_entry: NonNull<Clock>)58     pub(crate) fn timer_cancel(&self, clock_entry: NonNull<Clock>) {
59         let mut lock = self.wheel.lock().unwrap();
60         lock.cancel(clock_entry);
61     }
62 
handle_entry( &self, mut clock_entry: NonNull<Clock>, waker_list: &mut [Option<Waker>; 32], waker_idx: &mut usize, )63     fn handle_entry(
64         &self,
65         mut clock_entry: NonNull<Clock>,
66         waker_list: &mut [Option<Waker>; 32],
67         waker_idx: &mut usize,
68     ) {
69         // Unsafe access to timer_handle is only unsafe when Sleep Drop,
70         // but does not let `Sleep` go to `Ready` before access to timer_handle fetched
71         // by poll.
72         let clock_handle = unsafe { clock_entry.as_mut() };
73         waker_list[*waker_idx] = clock_handle.take_waker();
74         *waker_idx += 1;
75 
76         clock_handle.set_result(true);
77 
78         if *waker_idx == waker_list.len() {
79             for waker in waker_list.iter_mut() {
80                 waker
81                     .take()
82                     .expect("waker taken from the clock is none")
83                     .wake();
84             }
85             *waker_idx = 0;
86         }
87     }
88 
run(&self) -> Option<Duration>89     pub(crate) fn run(&self) -> Option<Duration> {
90         let now = Instant::now();
91         let now = now
92             .checked_duration_since(self.start_time())
93             .expect("driver's start time is later than the current time")
94             .as_millis()
95             .try_into()
96             .unwrap_or(u64::MAX);
97 
98         let mut waker_list: [Option<Waker>; 32] = Default::default();
99         let mut waker_idx = 0;
100         let mut is_wake = false;
101 
102         let mut lock = self.wheel.lock().unwrap();
103 
104         let mut timeout = None;
105 
106         loop {
107             match lock.poll(now) {
108                 TimeOut::ClockEntry(clock_entry) => {
109                     is_wake = true;
110                     self.handle_entry(clock_entry, &mut waker_list, &mut waker_idx);
111                 }
112                 TimeOut::Duration(duration) => {
113                     timeout = Some(duration);
114                     break;
115                 }
116                 TimeOut::None => break,
117             }
118         }
119 
120         drop(lock);
121         for waker in waker_list[0..waker_idx].iter_mut() {
122             waker
123                 .take()
124                 .expect("waker taken from the clock is none")
125                 .wake();
126         }
127         if is_wake {
128             timeout = Some(Duration::new(0, 0));
129         }
130         timeout
131     }
132 }
133 
134 impl Deref for TimeHandle {
135     type Target = Arc<TimeDriver>;
136 
deref(&self) -> &Self::Target137     fn deref(&self) -> &Self::Target {
138         &self.inner
139     }
140 }
141