Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions drv/front-io-api/src/transceivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use core::sync::atomic::{AtomicU32, Ordering};

use crate::{Addr, FrontIOError, Reg};
use drv_fpga_api::{FpgaError, FpgaUserDesign, ReadOp, WriteOp};
use drv_transceivers_api::{ModuleStatus, NUM_PORTS};
use ringbuf::Count;
use transceiver_messages::ModuleId;
use userlib::UnwrapLite;
use zerocopy::{
Expand Down Expand Up @@ -134,6 +137,24 @@ impl LogicalPort {
PortLocation::from(*self)
}
}

/// Implement the `Count` trait on `LogicalPort` to allow for per-port metrics
impl Count for LogicalPort {
type Counters = [AtomicU32; NUM_PORTS as usize];

#[allow(clippy::declare_interior_mutable_const)]
const NEW_COUNTERS: Self::Counters =
[const { AtomicU32::new(0) }; NUM_PORTS as usize];

fn count(&self, counters: &Self::Counters) {
// This should never happen, but just in case.
let Some(ctr) = counters.get(self.0 as usize) else {
return;
};
ctr.fetch_add(1, Ordering::Relaxed);
}
}
Comment on lines +142 to +156

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is cute; I wonder if we might want the counters crate to have a macro or something for saying "yes, this looks like a u32, but it will always be in some range, so you can derive counters for it without having to worry"; elsewhere, I've tended to just use repr(N) enums for this sort of thing, like this thing:

/// PSU numbers represented as an enum. This is intended for use with
/// `counted_ringbuf!`, instead of representing PSU numbers as raw u8s, which
/// cannot derive `counters::Count` (and would have to generate a counter table
/// with 256 entries rather than just 6).
#[derive(Copy, Clone, Eq, PartialEq, counters::Count)]
#[repr(u8)]
enum Slot {
Psu0 = 0,
Psu1 = 1,
Psu2 = 2,
Psu3 = 3,
Psu4 = 4,
Psu5 = 5,
}

but that then requires some weirdish boilerplate for converting between the enum and integers if you also want to index arrays or whatever.

very much not a blocker for this PR, but I wonder if we might throw together a little newtype-integer-counter derive or something that works like this.


/// Represents a set of selected logical ports, i.e. a 32-bit bitmask
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct LogicalPortMask(pub u32);
Expand Down
Loading
Loading