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