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