Larger update #49
@ -1,5 +1,4 @@
|
|||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
use core::sync::atomic::{AtomicU16, Ordering};
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
@ -115,63 +114,63 @@ impl SequenceCountProviderCore<u16> for CcsdsSimpleSeqCountProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SeqCountProviderAtomicRef {
|
|
||||||
atomic: AtomicU16,
|
|
||||||
ordering: Ordering,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SeqCountProviderAtomicRef {
|
|
||||||
pub const fn new(ordering: Ordering) -> Self {
|
|
||||||
Self {
|
|
||||||
atomic: AtomicU16::new(0),
|
|
||||||
ordering,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SequenceCountProviderCore<u16> for SeqCountProviderAtomicRef {
|
|
||||||
fn get(&self) -> u16 {
|
|
||||||
self.atomic.load(self.ordering)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn increment(&self) {
|
|
||||||
self.atomic.fetch_add(1, self.ordering);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_and_increment(&self) -> u16 {
|
|
||||||
self.atomic.fetch_add(1, self.ordering)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod stdmod {
|
pub mod stdmod {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
macro_rules! sync_clonable_seq_counter_impl {
|
||||||
|
($($ty: ident,)+) => {
|
||||||
|
$(paste! {
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct SeqCountProviderSyncClonable {
|
pub struct [<SeqCountProviderSync $ty:upper>] {
|
||||||
seq_count: Arc<AtomicU16>,
|
seq_count: Arc<Mutex<$ty>>,
|
||||||
|
max_val: $ty
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SequenceCountProviderCore<u16> for SeqCountProviderSyncClonable {
|
impl [<SeqCountProviderSync $ty:upper>] {
|
||||||
fn get(&self) -> u16 {
|
pub fn new() -> Self {
|
||||||
self.seq_count.load(Ordering::SeqCst)
|
Self::new_with_max_val($ty::MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_max_val(max_val: $ty) -> Self {
|
||||||
|
Self {
|
||||||
|
seq_count: Arc::default(),
|
||||||
|
max_val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl SequenceCountProviderCore<$ty> for [<SeqCountProviderSync $ty:upper>] {
|
||||||
|
fn get(&self) -> $ty {
|
||||||
|
*self.seq_count.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment(&self) {
|
fn increment(&self) {
|
||||||
self.seq_count.fetch_add(1, Ordering::SeqCst);
|
self.get_and_increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_and_increment(&self) -> u16 {
|
fn get_and_increment(&self) -> $ty {
|
||||||
self.seq_count.fetch_add(1, Ordering::SeqCst)
|
let mut counter = self.seq_count.lock().unwrap();
|
||||||
|
let current_val = *counter;
|
||||||
|
if *counter == self.max_val {
|
||||||
|
*counter = 0;
|
||||||
|
} else {
|
||||||
|
*counter += 1;
|
||||||
|
}
|
||||||
|
current_val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sync_clonable_seq_counter_impl!(u8, u16, u32, u64,);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::seq_count::{
|
use crate::seq_count::{
|
||||||
CcsdsSimpleSeqCountProvider, SeqCountProviderSimple, SequenceCountProviderCore,
|
CcsdsSimpleSeqCountProvider, SeqCountProviderSimple, SeqCountProviderSyncU8,
|
||||||
|
SequenceCountProviderCore,
|
||||||
};
|
};
|
||||||
use spacepackets::MAX_SEQ_COUNT;
|
use spacepackets::MAX_SEQ_COUNT;
|
||||||
|
|
||||||
@ -210,4 +209,31 @@ mod tests {
|
|||||||
}
|
}
|
||||||
assert_eq!(ccsds_counter.get(), 0);
|
assert_eq!(ccsds_counter.get(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_atomic_ref_counters() {
|
||||||
|
let sync_u8_counter = SeqCountProviderSyncU8::new();
|
||||||
|
assert_eq!(sync_u8_counter.get(), 0);
|
||||||
|
assert_eq!(sync_u8_counter.get_and_increment(), 0);
|
||||||
|
assert_eq!(sync_u8_counter.get_and_increment(), 1);
|
||||||
|
assert_eq!(sync_u8_counter.get(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_atomic_ref_counters_overflow() {
|
||||||
|
let sync_u8_counter = SeqCountProviderSyncU8::new();
|
||||||
|
for _ in 0..u8::MAX as u16 + 1 {
|
||||||
|
sync_u8_counter.increment();
|
||||||
|
}
|
||||||
|
assert_eq!(sync_u8_counter.get(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_atomic_ref_counters_overflow_custom_max_val() {
|
||||||
|
let sync_u8_counter = SeqCountProviderSyncU8::new_with_max_val(128);
|
||||||
|
for _ in 0..129 {
|
||||||
|
sync_u8_counter.increment();
|
||||||
|
}
|
||||||
|
assert_eq!(sync_u8_counter.get(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user