1 use core::{ 2 fmt, 3 intrinsics::unlikely, 4 ops::{self, Sub}, 5 }; 6 7 use crate::arch::CurrentTimeArch; 8 9 use self::timekeep::ktime_get_real_ns; 10 11 pub mod clocksource; 12 pub mod jiffies; 13 pub mod sleep; 14 pub mod syscall; 15 pub mod timeconv; 16 pub mod timekeep; 17 pub mod timekeeping; 18 pub mod timer; 19 /* Time structures. (Partitially taken from smoltcp) 20 21 The `time` module contains structures used to represent both 22 absolute and relative time. 23 24 - [Instant] is used to represent absolute time. 25 - [Duration] is used to represent relative time. 26 27 [Instant]: struct.Instant.html 28 [Duration]: struct.Duration.html 29 */ 30 #[allow(dead_code)] 31 pub const MSEC_PER_SEC: u32 = 1000; 32 #[allow(dead_code)] 33 pub const USEC_PER_MSEC: u32 = 1000; 34 #[allow(dead_code)] 35 pub const NSEC_PER_USEC: u32 = 1000; 36 #[allow(dead_code)] 37 pub const NSEC_PER_MSEC: u32 = 1000000; 38 #[allow(dead_code)] 39 pub const USEC_PER_SEC: u32 = 1000000; 40 #[allow(dead_code)] 41 pub const NSEC_PER_SEC: u32 = 1000000000; 42 #[allow(dead_code)] 43 pub const FSEC_PER_SEC: u64 = 1000000000000000; 44 45 /// 表示时间的结构体,符合POSIX标准。 46 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 47 #[repr(C)] 48 pub struct TimeSpec { 49 pub tv_sec: i64, 50 pub tv_nsec: i64, 51 } 52 53 impl TimeSpec { 54 #[allow(dead_code)] 55 pub fn new(sec: i64, nsec: i64) -> TimeSpec { 56 return TimeSpec { 57 tv_sec: sec, 58 tv_nsec: nsec, 59 }; 60 } 61 62 /// 获取当前时间 63 pub fn now() -> Self { 64 #[cfg(target_arch = "x86_64")] 65 { 66 use crate::arch::driver::tsc::TSCManager; 67 let khz = TSCManager::cpu_khz(); 68 if unlikely(khz == 0) { 69 return TimeSpec::default(); 70 } else { 71 return Self::from(Duration::from_millis( 72 CurrentTimeArch::get_cycles() as u64 / khz, 73 )); 74 } 75 } 76 77 #[cfg(target_arch = "riscv64")] 78 { 79 unimplemented!("TimeSpec::now()") 80 } 81 } 82 } 83 84 impl Sub for TimeSpec { 85 type Output = Duration; 86 fn sub(self, rhs: Self) -> Self::Output { 87 let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0); 88 let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0); 89 Duration::from_micros((sec * 1000000 + nsec / 1000) as u64) 90 } 91 } 92 93 impl From<Duration> for TimeSpec { 94 fn from(dur: Duration) -> Self { 95 TimeSpec { 96 tv_sec: dur.total_micros() as i64 / 1000000, 97 tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000, 98 } 99 } 100 } 101 102 impl Into<Duration> for TimeSpec { 103 fn into(self) -> Duration { 104 Duration::from_micros(self.tv_sec as u64 * 1000000 + self.tv_nsec as u64 / 1000) 105 } 106 } 107 108 /// A representation of an absolute time value. 109 /// 110 /// The `Instant` type is a wrapper around a `i64` value that 111 /// represents a number of microseconds, monotonically increasing 112 /// since an arbitrary moment in time, such as system startup. 113 /// 114 /// * A value of `0` is inherently arbitrary. 115 /// * A value less than `0` indicates a time before the starting 116 /// point. 117 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 118 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 119 pub struct Instant { 120 micros: i64, 121 } 122 123 #[allow(dead_code)] 124 impl Instant { 125 pub const ZERO: Instant = Instant::from_micros_const(0); 126 127 /// Create a new `Instant` from a number of microseconds. 128 pub fn from_micros<T: Into<i64>>(micros: T) -> Instant { 129 Instant { 130 micros: micros.into(), 131 } 132 } 133 134 pub const fn from_micros_const(micros: i64) -> Instant { 135 Instant { micros } 136 } 137 138 /// Create a new `Instant` from a number of milliseconds. 139 pub fn from_millis<T: Into<i64>>(millis: T) -> Instant { 140 Instant { 141 micros: millis.into() * 1000, 142 } 143 } 144 145 /// Create a new `Instant` from a number of milliseconds. 146 pub const fn from_millis_const(millis: i64) -> Instant { 147 Instant { 148 micros: millis * 1000, 149 } 150 } 151 152 /// Create a new `Instant` from a number of seconds. 153 pub fn from_secs<T: Into<i64>>(secs: T) -> Instant { 154 Instant { 155 micros: secs.into() * 1000000, 156 } 157 } 158 159 /// Create a new `Instant` from the current time 160 pub fn now() -> Instant { 161 Self::from_micros(ktime_get_real_ns() / 1000) 162 } 163 164 /// The fractional number of milliseconds that have passed 165 /// since the beginning of time. 166 pub const fn millis(&self) -> i64 { 167 self.micros % 1000000 / 1000 168 } 169 170 /// The fractional number of microseconds that have passed 171 /// since the beginning of time. 172 pub const fn micros(&self) -> i64 { 173 self.micros % 1000000 174 } 175 176 /// The number of whole seconds that have passed since the 177 /// beginning of time. 178 pub const fn secs(&self) -> i64 { 179 self.micros / 1000000 180 } 181 182 /// The total number of milliseconds that have passed since 183 /// the beginning of time. 184 pub const fn total_millis(&self) -> i64 { 185 self.micros / 1000 186 } 187 /// The total number of milliseconds that have passed since 188 /// the beginning of time. 189 pub const fn total_micros(&self) -> i64 { 190 self.micros 191 } 192 } 193 194 impl fmt::Display for Instant { 195 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 196 write!(f, "{}.{:0>3}s", self.secs(), self.millis()) 197 } 198 } 199 200 impl ops::Add<Duration> for Instant { 201 type Output = Instant; 202 203 fn add(self, rhs: Duration) -> Instant { 204 Instant::from_micros(self.micros + rhs.total_micros() as i64) 205 } 206 } 207 208 impl ops::AddAssign<Duration> for Instant { 209 fn add_assign(&mut self, rhs: Duration) { 210 self.micros += rhs.total_micros() as i64; 211 } 212 } 213 214 impl ops::Sub<Duration> for Instant { 215 type Output = Instant; 216 217 fn sub(self, rhs: Duration) -> Instant { 218 Instant::from_micros(self.micros - rhs.total_micros() as i64) 219 } 220 } 221 222 impl ops::SubAssign<Duration> for Instant { 223 fn sub_assign(&mut self, rhs: Duration) { 224 self.micros -= rhs.total_micros() as i64; 225 } 226 } 227 228 impl ops::Sub<Instant> for Instant { 229 type Output = Duration; 230 231 fn sub(self, rhs: Instant) -> Duration { 232 Duration::from_micros((self.micros - rhs.micros).unsigned_abs()) 233 } 234 } 235 236 /// A relative amount of time. 237 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 238 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 239 pub struct Duration { 240 micros: u64, 241 } 242 243 impl Duration { 244 pub const ZERO: Duration = Duration::from_micros(0); 245 /// Create a new `Duration` from a number of microseconds. 246 pub const fn from_micros(micros: u64) -> Duration { 247 Duration { micros } 248 } 249 250 /// Create a new `Duration` from a number of milliseconds. 251 pub const fn from_millis(millis: u64) -> Duration { 252 Duration { 253 micros: millis * 1000, 254 } 255 } 256 257 /// Create a new `Instant` from a number of seconds. 258 pub const fn from_secs(secs: u64) -> Duration { 259 Duration { 260 micros: secs * 1000000, 261 } 262 } 263 264 /// The fractional number of milliseconds in this `Duration`. 265 pub const fn millis(&self) -> u64 { 266 self.micros / 1000 % 1000 267 } 268 269 /// The fractional number of milliseconds in this `Duration`. 270 pub const fn micros(&self) -> u64 { 271 self.micros % 1000000 272 } 273 274 /// The number of whole seconds in this `Duration`. 275 pub const fn secs(&self) -> u64 { 276 self.micros / 1000000 277 } 278 279 /// The total number of milliseconds in this `Duration`. 280 pub const fn total_millis(&self) -> u64 { 281 self.micros / 1000 282 } 283 284 /// The total number of microseconds in this `Duration`. 285 pub const fn total_micros(&self) -> u64 { 286 self.micros 287 } 288 } 289 290 impl fmt::Display for Duration { 291 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 292 write!(f, "{}.{:03}s", self.secs(), self.millis()) 293 } 294 } 295 296 impl ops::Add<Duration> for Duration { 297 type Output = Duration; 298 299 fn add(self, rhs: Duration) -> Duration { 300 Duration::from_micros(self.micros + rhs.total_micros()) 301 } 302 } 303 304 impl ops::AddAssign<Duration> for Duration { 305 fn add_assign(&mut self, rhs: Duration) { 306 self.micros += rhs.total_micros(); 307 } 308 } 309 310 impl ops::Sub<Duration> for Duration { 311 type Output = Duration; 312 313 fn sub(self, rhs: Duration) -> Duration { 314 Duration::from_micros( 315 self.micros 316 .checked_sub(rhs.total_micros()) 317 .expect("overflow when subtracting durations"), 318 ) 319 } 320 } 321 322 impl ops::SubAssign<Duration> for Duration { 323 fn sub_assign(&mut self, rhs: Duration) { 324 self.micros = self 325 .micros 326 .checked_sub(rhs.total_micros()) 327 .expect("overflow when subtracting durations"); 328 } 329 } 330 331 impl ops::Mul<u32> for Duration { 332 type Output = Duration; 333 334 fn mul(self, rhs: u32) -> Duration { 335 Duration::from_micros(self.micros * rhs as u64) 336 } 337 } 338 339 impl ops::MulAssign<u32> for Duration { 340 fn mul_assign(&mut self, rhs: u32) { 341 self.micros *= rhs as u64; 342 } 343 } 344 345 impl ops::Div<u32> for Duration { 346 type Output = Duration; 347 348 fn div(self, rhs: u32) -> Duration { 349 Duration::from_micros(self.micros / rhs as u64) 350 } 351 } 352 353 impl ops::DivAssign<u32> for Duration { 354 fn div_assign(&mut self, rhs: u32) { 355 self.micros /= rhs as u64; 356 } 357 } 358 359 impl ops::Shl<u32> for Duration { 360 type Output = Duration; 361 362 fn shl(self, rhs: u32) -> Duration { 363 Duration::from_micros(self.micros << rhs) 364 } 365 } 366 367 impl ops::ShlAssign<u32> for Duration { 368 fn shl_assign(&mut self, rhs: u32) { 369 self.micros <<= rhs; 370 } 371 } 372 373 impl ops::Shr<u32> for Duration { 374 type Output = Duration; 375 376 fn shr(self, rhs: u32) -> Duration { 377 Duration::from_micros(self.micros >> rhs) 378 } 379 } 380 381 impl ops::ShrAssign<u32> for Duration { 382 fn shr_assign(&mut self, rhs: u32) { 383 self.micros >>= rhs; 384 } 385 } 386 387 impl From<::core::time::Duration> for Duration { 388 fn from(other: ::core::time::Duration) -> Duration { 389 Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64) 390 } 391 } 392 393 impl From<Duration> for ::core::time::Duration { 394 fn from(val: Duration) -> Self { 395 ::core::time::Duration::from_micros(val.total_micros()) 396 } 397 } 398 399 /// 支持与smoltcp的时间转换 400 impl From<smoltcp::time::Instant> for Instant { 401 fn from(val: smoltcp::time::Instant) -> Self { 402 Instant::from_micros(val.micros()) 403 } 404 } 405 406 impl Into<smoltcp::time::Instant> for Instant { 407 fn into(self) -> smoltcp::time::Instant { 408 smoltcp::time::Instant::from_millis(self.millis()) 409 } 410 } 411 412 /// 支持与smoltcp的时间转换 413 impl From<smoltcp::time::Duration> for Duration { 414 fn from(val: smoltcp::time::Duration) -> Self { 415 Duration::from_micros(val.micros()) 416 } 417 } 418 419 impl Into<smoltcp::time::Duration> for Duration { 420 fn into(self) -> smoltcp::time::Duration { 421 smoltcp::time::Duration::from_millis(self.millis()) 422 } 423 } 424 425 pub trait TimeArch { 426 /// Get CPU cycles (Read from register) 427 fn get_cycles() -> usize; 428 } 429