4
0

queue.rs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. use core::{cell::UnsafeCell, marker::PhantomData, mem};
  2. use crate::{
  3. bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_QUEUE},
  4. helpers::{bpf_map_pop_elem, bpf_map_push_elem},
  5. maps::PinningType,
  6. };
  7. #[repr(transparent)]
  8. pub struct Queue<T> {
  9. def: UnsafeCell<bpf_map_def>,
  10. _t: PhantomData<T>,
  11. }
  12. unsafe impl<T: Sync> Sync for Queue<T> {}
  13. impl<T> Queue<T> {
  14. pub const fn with_max_entries(max_entries: u32, flags: u32) -> Queue<T> {
  15. Queue {
  16. def: UnsafeCell::new(bpf_map_def {
  17. type_: BPF_MAP_TYPE_QUEUE,
  18. key_size: 0,
  19. value_size: mem::size_of::<T>() as u32,
  20. max_entries,
  21. map_flags: flags,
  22. id: 0,
  23. pinning: PinningType::None as u32,
  24. }),
  25. _t: PhantomData,
  26. }
  27. }
  28. pub const fn pinned(max_entries: u32, flags: u32) -> Queue<T> {
  29. Queue {
  30. def: UnsafeCell::new(bpf_map_def {
  31. type_: BPF_MAP_TYPE_QUEUE,
  32. key_size: 0,
  33. value_size: mem::size_of::<T>() as u32,
  34. max_entries,
  35. map_flags: flags,
  36. id: 0,
  37. pinning: PinningType::ByName as u32,
  38. }),
  39. _t: PhantomData,
  40. }
  41. }
  42. pub fn push(&self, value: &T, flags: u64) -> Result<(), i64> {
  43. let ret = unsafe {
  44. bpf_map_push_elem(
  45. self.def.get() as *mut _,
  46. value as *const _ as *const _,
  47. flags,
  48. )
  49. };
  50. (ret == 0).then_some(()).ok_or(ret)
  51. }
  52. pub fn pop(&self) -> Option<T> {
  53. unsafe {
  54. let mut value = mem::MaybeUninit::uninit();
  55. let ret = bpf_map_pop_elem(self.def.get() as *mut _, value.as_mut_ptr() as *mut _);
  56. (ret == 0).then_some(value.assume_init())
  57. }
  58. }
  59. }