Skip to content

Instantly share code, notes, and snippets.

@pftbest
Created June 29, 2017 10:54
Show Gist options
  • Save pftbest/fd8782eae59a02c39c88247dd0ad5023 to your computer and use it in GitHub Desktop.
Save pftbest/fd8782eae59a02c39c88247dd0ad5023 to your computer and use it in GitHub Desktop.
extern crate core;
use core::default::Default;
use core::sync::atomic::{AtomicUsize, Ordering};
use core::cell::UnsafeCell;
const RING_SIZE: usize = 32;
pub struct Ring<T: Clone + Copy> {
head: AtomicUsize,
tail: AtomicUsize,
data: UnsafeCell<[T; RING_SIZE]>,
}
unsafe impl<T: Clone + Copy> Sync for Ring<T> {}
impl<T: Clone + Copy> Ring<T> {
pub fn new() -> Self
where
T: Default,
{
Ring {
head: AtomicUsize::new(0),
tail: AtomicUsize::new(0),
data: UnsafeCell::new([T::default(); RING_SIZE]),
}
}
pub fn put(&self, data: T) -> Result<(), ()> {
let head = self.head.load(Ordering::Relaxed);
let tail = self.tail.load(Ordering::Acquire);
let next_head = (head + 1) % RING_SIZE;
if next_head == tail {
return Err(());
}
unsafe {
(*self.data.get())[head] = data;
}
self.head.store(next_head, Ordering::Release);
Ok(())
}
pub fn get(&self) -> Result<T, ()> {
let tail = self.tail.load(Ordering::Relaxed);
let head = self.head.load(Ordering::Acquire);
if head == tail {
return Err(());
}
let data = unsafe { (*self.data.get())[tail] };
let next_tail = (tail + 1) % RING_SIZE;
self.tail.store(next_tail, Ordering::Release);
Ok(data)
}
}
use std::thread;
use std::sync::Arc;
fn main() {
let a = Arc::new(Ring::<u8>::new());
let b = a.clone();
const N: u32 = 10000;
let t1 = thread::spawn(move || {
let mut sum: u32 = 0;
for i in 0..N {
sum += (i as u8) as u32;
while let Err(_) = a.put(i as u8) {}
}
println!("Sent total: {}", sum);
});
let t2 = thread::spawn(move || {
let mut sum: u32 = 0;
for _ in 0..N {
let mut data = b.get();
while data.is_err() {
data = b.get();
}
sum += data.unwrap() as u32;
}
assert!(b.get().is_err());
println!("Received total: {}", sum);
});
t1.join().unwrap();
t2.join().unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment