rust-kernel
Rustbelt: a hobby x86_64 kernel written in Rust
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | //! A microsecond clock for the network stack.
//!
//! The PIT ticks only ~18.2 times a second (55 ms), far too coarse to time
//! a ping (QEMU answers in well under a millisecond) or to run TCP's
//! retransmit timers. Every x86-64 CPU has a *time stamp counter* (TSC): a
//! 64-bit counter that goes up at a fixed rate, read with `rdtsc`. We don't
//! know that rate, so we measure it once against the PIT (apic.rs does this
//! while it calibrates the APIC timer, over 2 PIT ticks) and from then on
//! `now_us` is just `rdtsc / rate`.
//!
//! Before calibration (or if it never happens, e.g. in some tests) we fall
//! back to counting PIT ticks.
use ;
/// One PIT tick in microseconds (1 / 18.2065 Hz).
pub const PIT_TICK_US: u64 = 54_925;
static TSC_PER_MS: AtomicU64 = new;
static TSC_START: AtomicU64 = new;
/// Called with a TSC reading at a PIT tick edge (`start`) and the number of
/// ticks it took to reach `end`.
/// Microseconds since boot.
/// The PIT tick by which `us` microseconds from now will surely have
/// passed. For sleeping/timeouts, which may run late but never early: we
/// may be anywhere inside the current ~55 ms tick, so one extra tick.
// ---------------------------------------------------------------------------
// Wall-clock time (CLOCK_REALTIME)
// ---------------------------------------------------------------------------
/// Unix time (microseconds since 1970-01-01 UTC) at boot (now_us = 0),
/// read from the CMOS clock on first use. 0 = not read yet.
static BOOT_REALTIME_US: AtomicU64 = new;
/// Read a CMOS register (the PC's battery-backed real-time clock).
/// The RTC's date and time as Unix seconds. QEMU's RTC runs on UTC.
/// Days since 1970-01-01 for a date (Howard Hinnant's algorithm).
/// Microseconds since 1970-01-01 UTC (clock_gettime(CLOCK_REALTIME)).
|