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