Skip to content

Commit

Permalink
Add winapi srwlock to benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
nico-abram authored and Nicolás Luján committed Oct 27, 2020
1 parent ab3718f commit 143710f
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 10 deletions.
3 changes: 3 additions & 0 deletions benchmark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ path = "src/rwlock.rs"
[features]
nightly = ["parking_lot/nightly"]
deadlock_detection = ["parking_lot/deadlock_detection"]

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["synchapi"] }
51 changes: 50 additions & 1 deletion benchmark/src/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
mod args;
use crate::args::ArgRange;

#[cfg(unix)]
#[cfg(any(windows, unix))]
use std::cell::UnsafeCell;
use std::{
sync::{
Expand Down Expand Up @@ -57,6 +57,46 @@ impl<T> Mutex<T> for parking_lot::Mutex<T> {
}
}

#[cfg(not(windows))]
type SrwLock<T> = std::sync::Mutex<T>;

#[cfg(windows)]
use winapi::um::synchapi;
#[cfg(windows)]
struct SrwLock<T>(UnsafeCell<T>, UnsafeCell<synchapi::SRWLOCK>);
#[cfg(windows)]
unsafe impl<T> Sync for SrwLock<T> {}
#[cfg(windows)]
unsafe impl<T: Send> Send for SrwLock<T> {}
#[cfg(windows)]
impl<T> Mutex<T> for SrwLock<T> {
fn new(v: T) -> Self {
let mut h: synchapi::SRWLOCK = synchapi::SRWLOCK { Ptr: std::ptr::null_mut() };

unsafe {
synchapi::InitializeSRWLock(&mut h);
}
SrwLock(
UnsafeCell::new(v),
UnsafeCell::new(h),
)
}
fn lock<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
unsafe {
synchapi::AcquireSRWLockExclusive(self.1.get());
let res = f(&mut *self.0.get());
synchapi::ReleaseSRWLockExclusive(self.1.get());
res
}
}
fn name() -> &'static str {
"winapi_srwlock"
}
}

#[cfg(not(unix))]
type PthreadMutex<T> = std::sync::Mutex<T>;

Expand Down Expand Up @@ -220,6 +260,15 @@ fn run_all(
seconds_per_test,
test_iterations,
);
if cfg!(windows) {
run_benchmark_iterations::<SrwLock<f64>>(
num_threads,
work_per_critical_section,
work_between_critical_sections,
seconds_per_test,
test_iterations,
);
}
if cfg!(unix) {
run_benchmark_iterations::<PthreadMutex<f64>>(
num_threads,
Expand Down
71 changes: 62 additions & 9 deletions benchmark/src/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
mod args;
use crate::args::ArgRange;

#[cfg(unix)]
#[cfg(any(windows, unix))]
use std::cell::UnsafeCell;
use std::{
sync::{
Expand Down Expand Up @@ -93,6 +93,57 @@ impl<T: Copy> RwLock<T> for seqlock::SeqLock<T> {
}
}

#[cfg(not(windows))]
type SrwLock<T> = std::sync::RwLock<T>;

#[cfg(windows)]
use winapi::um::synchapi;
#[cfg(windows)]
struct SrwLock<T>(UnsafeCell<T>, UnsafeCell<synchapi::SRWLOCK>);
#[cfg(windows)]
unsafe impl<T> Sync for SrwLock<T> {}
#[cfg(windows)]
unsafe impl<T: Send> Send for SrwLock<T> {}
#[cfg(windows)]
impl<T> RwLock<T> for SrwLock<T> {
fn new(v: T) -> Self {
let mut h: synchapi::SRWLOCK = synchapi::SRWLOCK { Ptr: std::ptr::null_mut() };

unsafe {
synchapi::InitializeSRWLock(&mut h);
}
SrwLock(
UnsafeCell::new(v),
UnsafeCell::new(h),
)
}
fn read<F, R>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
unsafe {
synchapi::AcquireSRWLockShared(self.1.get());
let res = f(&*self.0.get());
synchapi::ReleaseSRWLockShared(self.1.get());
res
}
}
fn write<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
unsafe {
synchapi::AcquireSRWLockExclusive(self.1.get());
let res = f(&mut *self.0.get());
synchapi::ReleaseSRWLockExclusive(self.1.get());
res
}
}
fn name() -> &'static str {
"winapi_srwlock"
}
}

#[cfg(not(unix))]
type PthreadRwLock<T> = std::sync::RwLock<T>;

Expand Down Expand Up @@ -304,14 +355,16 @@ fn run_all(
seconds_per_test,
test_iterations,
);
run_benchmark_iterations::<std::sync::RwLock<f64>>(
num_writer_threads,
num_reader_threads,
work_per_critical_section,
work_between_critical_sections,
seconds_per_test,
test_iterations,
);
if cfg!(windows) {
run_benchmark_iterations::<std::sync::RwLock<f64>>(
num_writer_threads,
num_reader_threads,
work_per_critical_section,
work_between_critical_sections,
seconds_per_test,
test_iterations,
);
}
if cfg!(unix) {
run_benchmark_iterations::<PthreadRwLock<f64>>(
num_writer_threads,
Expand Down

0 comments on commit 143710f

Please sign in to comment.