memguar/wrappers/
advisor.rs1use std::convert::AsMut;
2use std::marker::PhantomData;
3
4use libc::{c_int, c_void, posix_madvise};
5
6use crate::wrappers::advisor::Advise::DontNeed;
7
8#[repr(transparent)]
24pub struct Adviser<C: AsMut<[T]>, T> {
25 pub buf: C,
26 item_type: PhantomData<T>,
27}
28
29impl<C: AsMut<[T]>, T> Adviser<C, T> {
30 pub fn new(buf: C) -> Self {
31 Self {
32 buf,
33 item_type: PhantomData,
34 }
35 }
36
37 pub fn syscall_advise(&mut self, advise: Advise) -> Result<(), AdviseError> {
41 let buf = self.buf.as_mut();
42 assert!(size_of_val(buf) > 0, "Zero size buffer");
43 let ptr = buf.as_mut_ptr() as *mut c_void;
44 let len = size_of_val(buf);
45 let result = unsafe {
46 posix_madvise(ptr, len, advise as c_int)
47 };
48
49 match result {
50 0 => Ok(()),
51 result => Err(AdviseError::from(result)),
52 }
53 }
54}
55
56impl<C: AsMut<[T]>, T> Drop for Adviser<C, T> {
57 fn drop(&mut self) {
58 self.syscall_advise(DontNeed)
59 .expect("Cant give advise while dropping")
60 }
61}
62#[repr(i32)]
64pub enum Advise {
65 WillNeed = 3,
66 DontNeed = 4,
67}
68#[derive(Debug)]
70pub enum AdviseError {
71 EFAULT,
72 EINVAL,
73 ENOMEM,
74 ENOSYS,
75 EUNIM(c_int),
76}
77
78impl From<c_int> for AdviseError {
79 fn from(err: c_int) -> Self {
80 match err {
81 12 => AdviseError::ENOMEM,
82 14 => AdviseError::EFAULT,
83 22 => AdviseError::EINVAL,
84 38 => AdviseError::ENOSYS,
85 _ => AdviseError::EUNIM(err),
86 }
87 }
88}