|
1 | 1 | use crate::fmt; |
2 | 2 | use crate::time::Duration; |
3 | 3 |
|
4 | | -pub use self::inner::Instant; |
5 | | - |
6 | 4 | const NSEC_PER_SEC: u64 = 1_000_000_000; |
7 | 5 | pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; |
8 | 6 | #[allow(dead_code)] // Used for pthread condvar timeouts |
@@ -249,162 +247,34 @@ impl From<__timespec64> for Timespec { |
249 | 247 | Timespec::new(t.tv_sec, t.tv_nsec.into()) |
250 | 248 | } |
251 | 249 | } |
| 250 | +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 251 | +pub struct Instant { |
| 252 | + t: Timespec, |
| 253 | +} |
252 | 254 |
|
253 | | -#[cfg(any( |
254 | | - all(target_os = "macos", not(target_arch = "aarch64")), |
255 | | - target_os = "ios", |
256 | | - target_os = "watchos", |
257 | | - target_os = "tvos" |
258 | | -))] |
259 | | -mod inner { |
260 | | - use crate::sync::atomic::{AtomicU64, Ordering}; |
261 | | - use crate::sys_common::mul_div_u64; |
262 | | - use crate::time::Duration; |
263 | | - |
264 | | - use super::{SystemTime, Timespec, NSEC_PER_SEC}; |
265 | | - |
266 | | - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] |
267 | | - pub struct Instant { |
268 | | - t: u64, |
269 | | - } |
270 | | - |
271 | | - #[repr(C)] |
272 | | - #[derive(Copy, Clone)] |
273 | | - struct mach_timebase_info { |
274 | | - numer: u32, |
275 | | - denom: u32, |
276 | | - } |
277 | | - type mach_timebase_info_t = *mut mach_timebase_info; |
278 | | - type kern_return_t = libc::c_int; |
279 | | - |
280 | | - impl Instant { |
281 | | - pub fn now() -> Instant { |
282 | | - extern "C" { |
283 | | - fn mach_absolute_time() -> u64; |
284 | | - } |
285 | | - Instant { t: unsafe { mach_absolute_time() } } |
286 | | - } |
287 | | - |
288 | | - pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { |
289 | | - let diff = self.t.checked_sub(other.t)?; |
290 | | - let info = info(); |
291 | | - let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64); |
292 | | - Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)) |
293 | | - } |
294 | | - |
295 | | - pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { |
296 | | - Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? }) |
297 | | - } |
298 | | - |
299 | | - pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { |
300 | | - Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? }) |
301 | | - } |
302 | | - } |
303 | | - |
304 | | - impl From<libc::timeval> for Timespec { |
305 | | - fn from(t: libc::timeval) -> Timespec { |
306 | | - Timespec::new(t.tv_sec as i64, 1000 * t.tv_usec as i64) |
307 | | - } |
308 | | - } |
309 | | - |
310 | | - impl From<libc::timeval> for SystemTime { |
311 | | - fn from(t: libc::timeval) -> SystemTime { |
312 | | - SystemTime { t: Timespec::from(t) } |
313 | | - } |
314 | | - } |
315 | | - |
316 | | - fn checked_dur2intervals(dur: &Duration) -> Option<u64> { |
317 | | - let nanos = |
318 | | - dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as u64)?; |
319 | | - let info = info(); |
320 | | - Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64)) |
| 255 | +impl Instant { |
| 256 | + pub fn now() -> Instant { |
| 257 | + Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) } |
321 | 258 | } |
322 | 259 |
|
323 | | - fn info() -> mach_timebase_info { |
324 | | - // INFO_BITS conceptually is an `Option<mach_timebase_info>`. We can do |
325 | | - // this in 64 bits because we know 0 is never a valid value for the |
326 | | - // `denom` field. |
327 | | - // |
328 | | - // Encoding this as a single `AtomicU64` allows us to use `Relaxed` |
329 | | - // operations, as we are only interested in the effects on a single |
330 | | - // memory location. |
331 | | - static INFO_BITS: AtomicU64 = AtomicU64::new(0); |
332 | | - |
333 | | - // If a previous thread has initialized `INFO_BITS`, use it. |
334 | | - let info_bits = INFO_BITS.load(Ordering::Relaxed); |
335 | | - if info_bits != 0 { |
336 | | - return info_from_bits(info_bits); |
337 | | - } |
338 | | - |
339 | | - // ... otherwise learn for ourselves ... |
340 | | - extern "C" { |
341 | | - fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t; |
342 | | - } |
343 | | - |
344 | | - let mut info = info_from_bits(0); |
345 | | - unsafe { |
346 | | - mach_timebase_info(&mut info); |
347 | | - } |
348 | | - INFO_BITS.store(info_to_bits(info), Ordering::Relaxed); |
349 | | - info |
| 260 | + pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { |
| 261 | + self.t.sub_timespec(&other.t).ok() |
350 | 262 | } |
351 | 263 |
|
352 | | - #[inline] |
353 | | - fn info_to_bits(info: mach_timebase_info) -> u64 { |
354 | | - ((info.denom as u64) << 32) | (info.numer as u64) |
| 264 | + pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { |
| 265 | + Some(Instant { t: self.t.checked_add_duration(other)? }) |
355 | 266 | } |
356 | 267 |
|
357 | | - #[inline] |
358 | | - fn info_from_bits(bits: u64) -> mach_timebase_info { |
359 | | - mach_timebase_info { numer: bits as u32, denom: (bits >> 32) as u32 } |
| 268 | + pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { |
| 269 | + Some(Instant { t: self.t.checked_sub_duration(other)? }) |
360 | 270 | } |
361 | 271 | } |
362 | 272 |
|
363 | | -#[cfg(not(any( |
364 | | - all(target_os = "macos", not(target_arch = "aarch64")), |
365 | | - target_os = "ios", |
366 | | - target_os = "watchos", |
367 | | - target_os = "tvos" |
368 | | -)))] |
369 | | -mod inner { |
370 | | - use crate::fmt; |
371 | | - use crate::time::Duration; |
372 | | - |
373 | | - use super::Timespec; |
374 | | - |
375 | | - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
376 | | - pub struct Instant { |
377 | | - t: Timespec, |
378 | | - } |
379 | | - |
380 | | - impl Instant { |
381 | | - pub fn now() -> Instant { |
382 | | - #[cfg(target_os = "macos")] |
383 | | - const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW; |
384 | | - #[cfg(not(target_os = "macos"))] |
385 | | - const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC; |
386 | | - Instant { t: Timespec::now(clock_id) } |
387 | | - } |
388 | | - |
389 | | - pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { |
390 | | - self.t.sub_timespec(&other.t).ok() |
391 | | - } |
392 | | - |
393 | | - pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { |
394 | | - Some(Instant { t: self.t.checked_add_duration(other)? }) |
395 | | - } |
396 | | - |
397 | | - pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { |
398 | | - Some(Instant { t: self.t.checked_sub_duration(other)? }) |
399 | | - } |
400 | | - } |
401 | | - |
402 | | - impl fmt::Debug for Instant { |
403 | | - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
404 | | - f.debug_struct("Instant") |
405 | | - .field("tv_sec", &self.t.tv_sec) |
406 | | - .field("tv_nsec", &self.t.tv_nsec.0) |
407 | | - .finish() |
408 | | - } |
| 273 | +impl fmt::Debug for Instant { |
| 274 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 275 | + f.debug_struct("Instant") |
| 276 | + .field("tv_sec", &self.t.tv_sec) |
| 277 | + .field("tv_nsec", &self.t.tv_nsec.0) |
| 278 | + .finish() |
409 | 279 | } |
410 | 280 | } |
0 commit comments