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, timekeeping::getnstimeofday}; 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 20 /* Time structures. (Partitially taken from smoltcp) 21 22 The `time` module contains structures used to represent both 23 absolute and relative time. 24 25 - [Instant] is used to represent absolute time. 26 - [Duration] is used to represent relative time. 27 28 [Instant]: struct.Instant.html 29 [Duration]: struct.Duration.html 30 */ 31 #[allow(dead_code)] 32 pub const MSEC_PER_SEC: u32 = 1000; 33 #[allow(dead_code)] 34 pub const USEC_PER_MSEC: u32 = 1000; 35 #[allow(dead_code)] 36 pub const NSEC_PER_USEC: u32 = 1000; 37 #[allow(dead_code)] 38 pub const NSEC_PER_MSEC: u32 = 1000000; 39 #[allow(dead_code)] 40 pub const USEC_PER_SEC: u32 = 1000000; 41 #[allow(dead_code)] 42 pub const NSEC_PER_SEC: u32 = 1000000000; 43 #[allow(dead_code)] 44 pub const FSEC_PER_SEC: u64 = 1000000000000000; 45 46 /// 表示时间的结构体,符合POSIX标准。 47 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 48 #[repr(C)] 49 pub struct PosixTimeSpec { 50 pub tv_sec: i64, 51 pub tv_nsec: i64, 52 } 53 54 impl PosixTimeSpec { 55 #[allow(dead_code)] 56 pub fn new(sec: i64, nsec: i64) -> PosixTimeSpec { 57 return PosixTimeSpec { 58 tv_sec: sec, 59 tv_nsec: nsec, 60 }; 61 } 62 63 /// 获取当前时间 64 #[inline(always)] 65 pub fn now() -> Self { 66 getnstimeofday() 67 } 68 69 /// 获取当前CPU时间(使用CPU时钟周期计算,会存在回绕问题) 70 pub fn now_cpu_time() -> Self { 71 #[cfg(target_arch = "x86_64")] 72 { 73 use crate::arch::driver::tsc::TSCManager; 74 let khz = TSCManager::cpu_khz(); 75 if unlikely(khz == 0) { 76 return PosixTimeSpec::default(); 77 } else { 78 return Self::from(Duration::from_millis( 79 CurrentTimeArch::get_cycles() as u64 / khz, 80 )); 81 } 82 } 83 84 #[cfg(target_arch = "riscv64")] 85 { 86 return PosixTimeSpec::new(0, 0); 87 } 88 } 89 90 /// 换算成纳秒 91 pub fn total_nanos(&self) -> i64 { 92 self.tv_sec * 1000000000 + self.tv_nsec 93 } 94 } 95 96 impl Sub for PosixTimeSpec { 97 type Output = Duration; 98 fn sub(self, rhs: Self) -> Self::Output { 99 let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0); 100 let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0); 101 Duration::from_micros((sec * 1000000 + nsec / 1000) as u64) 102 } 103 } 104 105 impl From<Duration> for PosixTimeSpec { 106 fn from(dur: Duration) -> Self { 107 PosixTimeSpec { 108 tv_sec: dur.total_micros() as i64 / 1000000, 109 tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000, 110 } 111 } 112 } 113 114 impl From<PosixTimeSpec> for Duration { 115 fn from(val: PosixTimeSpec) -> Self { 116 Duration::from_micros(val.tv_sec as u64 * 1000000 + val.tv_nsec as u64 / 1000) 117 } 118 } 119 120 /// A representation of an absolute time value. 121 /// 122 /// The `Instant` type is a wrapper around a `i64` value that 123 /// represents a number of microseconds, monotonically increasing 124 /// since an arbitrary moment in time, such as system startup. 125 /// 126 /// * A value of `0` is inherently arbitrary. 127 /// * A value less than `0` indicates a time before the starting 128 /// point. 129 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 130 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 131 pub struct Instant { 132 micros: i64, 133 } 134 135 #[allow(dead_code)] 136 impl Instant { 137 pub const ZERO: Instant = Instant::from_micros_const(0); 138 139 /// mktime64 - 将日期转换为秒。 140 /// 141 /// ## 参数 142 /// 143 /// - year0: 要转换的年份 144 /// - mon0: 要转换的月份 145 /// - day: 要转换的天 146 /// - hour: 要转换的小时 147 /// - min: 要转换的分钟 148 /// - sec: 要转换的秒 149 /// 150 /// 将公历日期转换为1970-01-01 00:00:00以来的秒数。 151 /// 假设输入为正常的日期格式,即1980-12-31 23:59:59 => 年份=1980, 月=12, 日=31, 时=23, 分=59, 秒=59。 152 /// 153 /// [For the Julian calendar(俄罗斯在1917年之前使用,英国及其殖民地在大西洋1752年之前使用, 154 /// 其他地方在1582年之前使用,某些社区仍然在使用)省略-year/100+year/400项, 155 /// 并在结果上加10。] 156 /// 157 /// 这个算法最初由高斯(我认为是)发表。 158 /// 159 /// 要表示闰秒,可以通过将sec设为60(在ISO 8601允许)来调用此函数。 160 /// 闰秒与随后的秒一样处理,因为它们在UNIX时间中不存在。 161 /// 162 /// 支持将午夜作为当日末尾的24:00:00编码 - 即明天的午夜(在ISO 8601允许)。 163 /// 164 /// ## 返回 165 /// 166 /// 返回:给定输入日期自1970-01-01 00:00:00以来的秒数 167 pub fn mktime64(year0: u32, mon0: u32, day: u32, hour: u32, min: u32, sec: u32) -> Self { 168 let mut mon: i64 = mon0.into(); 169 let mut year: u64 = year0.into(); 170 let day: u64 = day.into(); 171 let hour: u64 = hour.into(); 172 let min: u64 = min.into(); 173 let sec: u64 = sec.into(); 174 175 mon -= 2; 176 /* 1..12 -> 11,12,1..10 */ 177 if mon <= 0 { 178 /* Puts Feb last since it has leap day */ 179 mon += 12; 180 year -= 1; 181 } 182 let mon = mon as u64; 183 184 let secs = ((((year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + year * 365 185 - 719499) 186 * 24 + hour) /* now have hours - midnight tomorrow handled here */ 187 * 60 + min)/* now have minutes */ 188 * 60 189 + sec; /* finally seconds */ 190 191 Self::from_secs(secs as i64) 192 } 193 194 /// Create a new `Instant` from a number of microseconds. 195 pub fn from_micros<T: Into<i64>>(micros: T) -> Instant { 196 Instant { 197 micros: micros.into(), 198 } 199 } 200 201 pub const fn from_micros_const(micros: i64) -> Instant { 202 Instant { micros } 203 } 204 205 /// Create a new `Instant` from a number of milliseconds. 206 pub fn from_millis<T: Into<i64>>(millis: T) -> Instant { 207 Instant { 208 micros: millis.into() * 1000, 209 } 210 } 211 212 /// Create a new `Instant` from a number of milliseconds. 213 pub const fn from_millis_const(millis: i64) -> Instant { 214 Instant { 215 micros: millis * 1000, 216 } 217 } 218 219 /// Create a new `Instant` from a number of seconds. 220 pub fn from_secs<T: Into<i64>>(secs: T) -> Instant { 221 Instant { 222 micros: secs.into() * 1000000, 223 } 224 } 225 226 /// Create a new `Instant` from the current time 227 pub fn now() -> Instant { 228 Self::from_micros(ktime_get_real_ns() / 1000) 229 } 230 231 /// The fractional number of milliseconds that have passed 232 /// since the beginning of time. 233 pub const fn millis(&self) -> i64 { 234 self.micros % 1000000 / 1000 235 } 236 237 /// The fractional number of microseconds that have passed 238 /// since the beginning of time. 239 pub const fn micros(&self) -> i64 { 240 self.micros % 1000000 241 } 242 243 /// The number of whole seconds that have passed since the 244 /// beginning of time. 245 pub const fn secs(&self) -> i64 { 246 self.micros / 1000000 247 } 248 249 /// The total number of milliseconds that have passed since 250 /// the beginning of time. 251 pub const fn total_millis(&self) -> i64 { 252 self.micros / 1000 253 } 254 /// The total number of milliseconds that have passed since 255 /// the beginning of time. 256 pub const fn total_micros(&self) -> i64 { 257 self.micros 258 } 259 } 260 261 impl fmt::Display for Instant { 262 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 263 write!(f, "{}.{:0>3}s", self.secs(), self.millis()) 264 } 265 } 266 267 impl ops::Add<Duration> for Instant { 268 type Output = Instant; 269 270 fn add(self, rhs: Duration) -> Instant { 271 Instant::from_micros(self.micros + rhs.total_micros() as i64) 272 } 273 } 274 275 impl ops::AddAssign<Duration> for Instant { 276 fn add_assign(&mut self, rhs: Duration) { 277 self.micros += rhs.total_micros() as i64; 278 } 279 } 280 281 impl ops::Sub<Duration> for Instant { 282 type Output = Instant; 283 284 fn sub(self, rhs: Duration) -> Instant { 285 Instant::from_micros(self.micros - rhs.total_micros() as i64) 286 } 287 } 288 289 impl ops::SubAssign<Duration> for Instant { 290 fn sub_assign(&mut self, rhs: Duration) { 291 self.micros -= rhs.total_micros() as i64; 292 } 293 } 294 295 impl ops::Sub<Instant> for Instant { 296 type Output = Duration; 297 298 fn sub(self, rhs: Instant) -> Duration { 299 Duration::from_micros((self.micros - rhs.micros).unsigned_abs()) 300 } 301 } 302 303 /// A relative amount of time. 304 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 305 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 306 pub struct Duration { 307 micros: u64, 308 } 309 310 impl Duration { 311 pub const ZERO: Duration = Duration::from_micros(0); 312 /// Create a new `Duration` from a number of microseconds. 313 pub const fn from_micros(micros: u64) -> Duration { 314 Duration { micros } 315 } 316 317 /// Create a new `Duration` from a number of milliseconds. 318 pub const fn from_millis(millis: u64) -> Duration { 319 Duration { 320 micros: millis * 1000, 321 } 322 } 323 324 /// Create a new `Instant` from a number of seconds. 325 pub const fn from_secs(secs: u64) -> Duration { 326 Duration { 327 micros: secs * 1000000, 328 } 329 } 330 331 /// The fractional number of milliseconds in this `Duration`. 332 pub const fn millis(&self) -> u64 { 333 self.micros / 1000 % 1000 334 } 335 336 /// The fractional number of milliseconds in this `Duration`. 337 pub const fn micros(&self) -> u64 { 338 self.micros % 1000000 339 } 340 341 /// The number of whole seconds in this `Duration`. 342 pub const fn secs(&self) -> u64 { 343 self.micros / 1000000 344 } 345 346 /// The total number of milliseconds in this `Duration`. 347 pub const fn total_millis(&self) -> u64 { 348 self.micros / 1000 349 } 350 351 /// The total number of microseconds in this `Duration`. 352 pub const fn total_micros(&self) -> u64 { 353 self.micros 354 } 355 } 356 357 impl fmt::Display for Duration { 358 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 359 write!(f, "{}.{:03}s", self.secs(), self.millis()) 360 } 361 } 362 363 impl ops::Add<Duration> for Duration { 364 type Output = Duration; 365 366 fn add(self, rhs: Duration) -> Duration { 367 Duration::from_micros(self.micros + rhs.total_micros()) 368 } 369 } 370 371 impl ops::AddAssign<Duration> for Duration { 372 fn add_assign(&mut self, rhs: Duration) { 373 self.micros += rhs.total_micros(); 374 } 375 } 376 377 impl ops::Sub<Duration> for Duration { 378 type Output = Duration; 379 380 fn sub(self, rhs: Duration) -> Duration { 381 Duration::from_micros( 382 self.micros 383 .checked_sub(rhs.total_micros()) 384 .expect("overflow when subtracting durations"), 385 ) 386 } 387 } 388 389 impl ops::SubAssign<Duration> for Duration { 390 fn sub_assign(&mut self, rhs: Duration) { 391 self.micros = self 392 .micros 393 .checked_sub(rhs.total_micros()) 394 .expect("overflow when subtracting durations"); 395 } 396 } 397 398 impl ops::Mul<u32> for Duration { 399 type Output = Duration; 400 401 fn mul(self, rhs: u32) -> Duration { 402 Duration::from_micros(self.micros * rhs as u64) 403 } 404 } 405 406 impl ops::MulAssign<u32> for Duration { 407 fn mul_assign(&mut self, rhs: u32) { 408 self.micros *= rhs as u64; 409 } 410 } 411 412 impl ops::Div<u32> for Duration { 413 type Output = Duration; 414 415 fn div(self, rhs: u32) -> Duration { 416 Duration::from_micros(self.micros / rhs as u64) 417 } 418 } 419 420 impl ops::DivAssign<u32> for Duration { 421 fn div_assign(&mut self, rhs: u32) { 422 self.micros /= rhs as u64; 423 } 424 } 425 426 impl ops::Shl<u32> for Duration { 427 type Output = Duration; 428 429 fn shl(self, rhs: u32) -> Duration { 430 Duration::from_micros(self.micros << rhs) 431 } 432 } 433 434 impl ops::ShlAssign<u32> for Duration { 435 fn shl_assign(&mut self, rhs: u32) { 436 self.micros <<= rhs; 437 } 438 } 439 440 impl ops::Shr<u32> for Duration { 441 type Output = Duration; 442 443 fn shr(self, rhs: u32) -> Duration { 444 Duration::from_micros(self.micros >> rhs) 445 } 446 } 447 448 impl ops::ShrAssign<u32> for Duration { 449 fn shr_assign(&mut self, rhs: u32) { 450 self.micros >>= rhs; 451 } 452 } 453 454 impl From<::core::time::Duration> for Duration { 455 fn from(other: ::core::time::Duration) -> Duration { 456 Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64) 457 } 458 } 459 460 impl From<Duration> for ::core::time::Duration { 461 fn from(val: Duration) -> Self { 462 ::core::time::Duration::from_micros(val.total_micros()) 463 } 464 } 465 466 /// 支持与smoltcp的时间转换 467 impl From<smoltcp::time::Instant> for Instant { 468 fn from(val: smoltcp::time::Instant) -> Self { 469 Instant::from_micros(val.micros()) 470 } 471 } 472 473 impl From<Instant> for smoltcp::time::Instant { 474 fn from(val: Instant) -> Self { 475 smoltcp::time::Instant::from_millis(val.millis()) 476 } 477 } 478 479 /// 支持与smoltcp的时间转换 480 impl From<smoltcp::time::Duration> for Duration { 481 fn from(val: smoltcp::time::Duration) -> Self { 482 Duration::from_micros(val.micros()) 483 } 484 } 485 486 impl From<Duration> for smoltcp::time::Duration { 487 fn from(val: Duration) -> Self { 488 smoltcp::time::Duration::from_millis(val.millis()) 489 } 490 } 491 492 pub trait TimeArch { 493 /// Get CPU cycles (Read from register) 494 fn get_cycles() -> usize; 495 496 /// Calculate expire cycles 497 /// 498 /// # Arguments 499 /// 500 /// - `ns` - The time to expire in nanoseconds 501 /// 502 /// # Returns 503 /// 504 /// The expire cycles 505 fn cal_expire_cycles(ns: usize) -> usize; 506 507 /// 将CPU的时钟周期数转换为纳秒 508 fn cycles2ns(cycles: usize) -> usize; 509 } 510