mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Fix missing docs for AtomicDownUp, add a simple unit test.
This commit is contained in:
parent
31823d13fa
commit
b91bc23523
@ -1,7 +1,17 @@
|
|||||||
|
//! AtomicDownUp is a struct that contains two atomic u64 values, one for down and one for up.
|
||||||
|
//! We frequently order things down and then up in kernel maps, keeping the ordering explicit
|
||||||
|
//! helps reduce directional confusion/bugs.
|
||||||
|
|
||||||
use std::sync::atomic::AtomicU64;
|
use std::sync::atomic::AtomicU64;
|
||||||
use std::sync::atomic::Ordering::Relaxed;
|
use std::sync::atomic::Ordering::Relaxed;
|
||||||
use crate::units::DownUpOrder;
|
use crate::units::DownUpOrder;
|
||||||
|
|
||||||
|
/// AtomicDownUp is a struct that contains two atomic u64 values, one for down and one for up.
|
||||||
|
/// It's typically used for throughput, but can be used for any pairing that needs to keep track
|
||||||
|
/// of values by direction.
|
||||||
|
///
|
||||||
|
/// Note that unlike the DownUpOrder struct, it is not intended for direct serialization, and
|
||||||
|
/// is not generic.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AtomicDownUp {
|
pub struct AtomicDownUp {
|
||||||
down: AtomicU64,
|
down: AtomicU64,
|
||||||
@ -9,6 +19,7 @@ pub struct AtomicDownUp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AtomicDownUp {
|
impl AtomicDownUp {
|
||||||
|
/// Create a new `AtomicDownUp` with both values set to zero.
|
||||||
pub const fn zeroed() -> Self {
|
pub const fn zeroed() -> Self {
|
||||||
Self {
|
Self {
|
||||||
down: AtomicU64::new(0),
|
down: AtomicU64::new(0),
|
||||||
@ -16,11 +27,14 @@ impl AtomicDownUp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set both down and up to zero.
|
||||||
pub fn set_to_zero(&self) {
|
pub fn set_to_zero(&self) {
|
||||||
self.up.store(0, Relaxed);
|
self.up.store(0, Relaxed);
|
||||||
self.down.store(0, Relaxed);
|
self.down.store(0, Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a tuple of u64 values to the down and up values. The addition
|
||||||
|
/// is checked, and will not occur if it would result in an overflow.
|
||||||
pub fn checked_add_tuple(&self, n: (u64, u64)) {
|
pub fn checked_add_tuple(&self, n: (u64, u64)) {
|
||||||
let n0 = self.down.load(std::sync::atomic::Ordering::Relaxed);
|
let n0 = self.down.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
if let Some(n) = n0.checked_add(n.0) {
|
if let Some(n) = n0.checked_add(n.0) {
|
||||||
@ -33,6 +47,8 @@ impl AtomicDownUp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a DownUpOrder to the down and up values. The addition
|
||||||
|
/// is checked, and will not occur if it would result in an overflow.
|
||||||
pub fn checked_add(&self, n: DownUpOrder<u64>) {
|
pub fn checked_add(&self, n: DownUpOrder<u64>) {
|
||||||
let n0 = self.down.load(std::sync::atomic::Ordering::Relaxed);
|
let n0 = self.down.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
if let Some(n) = n0.checked_add(n.down) {
|
if let Some(n) = n0.checked_add(n.down) {
|
||||||
@ -45,22 +61,27 @@ impl AtomicDownUp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the down value.
|
||||||
pub fn get_down(&self) -> u64 {
|
pub fn get_down(&self) -> u64 {
|
||||||
self.down.load(Relaxed)
|
self.down.load(Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the up value.
|
||||||
pub fn get_up(&self) -> u64 {
|
pub fn get_up(&self) -> u64 {
|
||||||
self.up.load(Relaxed)
|
self.up.load(Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the down value.
|
||||||
pub fn set_down(&self, n: u64) {
|
pub fn set_down(&self, n: u64) {
|
||||||
self.down.store(n, Relaxed);
|
self.down.store(n, Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the up value.
|
||||||
pub fn set_up(&self, n: u64) {
|
pub fn set_up(&self, n: u64) {
|
||||||
self.up.store(n, Relaxed);
|
self.up.store(n, Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transform the AtomicDownUp into a `DownUpOrder<u64>`.
|
||||||
pub fn as_down_up(&self) -> DownUpOrder<u64> {
|
pub fn as_down_up(&self) -> DownUpOrder<u64> {
|
||||||
DownUpOrder::new(
|
DownUpOrder::new(
|
||||||
self.get_down(),
|
self.get_down(),
|
||||||
@ -68,3 +89,32 @@ impl AtomicDownUp {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_atomic_down_up() {
|
||||||
|
let adu = AtomicDownUp::zeroed();
|
||||||
|
assert_eq!(adu.get_down(), 0);
|
||||||
|
assert_eq!(adu.get_up(), 0);
|
||||||
|
|
||||||
|
adu.set_down(1);
|
||||||
|
adu.set_up(2);
|
||||||
|
assert_eq!(adu.get_down(), 1);
|
||||||
|
assert_eq!(adu.get_up(), 2);
|
||||||
|
|
||||||
|
adu.checked_add(DownUpOrder::new(1, 2));
|
||||||
|
assert_eq!(adu.get_down(), 2);
|
||||||
|
assert_eq!(adu.get_up(), 4);
|
||||||
|
|
||||||
|
adu.checked_add_tuple((1, 2));
|
||||||
|
assert_eq!(adu.get_down(), 3);
|
||||||
|
assert_eq!(adu.get_up(), 6);
|
||||||
|
|
||||||
|
adu.set_to_zero();
|
||||||
|
assert_eq!(adu.get_down(), 0);
|
||||||
|
assert_eq!(adu.get_up(), 0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user