Crates.io | ref_count |
lib.rs | ref_count |
version | 0.1.2 |
source | src |
created_at | 2024-02-22 05:32:16.749014 |
updated_at | 2024-02-22 18:24:44.428516 |
description | Efficient, low-level asynchronous synchronization for real-time and embedded systems |
homepage | |
repository | https://github.com/IronVelo/ref_count |
max_upload_size | |
id | 1148965 |
size | 92,053 |
ref_count
is a high-performance, robust, no_std
, no_alloc
, async reference counting crate designed for Rust
environments that require efficiency and low overhead. It leverages core futures and core wakers, alongside a lock-free
queue, to manage synchronization without blocking or spinning, making it ideal for use in embedded systems, real-time
applications, or any scenario where dynamic memory allocation and standard library features are not available or desired.
loom
among other measures.no_std
and no_alloc
: Works in no_std
environments without requiring dynamic memory allocation.Add ref_count
to your Cargo.toml
:
[dependencies]
ref_count = "0.1.2"
Creating an RwLock
use ref_count::{RefCount, Ref, ExclusiveRef, maybe_await};
use core::cell::UnsafeCell;
const MAX_WAITERS: usize = 32;
struct RwLock<T> {
data: UnsafeCell<T>,
state: RefCount<MAX_WAITERS>
}
struct ReadGuard<'lock, T> {
_ref: Ref<'lock, MAX_WAITERS>,
data: &'lock T
}
struct WriteGuard<'lock, T> {
_ref: ExclusiveRef<'lock, MAX_WAITERS>,
data: &'lock mut T
}
impl<T> RwLock<T> {
fn new(t: T) -> Self {
Self {
data: UnsafeCell::new(t),
state: RefCount::new()
}
}
async fn read(&self) -> ReadGuard<T> {
let r = maybe_await!(self.state.get_ref());
ReadGuard {
_ref: r,
// SAFETY: Multiple read guards can be created as `RefCount` ensures that
// no exclusive references are granted when shared references exist.
data: unsafe { &*self.data.get() }
}
}
async fn write(&self) -> WriteGuard<T> {
let e = maybe_await!(self.state.get_exclusive_ref());
WriteGuard {
_ref: e,
// SAFETY: Only one `WriteGuard` can be created at a time as `RefCount` ensures
// exclusive access to the data.
data: unsafe { &mut *self.data.get() }
}
}
}
The example above was crafted in under two minutes, highlighting the straightforward and user-friendly design of
ref_count
. This simplicity is at the core of the crate's philosophy, ensuring developers can implement robust,
no_std
, no_alloc
, async reference counting without a steep learning curve. Whether in embedded systems, real-time
applications, or other efficiency-critical environments, ref_count
aims to simplify the development process while
maintaining high performance and safety standards.
In the development of ref_count
, it was observed that in many applications, particularly those using read-write locks,
the frequency of read operations significantly surpasses that of write operations. This pattern is not merely anecdotal
but a well-documented phenomenon across a variety of fields, from file systems to database management. With this
insight, ref_count
was deliberately engineered to excel in these common scenarios, thereby ensuring that the
operations performed most frequently are also the most efficient.
By focusing on enhancing the performance of acquiring and releasing standard references, ref_count
achieves over a 50%
improvement in these operations compared to its leading competitors. For exclusive references, the design prioritizes
acquisition speed and efficiency for waiting threads, rather than concentrating solely on the speed of release
operations.