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)] new(sec: i64, nsec: i64) -> PosixTimeSpec61 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)] now() -> Self70 pub fn now() -> Self { 71 getnstimeofday() 72 } 73 74 /// 获取当前CPU时间(使用CPU时钟周期计算,会存在回绕问题) now_cpu_time() -> Self75 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 /// 换算成纳秒 total_nanos(&self) -> i6496 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; sub(self, rhs: Self) -> Self::Output103 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 { from(dur: Duration) -> Self111 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 { from(value: PosixTimeval) -> Self120 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 { from(val: PosixTimeSpec) -> Self129 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 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以来的秒数 mktime64(year0: u32, mon0: u32, day: u32, hour: u32, min: u32, sec: u32) -> Self180 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. from_micros<T: Into<i64>>(micros: T) -> Instant208 pub fn from_micros<T: Into<i64>>(micros: T) -> Instant { 209 Instant { 210 micros: micros.into(), 211 } 212 } 213 from_micros_const(micros: i64) -> Instant214 pub const fn from_micros_const(micros: i64) -> Instant { 215 Instant { micros } 216 } 217 218 /// Create a new `Instant` from a number of milliseconds. from_millis<T: Into<i64>>(millis: T) -> Instant219 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. from_millis_const(millis: i64) -> Instant226 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. from_secs<T: Into<i64>>(secs: T) -> Instant233 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 now() -> Instant240 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. millis(&self) -> i64247 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. micros(&self) -> i64253 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. secs(&self) -> i64259 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. total_millis(&self) -> i64265 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. total_micros(&self) -> i64270 pub const fn total_micros(&self) -> i64 { 271 self.micros 272 } 273 } 274 275 impl fmt::Display for Instant { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result276 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 add(self, rhs: Duration) -> Instant284 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 { add_assign(&mut self, rhs: Duration)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 sub(self, rhs: Duration) -> Instant298 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 { sub_assign(&mut self, rhs: Duration)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 sub(self, rhs: Instant) -> Duration312 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 pub struct Duration { 320 micros: u64, 321 } 322 323 impl Duration { 324 pub const ZERO: Duration = Duration::from_micros(0); 325 /// Create a new `Duration` from a number of microseconds. from_micros(micros: u64) -> Duration326 pub const fn from_micros(micros: u64) -> Duration { 327 Duration { micros } 328 } 329 330 /// Create a new `Duration` from a number of milliseconds. from_millis(millis: u64) -> Duration331 pub const fn from_millis(millis: u64) -> Duration { 332 Duration { 333 micros: millis * 1000, 334 } 335 } 336 337 /// Create a new `Instant` from a number of seconds. from_secs(secs: u64) -> Duration338 pub const fn from_secs(secs: u64) -> Duration { 339 Duration { 340 micros: secs * 1000000, 341 } 342 } 343 344 /// The fractional number of milliseconds in this `Duration`. millis(&self) -> u64345 pub const fn millis(&self) -> u64 { 346 self.micros / 1000 % 1000 347 } 348 349 /// The fractional number of milliseconds in this `Duration`. micros(&self) -> u64350 pub const fn micros(&self) -> u64 { 351 self.micros % 1000000 352 } 353 354 /// The number of whole seconds in this `Duration`. secs(&self) -> u64355 pub const fn secs(&self) -> u64 { 356 self.micros / 1000000 357 } 358 359 /// The total number of milliseconds in this `Duration`. total_millis(&self) -> u64360 pub const fn total_millis(&self) -> u64 { 361 self.micros / 1000 362 } 363 364 /// The total number of microseconds in this `Duration`. total_micros(&self) -> u64365 pub const fn total_micros(&self) -> u64 { 366 self.micros 367 } 368 } 369 370 impl fmt::Display for Duration { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result371 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 372 write!(f, "{}.{:03}s", self.secs(), self.millis()) 373 } 374 } 375 376 impl ops::Add<Duration> for Duration { 377 type Output = Duration; 378 add(self, rhs: Duration) -> Duration379 fn add(self, rhs: Duration) -> Duration { 380 Duration::from_micros(self.micros + rhs.total_micros()) 381 } 382 } 383 384 impl ops::AddAssign<Duration> for Duration { add_assign(&mut self, rhs: Duration)385 fn add_assign(&mut self, rhs: Duration) { 386 self.micros += rhs.total_micros(); 387 } 388 } 389 390 impl ops::Sub<Duration> for Duration { 391 type Output = Duration; 392 sub(self, rhs: Duration) -> Duration393 fn sub(self, rhs: Duration) -> Duration { 394 Duration::from_micros( 395 self.micros 396 .checked_sub(rhs.total_micros()) 397 .expect("overflow when subtracting durations"), 398 ) 399 } 400 } 401 402 impl ops::SubAssign<Duration> for Duration { sub_assign(&mut self, rhs: Duration)403 fn sub_assign(&mut self, rhs: Duration) { 404 self.micros = self 405 .micros 406 .checked_sub(rhs.total_micros()) 407 .expect("overflow when subtracting durations"); 408 } 409 } 410 411 impl ops::Mul<u32> for Duration { 412 type Output = Duration; 413 mul(self, rhs: u32) -> Duration414 fn mul(self, rhs: u32) -> Duration { 415 Duration::from_micros(self.micros * rhs as u64) 416 } 417 } 418 419 impl ops::MulAssign<u32> for Duration { mul_assign(&mut self, rhs: u32)420 fn mul_assign(&mut self, rhs: u32) { 421 self.micros *= rhs as u64; 422 } 423 } 424 425 impl ops::Div<u32> for Duration { 426 type Output = Duration; 427 div(self, rhs: u32) -> Duration428 fn div(self, rhs: u32) -> Duration { 429 Duration::from_micros(self.micros / rhs as u64) 430 } 431 } 432 433 impl ops::DivAssign<u32> for Duration { div_assign(&mut self, rhs: u32)434 fn div_assign(&mut self, rhs: u32) { 435 self.micros /= rhs as u64; 436 } 437 } 438 439 impl ops::Shl<u32> for Duration { 440 type Output = Duration; 441 shl(self, rhs: u32) -> Duration442 fn shl(self, rhs: u32) -> Duration { 443 Duration::from_micros(self.micros << rhs) 444 } 445 } 446 447 impl ops::ShlAssign<u32> for Duration { shl_assign(&mut self, rhs: u32)448 fn shl_assign(&mut self, rhs: u32) { 449 self.micros <<= rhs; 450 } 451 } 452 453 impl ops::Shr<u32> for Duration { 454 type Output = Duration; 455 shr(self, rhs: u32) -> Duration456 fn shr(self, rhs: u32) -> Duration { 457 Duration::from_micros(self.micros >> rhs) 458 } 459 } 460 461 impl ops::ShrAssign<u32> for Duration { shr_assign(&mut self, rhs: u32)462 fn shr_assign(&mut self, rhs: u32) { 463 self.micros >>= rhs; 464 } 465 } 466 467 impl From<::core::time::Duration> for Duration { from(other: ::core::time::Duration) -> Duration468 fn from(other: ::core::time::Duration) -> Duration { 469 Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64) 470 } 471 } 472 473 impl From<Duration> for ::core::time::Duration { from(val: Duration) -> Self474 fn from(val: Duration) -> Self { 475 ::core::time::Duration::from_micros(val.total_micros()) 476 } 477 } 478 479 /// 支持与smoltcp的时间转换 480 impl From<smoltcp::time::Instant> for Instant { from(val: smoltcp::time::Instant) -> Self481 fn from(val: smoltcp::time::Instant) -> Self { 482 Instant::from_micros(val.micros()) 483 } 484 } 485 486 impl From<Instant> for smoltcp::time::Instant { from(val: Instant) -> Self487 fn from(val: Instant) -> Self { 488 smoltcp::time::Instant::from_millis(val.millis()) 489 } 490 } 491 492 /// 支持与smoltcp的时间转换 493 impl From<smoltcp::time::Duration> for Duration { from(val: smoltcp::time::Duration) -> Self494 fn from(val: smoltcp::time::Duration) -> Self { 495 Duration::from_micros(val.micros()) 496 } 497 } 498 499 impl From<Duration> for smoltcp::time::Duration { from(val: Duration) -> Self500 fn from(val: Duration) -> Self { 501 smoltcp::time::Duration::from_millis(val.millis()) 502 } 503 } 504 505 pub trait TimeArch { 506 /// Get CPU cycles (Read from register) get_cycles() -> usize507 fn get_cycles() -> usize; 508 509 /// Calculate expire cycles 510 /// 511 /// # Arguments 512 /// 513 /// - `ns` - The time to expire in nanoseconds 514 /// 515 /// # Returns 516 /// 517 /// The expire cycles cal_expire_cycles(ns: usize) -> usize518 fn cal_expire_cycles(ns: usize) -> usize; 519 520 /// 将CPU的时钟周期数转换为纳秒 cycles2ns(cycles: usize) -> usize521 fn cycles2ns(cycles: usize) -> usize; 522 } 523