Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.

Commit 776d9ee

Browse files
authored
Remove unnecessary Index impls (#22)
1 parent 38b9a29 commit 776d9ee

File tree

5 files changed

+19
-44
lines changed

5 files changed

+19
-44
lines changed

src/rings.rs

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ struct XskRing<T: 'static> {
163163
cached_consumed: u32,
164164
/// Total number of entries in the ring
165165
count: u32,
166+
/// Mask for indexing ops, since rings are required to be power of 2 this
167+
/// lets us get away with a simple `&` instead of `%`
168+
mask: usize,
166169
}
167170

168171
/// Creates a memory map for a ring
@@ -196,6 +199,7 @@ fn map_ring<T>(
196199
producer,
197200
consumer,
198201
count,
202+
mask: count as usize - 1,
199203
ring,
200204
cached_produced: 0,
201205
cached_consumed: 0,
@@ -210,8 +214,11 @@ struct XskProducer<T: 'static>(XskRing<T>);
210214

211215
impl<T> XskProducer<T> {
212216
#[inline]
213-
fn mask(&self) -> usize {
214-
self.0.count as usize - 1
217+
fn set(&mut self, i: usize, item: T) {
218+
// SAFETY: The mask ensures the index is always within range
219+
unsafe {
220+
*self.0.ring.get_unchecked_mut(i & self.0.mask) = item;
221+
}
215222
}
216223

217224
/// The equivalent of [`xsk_ring_prod__reserve`](https://docs.ebpf.io/ebpf-library/libxdp/functions/xsk_ring_prod__reserve/)
@@ -255,31 +262,14 @@ impl<T> XskProducer<T> {
255262
}
256263
}
257264

258-
impl<T> std::ops::Index<usize> for XskProducer<T> {
259-
type Output = T;
260-
261-
#[inline]
262-
fn index(&self, index: usize) -> &Self::Output {
263-
// SAFETY: each ring impl ensures the index is valid
264-
unsafe { self.0.ring.get_unchecked(index) }
265-
}
266-
}
267-
268-
impl<T> std::ops::IndexMut<usize> for XskProducer<T> {
269-
#[inline]
270-
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
271-
// SAFETY: each ring impl ensures the index is valid
272-
unsafe { self.0.ring.get_unchecked_mut(index) }
273-
}
274-
}
275-
276265
/// Used for rx and completion rings where userspace is the consumer
277266
struct XskConsumer<T: 'static>(XskRing<T>);
278267

279-
impl<T> XskConsumer<T> {
268+
impl<T: Copy> XskConsumer<T> {
280269
#[inline]
281-
fn mask(&self) -> usize {
282-
self.0.count as usize - 1
270+
fn get(&self, i: usize) -> T {
271+
// SAFETY: The mask ensures the index is always within range
272+
unsafe { *self.0.ring.get_unchecked(i & self.0.mask) }
283273
}
284274

285275
/// The equivalent of [`xsk_ring_cons__peek`](https://docs.ebpf.io/ebpf-library/libxdp/functions/xsk_ring_cons__peek/)
@@ -316,14 +306,3 @@ impl<T> XskConsumer<T> {
316306
self.0.consumer.fetch_add(nb, Ordering::Release);
317307
}
318308
}
319-
320-
impl<T> std::ops::Index<usize> for XskConsumer<T> {
321-
type Output = T;
322-
323-
#[inline]
324-
fn index(&self, index: usize) -> &Self::Output {
325-
// SAFETY: Since we force power of 2 the same as libxdp, we know
326-
// it will always be within bounds
327-
unsafe { self.0.ring.get_unchecked(index) }
328-
}
329-
}

src/rings/completion.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ impl CompletionRing {
4949
let (actual, idx) = self.ring.peek(requested as _);
5050

5151
if actual > 0 {
52-
let mask = self.ring.mask();
5352
for i in idx..idx + actual {
54-
let addr = self.ring[i & mask];
53+
// SAFETY: The mask ensures the index is always within range
54+
let addr = self.ring.get(i);
5555
umem.free_addr(addr);
5656
}
5757

@@ -74,9 +74,8 @@ impl CompletionRing {
7474
let (actual, idx) = self.ring.peek(requested as _);
7575

7676
if actual > 0 {
77-
let mask = self.ring.mask();
7877
for (ts, i) in timestamps.iter_mut().zip(idx..idx + actual) {
79-
let addr = self.ring[i & mask];
78+
let addr = self.ring.get(i);
8079
*ts = umem.free_get_timestamp(addr);
8180
}
8281

src/rings/fill.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,8 @@ impl FillRing {
6060
let (actual, idx) = self.ring.reserve(requested as _);
6161

6262
if actual > 0 {
63-
let mask = self.ring.mask();
6463
for i in idx..idx + actual {
65-
self.ring[i & mask] = available.pop_front().unwrap();
64+
self.ring.set(i, available.pop_front().unwrap());
6665
}
6766

6867
self.ring.submit(actual as _);

src/rings/rx.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ impl RxRing {
5757
let (actual, idx) = self.ring.peek(nb as _);
5858

5959
if actual > 0 {
60-
let mask = self.ring.mask();
6160
for i in idx..idx + actual {
62-
let desc = self.ring[i & mask];
61+
let desc = self.ring.get(i);
6362
packets.push_front(
6463
// SAFETY: The user is responsible for the lifetime of the
6564
// packets we are returning

src/rings/tx.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,12 @@ impl TxRing {
6565
let (actual, idx) = self.ring.reserve(requested as _);
6666

6767
if actual > 0 {
68-
let mask = self.ring.mask();
6968
for i in idx..idx + actual {
7069
let Some(packet) = packets.pop_back() else {
7170
unreachable!()
7271
};
7372

74-
self.ring[i & mask] = packet.into();
73+
self.ring.set(i, packet.into());
7574
}
7675

7776
self.ring.submit(actual as _);

0 commit comments

Comments
 (0)