Skip to content

Commit

Permalink
Merge pull request #3393 from sourcebox/sync-additions
Browse files Browse the repository at this point in the history
embassy-sync: add clear, len, is_empty and is_full functions to zerocopy_channel
  • Loading branch information
Dirbaio authored Oct 6, 2024
2 parents 8f27349 + 12e6add commit 631fec8
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 3 deletions.
1 change: 1 addition & 0 deletions embassy-sync/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased

- Add LazyLock sync primitive.
- Add `clear`, `len`, `is_empty` and `is_full` functions to `zerocopy_channel`.

## 0.6.0 - 2024-05-29

Expand Down
91 changes: 88 additions & 3 deletions embassy-sync/src/zerocopy_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl<'a, M: RawMutex, T> Channel<'a, M, T> {
buf: buf.as_mut_ptr(),
phantom: PhantomData,
state: Mutex::new(RefCell::new(State {
len,
capacity: len,
front: 0,
back: 0,
full: false,
Expand All @@ -70,6 +70,28 @@ impl<'a, M: RawMutex, T> Channel<'a, M, T> {
pub fn split(&mut self) -> (Sender<'_, M, T>, Receiver<'_, M, T>) {
(Sender { channel: self }, Receiver { channel: self })
}

/// Clears all elements in the channel.
pub fn clear(&mut self) {
self.state.lock(|s| {
s.borrow_mut().clear();
});
}

/// Returns the number of elements currently in the channel.
pub fn len(&self) -> usize {
self.state.lock(|s| s.borrow().len())
}

/// Returns whether the channel is empty.
pub fn is_empty(&self) -> bool {
self.state.lock(|s| s.borrow().is_empty())
}

/// Returns whether the channel is full.
pub fn is_full(&self) -> bool {
self.state.lock(|s| s.borrow().is_full())
}
}

/// Send-only access to a [`Channel`].
Expand Down Expand Up @@ -130,6 +152,28 @@ impl<'a, M: RawMutex, T> Sender<'a, M, T> {
pub fn send_done(&mut self) {
self.channel.state.lock(|s| s.borrow_mut().push_done())
}

/// Clears all elements in the channel.
pub fn clear(&mut self) {
self.channel.state.lock(|s| {
s.borrow_mut().clear();
});
}

/// Returns the number of elements currently in the channel.
pub fn len(&self) -> usize {
self.channel.state.lock(|s| s.borrow().len())
}

/// Returns whether the channel is empty.
pub fn is_empty(&self) -> bool {
self.channel.state.lock(|s| s.borrow().is_empty())
}

/// Returns whether the channel is full.
pub fn is_full(&self) -> bool {
self.channel.state.lock(|s| s.borrow().is_full())
}
}

/// Receive-only access to a [`Channel`].
Expand Down Expand Up @@ -190,10 +234,33 @@ impl<'a, M: RawMutex, T> Receiver<'a, M, T> {
pub fn receive_done(&mut self) {
self.channel.state.lock(|s| s.borrow_mut().pop_done())
}

/// Clears all elements in the channel.
pub fn clear(&mut self) {
self.channel.state.lock(|s| {
s.borrow_mut().clear();
});
}

/// Returns the number of elements currently in the channel.
pub fn len(&self) -> usize {
self.channel.state.lock(|s| s.borrow().len())
}

/// Returns whether the channel is empty.
pub fn is_empty(&self) -> bool {
self.channel.state.lock(|s| s.borrow().is_empty())
}

/// Returns whether the channel is full.
pub fn is_full(&self) -> bool {
self.channel.state.lock(|s| s.borrow().is_full())
}
}

struct State {
len: usize,
/// Maximum number of elements the channel can hold.
capacity: usize,

/// Front index. Always 0..=(N-1)
front: usize,
Expand All @@ -210,13 +277,31 @@ struct State {

impl State {
fn increment(&self, i: usize) -> usize {
if i + 1 == self.len {
if i + 1 == self.capacity {
0
} else {
i + 1
}
}

fn clear(&mut self) {
self.front = 0;
self.back = 0;
self.full = false;
}

fn len(&self) -> usize {
if !self.full {
if self.back >= self.front {
self.back - self.front
} else {
self.capacity + self.back - self.front
}
} else {
self.capacity
}
}

fn is_full(&self) -> bool {
self.full
}
Expand Down

0 comments on commit 631fec8

Please sign in to comment.