Skip to content

Commit

Permalink
add windows support to rustcommon (#92)
Browse files Browse the repository at this point in the history
Adds windows support to rustcommon
  • Loading branch information
brayniac authored Dec 15, 2023
1 parent f71961d commit 452c4cc
Show file tree
Hide file tree
Showing 24 changed files with 283 additions and 105 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/cargo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ resolver="2"
members = [
"awaken",
"clocksource",
"heatmap",
"histogram",
"metriken",
"metriken/derive",
"ratelimit",
"ringlog",
"switchboard",
"waterfall",
]

[profile.bench]
Expand Down
2 changes: 1 addition & 1 deletion awaken/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "awaken"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "Apache-2.0"
authors = ["Brian Martin <brian@pelikan.io>"]
Expand Down
4 changes: 4 additions & 0 deletions awaken/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ impl Waker {
}
}

#[cfg(target_os = "linux")]
pub fn as_raw_fd(&self) -> Option<RawFd> {
self.inner.as_raw_fd()
}
Expand All @@ -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<RawFd>;
}

#[cfg(target_os = "linux")]
use std::os::unix::prelude::RawFd;

pub use mio::Waker as MioWaker;
Expand All @@ -59,6 +62,7 @@ impl GenericWaker for MioWaker {
self.wake()
}

#[cfg(target_os = "linux")]
fn as_raw_fd(&self) -> Option<RawFd> {
None
}
Expand Down
5 changes: 4 additions & 1 deletion clocksource/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "clocksource"
version = "0.7.1"
version = "0.8.0"
authors = ["Brian Martin <brian@pelikan.io>"]
edition = "2021"
description = "Library for times and durations with fixed-size representations"
Expand All @@ -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"] }
29 changes: 1 addition & 28 deletions clocksource/src/coarse/instant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
29 changes: 1 addition & 28 deletions clocksource/src/coarse/unix_instant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions clocksource/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
pub mod coarse;
pub mod datetime;
pub mod precise;

mod sys;
14 changes: 1 addition & 13 deletions clocksource/src/precise/instant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 1 addition & 13 deletions clocksource/src/precise/unix_instant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 9 additions & 0 deletions clocksource/src/sys/mod.rs
Original file line number Diff line number Diff line change
@@ -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::*;
68 changes: 68 additions & 0 deletions clocksource/src/sys/unix.rs
Original file line number Diff line number Diff line change
@@ -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 }
}
}
89 changes: 89 additions & 0 deletions clocksource/src/sys/windows.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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 {
crate::coarse::Instant {
secs: (count() / frequency()) as u32,
}
}

pub fn precise() -> crate::precise::Instant {
let count = count();
let frequency = frequency();

let secs = count / frequency;
let ns = count % frequency;

crate::precise::Instant {
ns: secs * NANOS_PER_SEC + ns * 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::<FILETIME, i64>(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,
}
}
}
Loading

0 comments on commit 452c4cc

Please sign in to comment.