Skip to content
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 ringbuf trait on LogicalPort to allow for per-port metrics

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.

counters trait?

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