• 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 //! Utilities for tracking time.
15 
16 mod driver;
17 mod error;
18 mod sleep;
19 mod timeout;
20 mod timer;
21 mod wheel;
22 
23 use std::ptr::{addr_of_mut, NonNull};
24 use std::sync::atomic::AtomicBool;
25 use std::sync::atomic::Ordering::Relaxed;
26 use std::task::Waker;
27 
28 pub(crate) use driver::TimeDriver;
29 #[cfg(not(feature = "ffrt"))]
30 pub(crate) use driver::TimeHandle;
31 pub use sleep::{sleep, sleep_until, Sleep};
32 pub use timeout::timeout;
33 pub use timer::{periodic_schedule, timer, timer_at, Timer};
34 
35 use crate::util::linked_list::{Link, Node};
36 
37 // Struct for timing and waking up corresponding tasks on the timing wheel.
38 pub(crate) struct Clock {
39     // Expected expiration time.
40     expiration: u64,
41 
42     // The level to which the clock will be inserted.
43     level: usize,
44 
45     // Elapsed time duration.
46     duration: u64,
47 
48     // The result obtained when the corresponding Sleep structure is woken up by
49     // which can be used to determine if the Future is completed correctly.
50     result: AtomicBool,
51 
52     // Corresponding waker,
53     // which is used to wake up sleep coroutine.
54     waker: Option<Waker>,
55 
56     // Linked_list node.
57     node: Node<Clock>,
58 }
59 
60 impl Clock {
61     // Creates a default Clock structure.
new() -> Self62     pub(crate) fn new() -> Self {
63         Self {
64             expiration: 0,
65             level: 0,
66             duration: 0,
67             result: AtomicBool::new(false),
68             waker: None,
69             node: Node::new(),
70         }
71     }
72 
73     // Returns the expected expiration time.
expiration(&self) -> u6474     pub(crate) fn expiration(&self) -> u64 {
75         self.expiration
76     }
77 
78     // Sets the expected expiration time
set_expiration(&mut self, expiration: u64)79     pub(crate) fn set_expiration(&mut self, expiration: u64) {
80         self.expiration = expiration;
81     }
82 
83     // Returns the level to which the clock will be inserted.
level(&self) -> usize84     pub(crate) fn level(&self) -> usize {
85         self.level
86     }
87 
88     // Sets the level to which the clock will be inserted.
set_level(&mut self, level: usize)89     pub(crate) fn set_level(&mut self, level: usize) {
90         self.level = level;
91     }
92 
duration(&self) -> u6493     pub(crate) fn duration(&self) -> u64 {
94         self.duration
95     }
96 
set_duration(&mut self, duration: u64)97     pub(crate) fn set_duration(&mut self, duration: u64) {
98         self.duration = duration;
99     }
100 
101     // Returns the corresponding waker.
take_waker(&mut self) -> Option<Waker>102     pub(crate) fn take_waker(&mut self) -> Option<Waker> {
103         self.waker.take()
104     }
105 
106     // Sets the corresponding waker.
set_waker(&mut self, waker: Waker)107     pub(crate) fn set_waker(&mut self, waker: Waker) {
108         self.waker = Some(waker);
109     }
110 
111     // Returns the result.
result(&self) -> bool112     pub(crate) fn result(&self) -> bool {
113         self.result.load(Relaxed)
114     }
115 
116     // Sets the result.
set_result(&mut self, result: bool)117     pub(crate) fn set_result(&mut self, result: bool) {
118         self.result.store(result, Relaxed);
119     }
120 }
121 
122 impl Default for Clock {
default() -> Self123     fn default() -> Self {
124         Clock::new()
125     }
126 }
127 
128 unsafe impl Link for Clock {
node(mut ptr: NonNull<Self>) -> NonNull<Node<Self>> where Self: Sized,129     unsafe fn node(mut ptr: NonNull<Self>) -> NonNull<Node<Self>>
130     where
131         Self: Sized,
132     {
133         let node_ptr = addr_of_mut!(ptr.as_mut().node);
134         NonNull::new_unchecked(node_ptr)
135     }
136 }
137