From 829709238cb00e68c79384a3aa02359db973f14a Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 12:38:57 -0800 Subject: [PATCH 01/13] add windows support to clocksource Adds windows support to clocksource --- .github/workflows/cargo.yml | 2 +- clocksource/Cargo.toml | 3 + clocksource/src/coarse/instant.rs | 29 +------- clocksource/src/coarse/unix_instant.rs | 29 +------- clocksource/src/lib.rs | 2 + clocksource/src/precise/instant.rs | 14 +--- clocksource/src/precise/unix_instant.rs | 14 +--- clocksource/src/sys/mod.rs | 9 +++ clocksource/src/sys/unix.rs | 68 ++++++++++++++++++ clocksource/src/sys/windows.rs | 95 +++++++++++++++++++++++++ 10 files changed, 182 insertions(+), 83 deletions(-) create mode 100644 clocksource/src/sys/mod.rs create mode 100644 clocksource/src/sys/unix.rs create mode 100644 clocksource/src/sys/windows.rs diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index e671083e..5b1e900f 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-latest, macos-12 ] + os: [ ubuntu-latest, macos-latest, windows-latest ] steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable diff --git a/clocksource/Cargo.toml b/clocksource/Cargo.toml index 7aa05cd7..436ead84 100644 --- a/clocksource/Cargo.toml +++ b/clocksource/Cargo.toml @@ -11,3 +11,6 @@ repository = "https://github.com/pelikan-io/rustcommon" [dependencies] libc = "0.2.147" time = { version = "0.3.27", features = ["formatting"] } + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3.9", features = ["ntdef", "profileapi", "sysinfoapi"] } diff --git a/clocksource/src/coarse/instant.rs b/clocksource/src/coarse/instant.rs index 9964efd1..71d75865 100644 --- a/clocksource/src/coarse/instant.rs +++ b/clocksource/src/coarse/instant.rs @@ -24,35 +24,8 @@ pub struct Instant { impl Instant { /// Return an `Instant` that represents the current moment. - #[cfg(not(target_os = "macos"))] pub fn now() -> Self { - let mut ts = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - unsafe { - libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, &mut ts); - } - - let now = ts.tv_sec as u32; - - Self { secs: now } - } - - /// Return an `Instant` that represents the current moment. - #[cfg(target_os = "macos")] - pub fn now() -> Self { - let mut ts = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - unsafe { - libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts); - } - - let now = ts.tv_sec as u32; - - Self { secs: now } + crate::sys::monotonic::coarse() } /// Return the elapsed time, in nanoseconds, since the original timestamp. diff --git a/clocksource/src/coarse/unix_instant.rs b/clocksource/src/coarse/unix_instant.rs index 45fb4026..27156bf5 100644 --- a/clocksource/src/coarse/unix_instant.rs +++ b/clocksource/src/coarse/unix_instant.rs @@ -31,35 +31,8 @@ impl UnixInstant { pub const EPOCH: UnixInstant = UnixInstant { secs: 0 }; /// Return a `UnixInstant` that represents the current moment. - #[cfg(not(target_os = "macos"))] pub fn now() -> Self { - let mut ts = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - unsafe { - libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, &mut ts); - } - - let now = ts.tv_sec as u32; - - Self { secs: now } - } - - /// Return a `UnixInstant` that represents the current moment. - #[cfg(target_os = "macos")] - pub fn now() -> Self { - let mut ts = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - unsafe { - libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts); - } - - let now = ts.tv_sec as u32; - - Self { secs: now } + crate::sys::realtime::coarse() } /// Return the elapsed time, in nanoseconds, since the original timestamp. diff --git a/clocksource/src/lib.rs b/clocksource/src/lib.rs index 98e4c934..937b8715 100644 --- a/clocksource/src/lib.rs +++ b/clocksource/src/lib.rs @@ -13,3 +13,5 @@ pub mod coarse; pub mod datetime; pub mod precise; + +mod sys; diff --git a/clocksource/src/precise/instant.rs b/clocksource/src/precise/instant.rs index 040a9f7f..26323861 100644 --- a/clocksource/src/precise/instant.rs +++ b/clocksource/src/precise/instant.rs @@ -26,19 +26,7 @@ pub struct Instant { impl Instant { /// Return an `Instant` that represents the current moment. pub fn now() -> Self { - let mut ts = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - unsafe { - libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts); - } - - let now = (ts.tv_sec as u64) - .wrapping_mul(1_000_000_000) - .wrapping_add(ts.tv_nsec as u64); - - Self { ns: now } + crate::sys::monotonic::precise() } /// Return the elapsed time, in nanoseconds, since the original timestamp. diff --git a/clocksource/src/precise/unix_instant.rs b/clocksource/src/precise/unix_instant.rs index 86149034..fedf4e80 100644 --- a/clocksource/src/precise/unix_instant.rs +++ b/clocksource/src/precise/unix_instant.rs @@ -35,19 +35,7 @@ impl UnixInstant { /// Return a `UnixInstant` that represents the current moment in time. pub fn now() -> Self { - let mut ts = libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }; - unsafe { - libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts); - } - - let now = (ts.tv_sec as u64) - .wrapping_mul(1_000_000_000) - .wrapping_add(ts.tv_nsec as u64); - - Self { ns: now } + crate::sys::realtime::precise() } /// Return the elapsed time, in nanoseconds, since the original timestamp. diff --git a/clocksource/src/sys/mod.rs b/clocksource/src/sys/mod.rs new file mode 100644 index 00000000..1fcbc3cc --- /dev/null +++ b/clocksource/src/sys/mod.rs @@ -0,0 +1,9 @@ +#[cfg(not(target_os = "windows"))] +mod unix; +#[cfg(not(target_os = "windows"))] +pub use unix::*; + +#[cfg(target_os = "windows")] +mod windows; +#[cfg(target_os = "windows")] +pub use windows::*; \ No newline at end of file diff --git a/clocksource/src/sys/unix.rs b/clocksource/src/sys/unix.rs new file mode 100644 index 00000000..b85ec0d2 --- /dev/null +++ b/clocksource/src/sys/unix.rs @@ -0,0 +1,68 @@ +#[cfg(any(target_os = "macos", target_os = "ios"))] +const CLOCK_MONOTONIC_COARSE: u32 = libc::CLOCK_MONOTONIC; + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +const CLOCK_MONOTONIC_COARSE: i32 = libc::CLOCK_MONOTONIC_COARSE; + +#[cfg(any(target_os = "macos", target_os = "ios"))] +const CLOCK_REALTIME_COARSE: u32 = libc::CLOCK_REALTIME; + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +const CLOCK_REALTIME_COARSE: i32 = libc::CLOCK_REALTIME_COARSE; + +pub fn read_clock(clock: i32) -> libc::timespec { + let mut ts = libc::timespec { + tv_sec: 0, + tv_nsec: 0, + }; + + unsafe { + libc::clock_gettime(clock as _, &mut ts); + } + + ts +} + +pub mod monotonic { + use super::*; + + pub fn coarse() -> crate::coarse::Instant { + let ts = read_clock(CLOCK_MONOTONIC_COARSE as _); + + let now = ts.tv_sec as u32; + + crate::coarse::Instant { secs: now } + } + + pub fn precise() -> crate::precise::Instant { + let ts = read_clock(libc::CLOCK_MONOTONIC as _); + + let now = (ts.tv_sec as u64) + .wrapping_mul(1_000_000_000) + .wrapping_add(ts.tv_nsec as u64); + + crate::precise::Instant { ns: now } + } +} + +pub mod realtime { + use super::*; + + pub fn coarse() -> crate::coarse::UnixInstant { + let ts = read_clock(CLOCK_REALTIME_COARSE as _); + + let now = ts.tv_sec as u32; + + crate::coarse::UnixInstant { secs: now } + } + + pub fn precise() -> crate::precise::UnixInstant { + let ts = read_clock(libc::CLOCK_REALTIME as _); + + let now = (ts.tv_sec as u64) + .wrapping_mul(1_000_000_000) + .wrapping_add(ts.tv_nsec as u64); + + crate::precise::UnixInstant { ns: now } + } +} diff --git a/clocksource/src/sys/windows.rs b/clocksource/src/sys/windows.rs new file mode 100644 index 00000000..9ac7cfe4 --- /dev/null +++ b/clocksource/src/sys/windows.rs @@ -0,0 +1,95 @@ +use core::sync::atomic::{AtomicU64, Ordering}; + +const NANOS_PER_SEC: u64 = 1_000_000_000; + +pub mod monotonic { + use super::*; + + use winapi::um::winnt::LARGE_INTEGER; + + static FREQUENCY: AtomicU64 = AtomicU64::new(0); + + fn frequency() -> u64 { + let cached = FREQUENCY.load(Ordering::Relaxed); + + if cached != 0 { + return cached; + } + + let frequency; + unsafe { + let mut frq: LARGE_INTEGER = core::mem::zeroed(); + let _ = winapi::um::profileapi::QueryPerformanceFrequency(&mut frq); + frequency = *frq.QuadPart() as u64; + } + + FREQUENCY.store(frequency, Ordering::Relaxed); + frequency + } + + fn count() -> u64 { + unsafe { + let mut cnt: LARGE_INTEGER = core::mem::zeroed(); + let _ = winapi::um::profileapi::QueryPerformanceCounter(&mut cnt); + *cnt.QuadPart() as u64 + } + } + + pub fn coarse() -> crate::coarse::Instant { + let count = count(); + let frequency = frequency(); + + let q = count / frequency; + let r = count % frequency; + + crate::coarse::Instant { + secs: (q + r / frequency) as u32 + } + } + + pub fn precise() -> crate::precise::Instant { + let count = count(); + let frequency = frequency(); + + let q = count / frequency; + let r = count % frequency; + + crate::precise::Instant { + ns: q * NANOS_PER_SEC + r * NANOS_PER_SEC / frequency + } + } +} + +pub mod realtime { + use super::*; + + use winapi::shared::minwindef::FILETIME; + + const UNIX_EPOCH_INTERVALS: u64 = 116_444_736 * NANOS_PER_SEC; + const NANOS_PER_INTERVAL: u64 = 100; + + const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / NANOS_PER_INTERVAL; + + fn unix_intervals() -> u64 { + let filetime; + unsafe { + let mut ft: FILETIME = core::mem::zeroed(); + let _ = winapi::um::sysinfoapi::GetSystemTimePreciseAsFileTime(&mut ft); + filetime = (core::mem::transmute::(ft)) as u64; + } + + filetime - UNIX_EPOCH_INTERVALS + } + + pub fn coarse() -> crate::coarse::UnixInstant { + crate::coarse::UnixInstant { + secs: (unix_intervals() / INTERVALS_PER_SEC) as u32 + } + } + + pub fn precise() -> crate::precise::UnixInstant { + crate::precise::UnixInstant { + ns: unix_intervals() * NANOS_PER_INTERVAL + } + } +} \ No newline at end of file From a61b2b19b5752b301f8b1bb1a6eadaa2465a6cd3 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 12:43:20 -0800 Subject: [PATCH 02/13] rustfmt --- clocksource/src/sys/mod.rs | 2 +- clocksource/src/sys/windows.rs | 148 ++++++++++++++++----------------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/clocksource/src/sys/mod.rs b/clocksource/src/sys/mod.rs index 1fcbc3cc..39fe3c6e 100644 --- a/clocksource/src/sys/mod.rs +++ b/clocksource/src/sys/mod.rs @@ -6,4 +6,4 @@ pub use unix::*; #[cfg(target_os = "windows")] mod windows; #[cfg(target_os = "windows")] -pub use windows::*; \ No newline at end of file +pub use windows::*; diff --git a/clocksource/src/sys/windows.rs b/clocksource/src/sys/windows.rs index 9ac7cfe4..7a13dd04 100644 --- a/clocksource/src/sys/windows.rs +++ b/clocksource/src/sys/windows.rs @@ -3,93 +3,93 @@ use core::sync::atomic::{AtomicU64, Ordering}; const NANOS_PER_SEC: u64 = 1_000_000_000; pub mod monotonic { - use super::*; + use super::*; - use winapi::um::winnt::LARGE_INTEGER; + use winapi::um::winnt::LARGE_INTEGER; - static FREQUENCY: AtomicU64 = AtomicU64::new(0); + static FREQUENCY: AtomicU64 = AtomicU64::new(0); - fn frequency() -> u64 { - let cached = FREQUENCY.load(Ordering::Relaxed); + fn frequency() -> u64 { + let cached = FREQUENCY.load(Ordering::Relaxed); - if cached != 0 { - return cached; - } + if cached != 0 { + return cached; + } - let frequency; - unsafe { - let mut frq: LARGE_INTEGER = core::mem::zeroed(); - let _ = winapi::um::profileapi::QueryPerformanceFrequency(&mut frq); - frequency = *frq.QuadPart() as u64; - } + let frequency; + unsafe { + let mut frq: LARGE_INTEGER = core::mem::zeroed(); + let _ = winapi::um::profileapi::QueryPerformanceFrequency(&mut frq); + frequency = *frq.QuadPart() as u64; + } - FREQUENCY.store(frequency, Ordering::Relaxed); - frequency - } + FREQUENCY.store(frequency, Ordering::Relaxed); + frequency + } - fn count() -> u64 { - unsafe { - let mut cnt: LARGE_INTEGER = core::mem::zeroed(); - let _ = winapi::um::profileapi::QueryPerformanceCounter(&mut cnt); - *cnt.QuadPart() as u64 - } - } + fn count() -> u64 { + unsafe { + let mut cnt: LARGE_INTEGER = core::mem::zeroed(); + let _ = winapi::um::profileapi::QueryPerformanceCounter(&mut cnt); + *cnt.QuadPart() as u64 + } + } - pub fn coarse() -> crate::coarse::Instant { - let count = count(); - let frequency = frequency(); + pub fn coarse() -> crate::coarse::Instant { + let count = count(); + let frequency = frequency(); - let q = count / frequency; - let r = count % frequency; + let q = count / frequency; + let r = count % frequency; - crate::coarse::Instant { - secs: (q + r / frequency) as u32 - } - } + crate::coarse::Instant { + secs: (q + r / frequency) as u32, + } + } - pub fn precise() -> crate::precise::Instant { - let count = count(); - let frequency = frequency(); + pub fn precise() -> crate::precise::Instant { + let count = count(); + let frequency = frequency(); - let q = count / frequency; - let r = count % frequency; + let q = count / frequency; + let r = count % frequency; - crate::precise::Instant { - ns: q * NANOS_PER_SEC + r * NANOS_PER_SEC / frequency - } - } + crate::precise::Instant { + ns: q * NANOS_PER_SEC + r * NANOS_PER_SEC / frequency, + } + } } pub mod realtime { - use super::*; - - use winapi::shared::minwindef::FILETIME; - - const UNIX_EPOCH_INTERVALS: u64 = 116_444_736 * NANOS_PER_SEC; - const NANOS_PER_INTERVAL: u64 = 100; - - const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / NANOS_PER_INTERVAL; - - fn unix_intervals() -> u64 { - let filetime; - unsafe { - let mut ft: FILETIME = core::mem::zeroed(); - let _ = winapi::um::sysinfoapi::GetSystemTimePreciseAsFileTime(&mut ft); - filetime = (core::mem::transmute::(ft)) as u64; - } - - filetime - UNIX_EPOCH_INTERVALS - } - - pub fn coarse() -> crate::coarse::UnixInstant { - crate::coarse::UnixInstant { - secs: (unix_intervals() / INTERVALS_PER_SEC) as u32 - } - } - - pub fn precise() -> crate::precise::UnixInstant { - crate::precise::UnixInstant { - ns: unix_intervals() * NANOS_PER_INTERVAL - } - } -} \ No newline at end of file + use super::*; + + use winapi::shared::minwindef::FILETIME; + + const UNIX_EPOCH_INTERVALS: u64 = 116_444_736 * NANOS_PER_SEC; + const NANOS_PER_INTERVAL: u64 = 100; + + const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / NANOS_PER_INTERVAL; + + fn unix_intervals() -> u64 { + let filetime; + unsafe { + let mut ft: FILETIME = core::mem::zeroed(); + let _ = winapi::um::sysinfoapi::GetSystemTimePreciseAsFileTime(&mut ft); + filetime = (core::mem::transmute::(ft)) as u64; + } + + filetime - UNIX_EPOCH_INTERVALS + } + + pub fn coarse() -> crate::coarse::UnixInstant { + crate::coarse::UnixInstant { + secs: (unix_intervals() / INTERVALS_PER_SEC) as u32, + } + } + + pub fn precise() -> crate::precise::UnixInstant { + crate::precise::UnixInstant { + ns: unix_intervals() * NANOS_PER_INTERVAL, + } + } +} From cdf346213990a327e783115c4d788ca8d22331cc Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 13:03:11 -0800 Subject: [PATCH 03/13] more fixes for windows support --- Cargo.toml | 4 ++-- awaken/Cargo.toml | 2 +- awaken/src/lib.rs | 4 ++++ clocksource/Cargo.toml | 2 +- ratelimit/Cargo.toml | 4 ++-- ringlog/Cargo.toml | 4 ++-- ringlog/src/format.rs | 6 +++--- ringlog/src/lib.rs | 2 +- ringlog/src/single.rs | 2 +- switchboard/Cargo.toml | 2 +- 10 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 29dc5bbc..0e43272d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,14 @@ resolver="2" members = [ "awaken", "clocksource", - "heatmap", + # "heatmap", "histogram", "metriken", "metriken/derive", "ratelimit", "ringlog", "switchboard", - "waterfall", + # "waterfall", ] [profile.bench] diff --git a/awaken/Cargo.toml b/awaken/Cargo.toml index af919256..ffb638ce 100644 --- a/awaken/Cargo.toml +++ b/awaken/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awaken" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" authors = ["Brian Martin "] diff --git a/awaken/src/lib.rs b/awaken/src/lib.rs index be0a9df7..f3da1747 100644 --- a/awaken/src/lib.rs +++ b/awaken/src/lib.rs @@ -35,6 +35,7 @@ impl Waker { } } + #[cfg(target_os = "linux")] pub fn as_raw_fd(&self) -> Option { self.inner.as_raw_fd() } @@ -47,9 +48,11 @@ impl Waker { pub trait GenericWaker: Send + Sync { fn wake(&self) -> std::io::Result<()>; + #[cfg(target_os = "linux")] fn as_raw_fd(&self) -> Option; } +#[cfg(target_os = "linux")] use std::os::unix::prelude::RawFd; pub use mio::Waker as MioWaker; @@ -59,6 +62,7 @@ impl GenericWaker for MioWaker { self.wake() } + #[cfg(target_os = "linux")] fn as_raw_fd(&self) -> Option { None } diff --git a/clocksource/Cargo.toml b/clocksource/Cargo.toml index 436ead84..84086517 100644 --- a/clocksource/Cargo.toml +++ b/clocksource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clocksource" -version = "0.7.1" +version = "0.8.0" authors = ["Brian Martin "] edition = "2021" description = "Library for times and durations with fixed-size representations" diff --git a/ratelimit/Cargo.toml b/ratelimit/Cargo.toml index 9c31af45..3e44c0c5 100644 --- a/ratelimit/Cargo.toml +++ b/ratelimit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ratelimit" -version = "0.8.0" +version = "0.9.0" authors = ["Brian Martin "] edition = "2021" license = "MIT OR Apache-2.0" @@ -9,6 +9,6 @@ homepage = "https://github.com/pelikan-io/rustcommon/ratelimit" repository = "https://github.com/pelikan-io/rustcommon" [dependencies] -clocksource = { version = "0.7.1" } +clocksource = { version = "0.8.0", path = "../clocksource" } parking_lot = "0.12.1" thiserror = "1.0.40" \ No newline at end of file diff --git a/ringlog/Cargo.toml b/ringlog/Cargo.toml index 8af7ef6b..0ed5f1ea 100644 --- a/ringlog/Cargo.toml +++ b/ringlog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ringlog" -version = "0.3.2" +version = "0.4.0" edition = "2021" license = "Apache-2.0" authors = ["Brian Martin "] @@ -10,7 +10,7 @@ repository = "https://github.com/pelikan-io/rustcommon" [dependencies] ahash = "0.8.0" -clocksource = { version = "0.6.0" } +clocksource = { version = "0.8.0", path = "../clocksource" } metriken = { version = "0.3.3", path = "../metriken" } log = { version = "0.4.17", features = ["std"] } mpmc = "0.1.6" diff --git a/ringlog/src/format.rs b/ringlog/src/format.rs index 5639bbea..6089ed74 100644 --- a/ringlog/src/format.rs +++ b/ringlog/src/format.rs @@ -4,7 +4,7 @@ use crate::*; -use clocksource::{DateTime, SecondsFormat}; +use clocksource::datetime::{DateTime}; pub type FormatFunction = fn( write: &mut dyn std::io::Write, @@ -20,7 +20,7 @@ pub fn default_format( writeln!( w, "{} {} [{}] {}", - now.to_rfc3339_opts(SecondsFormat::Millis, false), + now, record.level(), record.module_path().unwrap_or(""), record.args() @@ -35,7 +35,7 @@ pub fn klog_format( writeln!( w, "{} {}", - now.to_rfc3339_opts(SecondsFormat::Millis, false), + now, record.args() ) } diff --git a/ringlog/src/lib.rs b/ringlog/src/lib.rs index 1bf0ff11..75339100 100644 --- a/ringlog/src/lib.rs +++ b/ringlog/src/lib.rs @@ -52,7 +52,7 @@ pub use sampling::*; pub use single::*; pub use traits::*; -use clocksource::DateTime; +use clocksource::datetime::DateTime; use mpmc::Queue; pub(crate) type LogBuffer = Vec; diff --git a/ringlog/src/single.rs b/ringlog/src/single.rs index a0c707c6..4616c282 100644 --- a/ringlog/src/single.rs +++ b/ringlog/src/single.rs @@ -40,7 +40,7 @@ impl Log for Logger { .unwrap_or_else(|| Vec::with_capacity(self.buffer_size)); // Write the log message into the buffer and send to the receiver - if (self.format)(&mut buffer, DateTime::recent(), record).is_ok() { + if (self.format)(&mut buffer, DateTime::from(clocksource::precise::UnixInstant::now()), record).is_ok() { let bytes = buffer.len(); // Note this may drop a log message, but avoids blocking. The diff --git a/switchboard/Cargo.toml b/switchboard/Cargo.toml index c10aa9f5..52992f84 100644 --- a/switchboard/Cargo.toml +++ b/switchboard/Cargo.toml @@ -9,7 +9,7 @@ homepage = "https://github.com/pelikan-io/rustcommon" repository = "https://github.com/pelikan-io/rustcommon" [dependencies] -awaken = { version = "0.1.0", path = "../awaken" } +awaken = { version = "0.2.0", path = "../awaken" } crossbeam-queue = "0.3.8" rand = "0.8.5" rand_chacha = "0.3.1" From 3d4fb382c474b2b47e95ca8a18cc9a062490d4f4 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 13:04:10 -0800 Subject: [PATCH 04/13] rustfmt --- ringlog/src/format.rs | 9 ++------- ringlog/src/single.rs | 8 +++++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ringlog/src/format.rs b/ringlog/src/format.rs index 6089ed74..625b7789 100644 --- a/ringlog/src/format.rs +++ b/ringlog/src/format.rs @@ -4,7 +4,7 @@ use crate::*; -use clocksource::datetime::{DateTime}; +use clocksource::datetime::DateTime; pub type FormatFunction = fn( write: &mut dyn std::io::Write, @@ -32,10 +32,5 @@ pub fn klog_format( now: DateTime, record: &Record, ) -> Result<(), std::io::Error> { - writeln!( - w, - "{} {}", - now, - record.args() - ) + writeln!(w, "{} {}", now, record.args()) } diff --git a/ringlog/src/single.rs b/ringlog/src/single.rs index 4616c282..6e39b6dd 100644 --- a/ringlog/src/single.rs +++ b/ringlog/src/single.rs @@ -40,7 +40,13 @@ impl Log for Logger { .unwrap_or_else(|| Vec::with_capacity(self.buffer_size)); // Write the log message into the buffer and send to the receiver - if (self.format)(&mut buffer, DateTime::from(clocksource::precise::UnixInstant::now()), record).is_ok() { + if (self.format)( + &mut buffer, + DateTime::from(clocksource::precise::UnixInstant::now()), + record, + ) + .is_ok() + { let bytes = buffer.len(); // Note this may drop a log message, but avoids blocking. The From a397a50713c599a3ae3a0699b75c7a564f903a12 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 13:06:10 -0800 Subject: [PATCH 05/13] run tests on windows too --- .github/workflows/cargo.yml | 2 +- Cargo.toml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 5b1e900f..35a2fea1 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -93,7 +93,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-latest, macos-12 ] + os: [ ubuntu-latest, macos-latest, windows-latest ] profile: [ release, debug ] steps: - uses: actions/checkout@v3 diff --git a/Cargo.toml b/Cargo.toml index 0e43272d..8b76a603 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,12 @@ resolver="2" members = [ "awaken", "clocksource", - # "heatmap", "histogram", "metriken", "metriken/derive", "ratelimit", "ringlog", "switchboard", - # "waterfall", ] [profile.bench] From 148679d458ee4612c8b2506703a19ee9e555b52b Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 13:16:02 -0800 Subject: [PATCH 06/13] windows structs are smaller --- histogram/src/atomic.rs | 4 ++++ histogram/src/snapshot.rs | 4 ++++ histogram/src/standard.rs | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/histogram/src/atomic.rs b/histogram/src/atomic.rs index c653e3e8..d372a24b 100644 --- a/histogram/src/atomic.rs +++ b/histogram/src/atomic.rs @@ -80,7 +80,11 @@ mod test { #[test] fn size() { + #[cfg(not(target_os = "windows"))] assert_eq!(std::mem::size_of::(), 64); + + #[cfg(target_os = "windows")] + assert_eq!(std::mem::size_of::(), 56); } #[test] diff --git a/histogram/src/snapshot.rs b/histogram/src/snapshot.rs index ef02842f..91581aca 100644 --- a/histogram/src/snapshot.rs +++ b/histogram/src/snapshot.rs @@ -179,6 +179,10 @@ mod tests { #[test] fn size() { + #[cfg(not(target_os = "windows"))] assert_eq!(std::mem::size_of::(), 80); + + #[cfg(target_os = "windows")] + assert_eq!(std::mem::size_of::(), 64); } } diff --git a/histogram/src/standard.rs b/histogram/src/standard.rs index 00cd17dc..63106f36 100644 --- a/histogram/src/standard.rs +++ b/histogram/src/standard.rs @@ -284,7 +284,11 @@ mod tests { #[test] fn size() { + #[cfg(not(target_os = "windows"))] assert_eq!(std::mem::size_of::(), 64); + + #[cfg(target_os = "windows")] + assert_eq!(std::mem::size_of::(), 56); } #[test] From 209cdc07cc7f9dedb465066a4cca3ecedddfc5b5 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 13:48:21 -0800 Subject: [PATCH 07/13] rustfmt --- histogram/src/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/histogram/src/atomic.rs b/histogram/src/atomic.rs index d372a24b..c67784bc 100644 --- a/histogram/src/atomic.rs +++ b/histogram/src/atomic.rs @@ -83,7 +83,7 @@ mod test { #[cfg(not(target_os = "windows"))] assert_eq!(std::mem::size_of::(), 64); - #[cfg(target_os = "windows")] + #[cfg(target_os = "windows")] assert_eq!(std::mem::size_of::(), 56); } From 7cac7036ec3459c6b3f35f7908a0f1125efa1c4a Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 13:55:35 -0800 Subject: [PATCH 08/13] bump version numbers --- switchboard/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/switchboard/Cargo.toml b/switchboard/Cargo.toml index 52992f84..c073c2d7 100644 --- a/switchboard/Cargo.toml +++ b/switchboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "switchboard" -version = "0.2.1" +version = "0.3.0" edition = "2021" license = "Apache-2.0" authors = ["Brian Martin "] From be2f8e9d2999e869f65fcc16cc517d2c32fcd31d Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 14:29:41 -0800 Subject: [PATCH 09/13] test realtime clock --- clocksource/src/sys/windows.rs | 12 +++------ clocksource/tests/realtime_coarse.rs | 37 +++++++++++++++++++++++++++ clocksource/tests/realtime_precise.rs | 33 ++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 clocksource/tests/realtime_coarse.rs create mode 100644 clocksource/tests/realtime_precise.rs diff --git a/clocksource/src/sys/windows.rs b/clocksource/src/sys/windows.rs index 7a13dd04..daa7a6b9 100644 --- a/clocksource/src/sys/windows.rs +++ b/clocksource/src/sys/windows.rs @@ -36,14 +36,8 @@ pub mod monotonic { } pub fn coarse() -> crate::coarse::Instant { - let count = count(); - let frequency = frequency(); - - let q = count / frequency; - let r = count % frequency; - crate::coarse::Instant { - secs: (q + r / frequency) as u32, + secs: count() / frequency() as u32, } } @@ -51,8 +45,8 @@ pub mod monotonic { let count = count(); let frequency = frequency(); - let q = count / frequency; - let r = count % frequency; + let secs = count / frequency; + let ns = count % frequency; crate::precise::Instant { ns: q * NANOS_PER_SEC + r * NANOS_PER_SEC / frequency, diff --git a/clocksource/tests/realtime_coarse.rs b/clocksource/tests/realtime_coarse.rs new file mode 100644 index 00000000..336ed12a --- /dev/null +++ b/clocksource/tests/realtime_coarse.rs @@ -0,0 +1,37 @@ +use clocksource::coarse::UnixInstant; +use std::time::SystemTime; + +fn to_unix_ns(t: SystemTime) -> u64 { + t.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_nanos() as u64 +} + +#[test] +fn realtime_coarse() { + // the realtime clock may jump backward, so we may need to try a few times + for _ in 0..5 { + let t0 = SystemTime::now(); + let t1 = UnixInstant::now(); + let t2 = SystemTime::now(); + let t3 = UnixInstant::now(); + let t4 = SystemTime::now(); + + // convert our times into durations since the unix epoch + let ut0 = to_unix_ns(t0); + let ut1 = t1.duration_since(UnixInstant::EPOCH).as_secs(); + let ut2 = to_unix_ns(t2); + let ut3 = t3.duration_since(UnixInstant::EPOCH).as_secs(); + let ut4 = to_unix_ns(t4); + + // check that the clock has moved forward and not backward + if t0 < t2 && t2 < t4 { + let ut0 = (ut0 / 1_000_000_000) as u32; + let ut2 = (ut2 / 1_000_000_000) as u32; + let ut4 = (ut4 / 1_000_000_000) as u32; + + assert!(ut0 <= ut1); + assert!(ut1 <= ut2); + assert!(ut2 <= ut3); + assert!(ut3 <= ut4); + } + } +} diff --git a/clocksource/tests/realtime_precise.rs b/clocksource/tests/realtime_precise.rs new file mode 100644 index 00000000..e3012fa8 --- /dev/null +++ b/clocksource/tests/realtime_precise.rs @@ -0,0 +1,33 @@ +use clocksource::precise::UnixInstant; +use std::time::SystemTime; + +fn to_unix_ns(t: SystemTime) -> u64 { + t.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_nanos() as u64 +} + +#[test] +fn realtime_precise() { + // the realtime clock may jump backward, so we may need to try a few times + for _ in 0..5 { + let t0 = SystemTime::now(); + let t1 = UnixInstant::now(); + let t2 = SystemTime::now(); + let t3 = UnixInstant::now(); + let t4 = SystemTime::now(); + + // convert our times into durations since the unix epoch + let ut0 = to_unix_ns(t0); + let ut1 = t1.duration_since(UnixInstant::EPOCH).as_nanos(); + let ut2 = to_unix_ns(t2); + let ut3 = t3.duration_since(UnixInstant::EPOCH).as_secs(); + let ut4 = to_unix_ns(t4); + + // check that the clock has moved forward and not backward + if t0 < t2 && t2 < t4 { + assert!(ut0 <= ut1); + assert!(ut1 <= ut2); + assert!(ut2 <= ut3); + assert!(ut3 <= ut4); + } + } +} From 043ed18da37797bd51d2fc10650c6773d1fb0677 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 14:34:17 -0800 Subject: [PATCH 10/13] fix --- clocksource/src/sys/windows.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clocksource/src/sys/windows.rs b/clocksource/src/sys/windows.rs index daa7a6b9..0120569f 100644 --- a/clocksource/src/sys/windows.rs +++ b/clocksource/src/sys/windows.rs @@ -37,7 +37,7 @@ pub mod monotonic { pub fn coarse() -> crate::coarse::Instant { crate::coarse::Instant { - secs: count() / frequency() as u32, + secs: (count() / frequency()) as u32, } } @@ -49,7 +49,7 @@ pub mod monotonic { let ns = count % frequency; crate::precise::Instant { - ns: q * NANOS_PER_SEC + r * NANOS_PER_SEC / frequency, + ns: secs * NANOS_PER_SEC + ns * NANOS_PER_SEC / frequency, } } } From a9d83c47feb6818035e2b4573642a992f445403f Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 14:37:40 -0800 Subject: [PATCH 11/13] add printing of times --- clocksource/tests/realtime_coarse.rs | 8 ++++---- clocksource/tests/realtime_precise.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clocksource/tests/realtime_coarse.rs b/clocksource/tests/realtime_coarse.rs index 336ed12a..064956f8 100644 --- a/clocksource/tests/realtime_coarse.rs +++ b/clocksource/tests/realtime_coarse.rs @@ -28,10 +28,10 @@ fn realtime_coarse() { let ut2 = (ut2 / 1_000_000_000) as u32; let ut4 = (ut4 / 1_000_000_000) as u32; - assert!(ut0 <= ut1); - assert!(ut1 <= ut2); - assert!(ut2 <= ut3); - assert!(ut3 <= ut4); + assert!(ut0 <= ut1, "ut0: {ut0} ut1: {ut1}"); + assert!(ut1 <= ut2, "ut1: {ut1} ut2: {ut2}"); + assert!(ut2 <= ut3, "ut2: {ut2} ut3: {ut3}"); + assert!(ut3 <= ut4, "ut3: {ut3} ut4: {ut4}"); } } } diff --git a/clocksource/tests/realtime_precise.rs b/clocksource/tests/realtime_precise.rs index e3012fa8..e53961d0 100644 --- a/clocksource/tests/realtime_precise.rs +++ b/clocksource/tests/realtime_precise.rs @@ -24,10 +24,10 @@ fn realtime_precise() { // check that the clock has moved forward and not backward if t0 < t2 && t2 < t4 { - assert!(ut0 <= ut1); - assert!(ut1 <= ut2); - assert!(ut2 <= ut3); - assert!(ut3 <= ut4); + assert!(ut0 <= ut1, "ut0: {ut0} ut1: {ut1}"); + assert!(ut1 <= ut2, "ut1: {ut1} ut2: {ut2}"); + assert!(ut2 <= ut3, "ut2: {ut2} ut3: {ut3}"); + assert!(ut3 <= ut4, "ut3: {ut3} ut4: {ut4}"); } } } From 55751925649f7767abd239835122f5ef028fd7ba Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 14:39:12 -0800 Subject: [PATCH 12/13] fix --- clocksource/tests/realtime_precise.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clocksource/tests/realtime_precise.rs b/clocksource/tests/realtime_precise.rs index e53961d0..ca818c7a 100644 --- a/clocksource/tests/realtime_precise.rs +++ b/clocksource/tests/realtime_precise.rs @@ -19,7 +19,7 @@ fn realtime_precise() { let ut0 = to_unix_ns(t0); let ut1 = t1.duration_since(UnixInstant::EPOCH).as_nanos(); let ut2 = to_unix_ns(t2); - let ut3 = t3.duration_since(UnixInstant::EPOCH).as_secs(); + let ut3 = t3.duration_since(UnixInstant::EPOCH).as_nanos(); let ut4 = to_unix_ns(t4); // check that the clock has moved forward and not backward From 0b5dd8c5490061ca7543728f0aaa2896350122da Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Dec 2023 14:42:50 -0800 Subject: [PATCH 13/13] add newline --- ratelimit/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratelimit/Cargo.toml b/ratelimit/Cargo.toml index 3e44c0c5..8b153f26 100644 --- a/ratelimit/Cargo.toml +++ b/ratelimit/Cargo.toml @@ -11,4 +11,4 @@ repository = "https://github.com/pelikan-io/rustcommon" [dependencies] clocksource = { version = "0.8.0", path = "../clocksource" } parking_lot = "0.12.1" -thiserror = "1.0.40" \ No newline at end of file +thiserror = "1.0.40"