maps: move maps inside RefCells

pull/1/head
Alessandro Decina 4 years ago
parent 77fa7d857c
commit f7cdd2e059

@ -1,4 +1,7 @@
use std::collections::HashMap;
use std::{
cell::{Ref, RefCell, RefMut},
collections::HashMap,
};
use thiserror::Error;
@ -45,7 +48,7 @@ unsafe impl object::Pod for bpf_map_def {}
#[derive(Debug)]
pub struct Bpf {
maps: HashMap<String, Map>,
maps: HashMap<String, RefCell<Map>>,
programs: HashMap<String, Program>,
}
@ -91,18 +94,18 @@ impl Bpf {
Ok(Bpf {
maps: maps
.drain(..)
.map(|map| (map.obj.name.clone(), map))
.map(|map| (map.obj.name.clone(), RefCell::new(map)))
.collect(),
programs,
})
}
pub fn map(&self, name: &str) -> Option<&Map> {
self.maps.get(name)
pub fn map(&self, name: &str) -> Option<Ref<'_, Map>> {
self.maps.get(name).map(|cell| cell.borrow())
}
pub fn map_mut(&mut self, name: &str) -> Option<&mut Map> {
self.maps.get_mut(name)
pub fn map_mut(&self, name: &str) -> Option<RefMut<'_, Map>> {
self.maps.get(name).map(|cell| cell.borrow_mut())
}
pub fn program(&self, name: &str) -> Option<&Program> {

@ -1,4 +1,10 @@
use std::{convert::TryFrom, marker::PhantomData, mem};
use std::{
cell::{Ref, RefMut},
convert::TryFrom,
marker::PhantomData,
mem,
ops::{Deref, DerefMut},
};
use crate::{
generated::bpf_map_type::BPF_MAP_TYPE_HASH,
@ -10,15 +16,15 @@ use crate::{
Pod, RawFd,
};
pub struct HashMap<T: AsRef<Map>, K, V> {
pub struct HashMap<T: Deref<Target = Map>, K, V> {
inner: T,
_k: PhantomData<K>,
_v: PhantomData<V>,
}
impl<T: AsRef<Map>, K: Pod, V: Pod> HashMap<T, K, V> {
impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
pub fn new(map: T) -> Result<HashMap<T, K, V>, MapError> {
let inner = map.as_ref();
let inner = map.deref();
let map_type = inner.obj.def.map_type;
if map_type != BPF_MAP_TYPE_HASH {
return Err(MapError::InvalidMapType {
@ -45,7 +51,7 @@ impl<T: AsRef<Map>, K: Pod, V: Pod> HashMap<T, K, V> {
}
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<Option<V>, MapError> {
let fd = self.inner.as_ref().fd_or_err()?;
let fd = self.inner.deref().fd_or_err()?;
bpf_map_lookup_elem(fd, key, flags)
.map_err(|(code, io_error)| MapError::LookupElementFailed { code, io_error })
}
@ -59,31 +65,31 @@ impl<T: AsRef<Map>, K: Pod, V: Pod> HashMap<T, K, V> {
}
}
impl<T: AsRef<Map> + AsMut<Map>, K: Pod, V: Pod> HashMap<T, K, V> {
impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
pub fn insert(&mut self, key: K, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.as_ref().fd_or_err()?;
let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_update_elem(fd, &key, &value, flags)
.map_err(|(code, io_error)| MapError::UpdateElementFailed { code, io_error })?;
Ok(())
}
pub unsafe fn pop(&mut self, key: &K) -> Result<Option<V>, MapError> {
let fd = self.inner.as_ref().fd_or_err()?;
let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_lookup_and_delete_elem(fd, key)
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementFailed { code, io_error })
}
pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
let fd = self.inner.as_ref().fd_or_err()?;
let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_delete_elem(fd, key)
.map(|_| ())
.map_err(|(code, io_error)| MapError::DeleteElementFailed { code, io_error })
}
}
impl<T: AsRef<Map>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K, V> {
impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K, V> {
fn fd(&self) -> Result<RawFd, MapError> {
self.inner.as_ref().fd_or_err()
self.inner.deref().fd_or_err()
}
unsafe fn get(&self, key: &K) -> Result<Option<V>, MapError> {
@ -91,6 +97,22 @@ impl<T: AsRef<Map>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K, V> {
}
}
impl<'a, K: Pod, V: Pod> TryFrom<Ref<'a, Map>> for HashMap<Ref<'a, Map>, K, V> {
type Error = MapError;
fn try_from(inner: Ref<'a, Map>) -> Result<HashMap<Ref<'a, Map>, K, V>, MapError> {
HashMap::new(inner)
}
}
impl<'a, K: Pod, V: Pod> TryFrom<RefMut<'a, Map>> for HashMap<RefMut<'a, Map>, K, V> {
type Error = MapError;
fn try_from(inner: RefMut<'a, Map>) -> Result<HashMap<RefMut<'a, Map>, K, V>, MapError> {
HashMap::new(inner)
}
}
impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for HashMap<&'a Map, K, V> {
type Error = MapError;

@ -1,7 +1,10 @@
use std::{
cell::RefMut,
convert::TryFrom,
ffi::c_void,
fs, io, mem, ptr, slice,
fs, io, mem,
ops::DerefMut,
ptr, slice,
str::FromStr,
sync::atomic::{self, AtomicPtr, Ordering},
};
@ -277,18 +280,18 @@ pub enum PerfMapError {
},
}
pub struct PerfMap<'map> {
map: &'map Map,
pub struct PerfMap<T: DerefMut<Target = Map>> {
map: T,
cpu_fds: Vec<(u32, RawFd)>,
buffers: Vec<Option<PerfBuffer>>,
}
impl<'map> PerfMap<'map> {
impl<T: DerefMut<Target = Map>> PerfMap<T> {
pub fn new(
map: &'map Map,
map: T,
cpu_ids: Option<Vec<u32>>,
page_count: Option<usize>,
) -> Result<PerfMap<'map>, PerfMapError> {
) -> Result<PerfMap<T>, PerfMapError> {
let map_type = map.obj.def.map_type;
if map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY {
return Err(MapError::InvalidMapType {
@ -345,11 +348,19 @@ impl<'map> PerfMap<'map> {
}
}
impl<'inner> TryFrom<&'inner Map> for PerfMap<'inner> {
impl<'a> TryFrom<RefMut<'a, Map>> for PerfMap<RefMut<'a, Map>> {
type Error = PerfMapError;
fn try_from(inner: &'inner Map) -> Result<PerfMap<'inner>, PerfMapError> {
PerfMap::new(inner, None, None)
fn try_from(a: RefMut<'a, Map>) -> Result<PerfMap<RefMut<'a, Map>>, PerfMapError> {
PerfMap::new(a, None, None)
}
}
impl<'a> TryFrom<&'a mut Map> for PerfMap<&'a mut Map> {
type Error = PerfMapError;
fn try_from(a: &'a mut Map) -> Result<PerfMap<&'a mut Map>, PerfMapError> {
PerfMap::new(a, None, None)
}
}

Loading…
Cancel
Save