@@ -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
211215impl < 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
277266struct 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- }
0 commit comments