commit 841347f14f2f6037ec267349f7ad0bfff50ee460 Author: Julio Biason Date: Wed Aug 21 09:46:46 2024 -0300 Initial structure diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..7b2edcc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "beacon" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..03e5c0f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "beacon" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..80be532 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,37 @@ +//! A Semaphore-like structure. + +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; +use std::sync::Condvar; +use std::sync::Mutex; + +pub struct Beacon { + lock: Mutex, + guard: Condvar, +} + +impl Beacon { + pub fn new(leases: usize) -> Self { + Self { + lock: Mutex::new(AtomicUsize::new(leases)), + guard: Condvar::new(), + } + } + + pub fn acquire(&self, leases: usize) { + let mut control = self.lock.lock().unwrap(); + let mut current_leases = control.load(Ordering::Relaxed); + while current_leases < leases { + control = self.guard.wait(control).unwrap(); + current_leases = control.load(Ordering::Relaxed); + } + + control.fetch_sub(leases, Ordering::SeqCst); + } + + pub fn release(&self, leases: usize) { + let control = self.lock.lock().unwrap(); + control.fetch_add(leases, Ordering::SeqCst); + self.guard.notify_all(); + } +}