ktd/state/
bandwidth.rs

1use std::sync::atomic::{AtomicI64, Ordering};
2
3/// Holds the current available _"bandwidth"_.
4///
5/// Strictly speaking it has no unit and its value can be set semi-arbitrarily.<br>
6/// In practice the unit chosen is the smallest amount that can be allocated by a table.
7static BANDWIDTH: AtomicI64 = AtomicI64::new(0);
8
9/// Sets the initial bandwidth as given by configuration.
10pub fn init(initial: u64) {
11    BANDWIDTH.store(initial as i64, Ordering::Relaxed);
12    log::debug!("initialized with {}", BANDWIDTH.load(Ordering::Relaxed));
13}
14
15/// Allocates _"bandwidth"_ for a table.
16///
17/// May return less than requested if there is not enough available.
18pub fn alloc(request: u64) -> u64 {
19    let request = request as i64;
20    let available = BANDWIDTH.fetch_sub(request, Ordering::Relaxed);
21    let proposed = available.min(request).max(0);
22    BANDWIDTH.fetch_add(request - proposed, Ordering::Relaxed);
23    log::debug!(
24        "requested {request}, alloc {proposed}, total after {}",
25        BANDWIDTH.load(Ordering::Relaxed)
26    );
27    proposed as u64
28}
29
30/// Frees _"bandwidth"_ previously allocated by a table.
31pub fn free(allocated: u64) {
32    BANDWIDTH.fetch_add(allocated as i64, Ordering::Relaxed);
33    log::debug!(
34        "freed {allocated}, total after {}",
35        BANDWIDTH.load(Ordering::Relaxed)
36    );
37}