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