|
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
|
@@ -250,161 +248,59 @@ impl From<__timespec64> for Timespec {
|
250 | 248 | }
|
251 | 249 | }
|
252 | 250 |
|
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)) |
321 |
| - } |
| 251 | +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 252 | +pub struct Instant { |
| 253 | + t: Timespec, |
| 254 | +} |
322 | 255 |
|
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. |
| 256 | +impl Instant { |
| 257 | + pub fn now() -> Instant { |
| 258 | + // https://www.manpagez.com/man/3/clock_gettime/ |
327 | 259 | //
|
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 | + // CLOCK_UPTIME_RAW clock that increments monotonically, in the same man- |
| 261 | + // ner as CLOCK_MONOTONIC_RAW, but that does not incre- |
| 262 | + // ment while the system is asleep. The returned value |
| 263 | + // is identical to the result of mach_absolute_time() |
| 264 | + // after the appropriate mach_timebase conversion is |
| 265 | + // applied. |
| 266 | + // |
| 267 | + // Instant on macos was historically implemented using mach_absolute_time; |
| 268 | + // we preserve this value domain out of an abundance of caution. |
| 269 | + #[cfg(any( |
| 270 | + target_os = "macos", |
| 271 | + target_os = "ios", |
| 272 | + target_os = "watchos", |
| 273 | + target_os = "tvos" |
| 274 | + ))] |
| 275 | + const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW; |
| 276 | + #[cfg(not(any( |
| 277 | + target_os = "macos", |
| 278 | + target_os = "ios", |
| 279 | + target_os = "watchos", |
| 280 | + target_os = "tvos" |
| 281 | + )))] |
| 282 | + const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC; |
| 283 | + Instant { t: Timespec::now(clock_id) } |
350 | 284 | }
|
351 | 285 |
|
352 |
| - #[inline] |
353 |
| - fn info_to_bits(info: mach_timebase_info) -> u64 { |
354 |
| - ((info.denom as u64) << 32) | (info.numer as u64) |
| 286 | + pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { |
| 287 | + self.t.sub_timespec(&other.t).ok() |
355 | 288 | }
|
356 | 289 |
|
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 } |
| 290 | + pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { |
| 291 | + Some(Instant { t: self.t.checked_add_duration(other)? }) |
360 | 292 | }
|
361 |
| -} |
362 | 293 |
|
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 |
| - } |
| 294 | + pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { |
| 295 | + Some(Instant { t: self.t.checked_sub_duration(other)? }) |
400 | 296 | }
|
| 297 | +} |
401 | 298 |
|
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 |
| - } |
| 299 | +impl fmt::Debug for Instant { |
| 300 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 301 | + f.debug_struct("Instant") |
| 302 | + .field("tv_sec", &self.t.tv_sec) |
| 303 | + .field("tv_nsec", &self.t.tv_nsec.0) |
| 304 | + .finish() |
409 | 305 | }
|
410 | 306 | }
|
0 commit comments