-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new io module for data structures specifically optimized for working with I/O and bytes. Include "pipes" in this new module, which is simply a wrapper around an atomic byte buffer with blocking features. Also move any internal types into an internal module.
- Loading branch information
Showing
9 changed files
with
398 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#[macro_use] | ||
extern crate criterion; | ||
extern crate ringtail; | ||
|
||
use criterion::Criterion; | ||
use std::io::{self, Write}; | ||
use std::thread; | ||
|
||
fn pipe_read_write_benchmark(c: &mut Criterion) { | ||
c.bench_function("pipe_read_write", |b| { | ||
let data = [1; 0x1000]; | ||
|
||
b.iter(move || { | ||
let (mut r, mut w) = ringtail::io::pipe(); | ||
|
||
let guard = thread::spawn(move || { | ||
for _ in 0..0x10 { | ||
w.write_all(&data).unwrap(); | ||
} | ||
}); | ||
|
||
io::copy(&mut r, &mut io::sink()).unwrap(); | ||
|
||
guard.join().unwrap(); | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group!(benches, pipe_read_write_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
//! Internal supporting structures. | ||
pub mod arrays; | ||
pub mod sync; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//! Synchronization primitives. | ||
use std::sync::atomic::*; | ||
use std::sync::{Condvar, Mutex}; | ||
|
||
/// A synchronization primitive used to put threads to sleep until another thread wakes it up. | ||
pub struct Signal { | ||
lock: Mutex<()>, | ||
condvar: Condvar, | ||
notified: AtomicBool, | ||
waiting: AtomicUsize, | ||
} | ||
|
||
impl Default for Signal { | ||
fn default() -> Self { | ||
Self { | ||
lock: Mutex::new(()), | ||
condvar: Condvar::new(), | ||
notified: AtomicBool::default(), | ||
waiting: AtomicUsize::default(), | ||
} | ||
} | ||
} | ||
|
||
impl Signal { | ||
pub fn notify(&self) { | ||
// Set the notify flag. | ||
self.notified.store(true, Ordering::SeqCst); | ||
|
||
// If any threads are waiting, wake one up. | ||
if self.waiting.load(Ordering::SeqCst) > 0 { | ||
// Acquire the mutex to coordinate waking up a thread. | ||
let _guard = self.lock.lock().unwrap(); | ||
self.condvar.notify_one(); | ||
} | ||
} | ||
|
||
pub fn wait(&self) { | ||
// Fast path. | ||
if self.notified.swap(false, Ordering::SeqCst) { | ||
return; | ||
} | ||
|
||
// Indicate we have begun waiting. | ||
self.waiting.fetch_add(1, Ordering::SeqCst); | ||
|
||
// Acquire the mutex to coordinate waiting. | ||
let mut guard = self.lock.lock().unwrap(); | ||
|
||
// Ensure the notify flag was not just set, then wait loop to ignore spurious wake-ups. | ||
while !self.notified.swap(false, Ordering::SeqCst) { | ||
guard = self.condvar.wait(guard).unwrap(); | ||
} | ||
|
||
// We're finished waiting. | ||
drop(guard); | ||
self.waiting.fetch_sub(1, Ordering::SeqCst); | ||
} | ||
} |
Oops, something went wrong.