Optimize event serialization with pre-allocated buffer (#2794)
* Optimize event serialization with pre-allocated buffer - Added event_buffer field to LlmpEventManager - Used to_slice instead of to_allocvec - Pre-allocated buffer size is 4KB Fixes #1082 * Fallback to to_allocvec in case of event_buffer overflow Also combined the shared logic between compressed & uncompressed event firing while keeping the same behavior * Made the initial event_buffer size to a const Also removed the unnecessary event_buffer.clear(), since we are already resizing it
This commit is contained in:
parent
930951827f
commit
8cd069cf3e
@ -45,6 +45,9 @@ use crate::{
|
|||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Default initial capacity of the event buffer - 4KB
|
||||||
|
const INITIAL_EVENT_BUFFER_SIZE: usize = 1024 * 4;
|
||||||
|
|
||||||
/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
|
/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
|
||||||
/// using low-level message passing, `llmp`.
|
/// using low-level message passing, `llmp`.
|
||||||
pub struct LlmpEventManager<EMH, S, SP>
|
pub struct LlmpEventManager<EMH, S, SP>
|
||||||
@ -75,6 +78,7 @@ where
|
|||||||
should_serialize_cnt: usize,
|
should_serialize_cnt: usize,
|
||||||
pub(crate) time_ref: Option<Handle<TimeObserver>>,
|
pub(crate) time_ref: Option<Handle<TimeObserver>>,
|
||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
|
event_buffer: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LlmpEventManager<(), NopState<NopInput>, NopShMemProvider> {
|
impl LlmpEventManager<(), NopState<NopInput>, NopShMemProvider> {
|
||||||
@ -165,6 +169,7 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
time_ref,
|
time_ref,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
custom_buf_handlers: vec![],
|
custom_buf_handlers: vec![],
|
||||||
|
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +204,7 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
time_ref,
|
time_ref,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
custom_buf_handlers: vec![],
|
custom_buf_handlers: vec![],
|
||||||
|
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,6 +239,7 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
time_ref,
|
time_ref,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
custom_buf_handlers: vec![],
|
custom_buf_handlers: vec![],
|
||||||
|
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,6 +272,7 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
time_ref,
|
time_ref,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
custom_buf_handlers: vec![],
|
custom_buf_handlers: vec![],
|
||||||
|
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,6 +417,7 @@ where
|
|||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
||||||
+ Evaluator<E, Self, <S::Corpus as Corpus>::Input, S>,
|
+ Evaluator<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
{
|
{
|
||||||
|
println!("Got event in client: {} from {:?}", event.name(), client_id);
|
||||||
if !self.hooks.pre_exec_all(state, client_id, &event)? {
|
if !self.hooks.pre_exec_all(state, client_id, &event)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -512,44 +521,56 @@ where
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
|
||||||
fn fire(
|
fn fire(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
event: Event<<Self::State as UsesInput>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let serialized = postcard::to_allocvec(&event)?;
|
#[cfg(feature = "llmp_compression")]
|
||||||
let flags = LLMP_FLAG_INITIALIZED;
|
let flags = LLMP_FLAG_INITIALIZED;
|
||||||
|
|
||||||
match self.compressor.maybe_compress(&serialized) {
|
self.event_buffer.resize(self.event_buffer.capacity(), 0);
|
||||||
Some(comp_buf) => {
|
|
||||||
self.llmp.send_buf_with_flags(
|
// Serialize the event, reallocating event_buffer if needed
|
||||||
LLMP_TAG_EVENT_TO_BOTH,
|
let written_len = match postcard::to_slice(&event, &mut self.event_buffer) {
|
||||||
flags | LLMP_FLAG_COMPRESSED,
|
Ok(written) => written.len(),
|
||||||
&comp_buf,
|
Err(postcard::Error::SerializeBufferFull) => {
|
||||||
)?;
|
let serialized = postcard::to_allocvec(&event)?;
|
||||||
|
self.event_buffer = serialized;
|
||||||
|
self.event_buffer.len()
|
||||||
}
|
}
|
||||||
None => {
|
Err(e) => return Err(Error::from(e)),
|
||||||
self.llmp.send_buf(LLMP_TAG_EVENT_TO_BOTH, &serialized)?;
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "llmp_compression")]
|
||||||
|
{
|
||||||
|
match self
|
||||||
|
.compressor
|
||||||
|
.maybe_compress(&self.event_buffer[..written_len])
|
||||||
|
{
|
||||||
|
Some(comp_buf) => {
|
||||||
|
self.llmp.send_buf_with_flags(
|
||||||
|
LLMP_TAG_EVENT_TO_BOTH,
|
||||||
|
flags | LLMP_FLAG_COMPRESSED,
|
||||||
|
&comp_buf,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.llmp
|
||||||
|
.send_buf(LLMP_TAG_EVENT_TO_BOTH, &self.event_buffer[..written_len])?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "llmp_compression"))]
|
||||||
|
{
|
||||||
|
self.llmp
|
||||||
|
.send_buf(LLMP_TAG_EVENT_TO_BOTH, &self.event_buffer[..written_len]);
|
||||||
|
}
|
||||||
|
|
||||||
self.last_sent = current_time();
|
self.last_sent = current_time();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "llmp_compression"))]
|
|
||||||
fn fire(
|
|
||||||
&mut self,
|
|
||||||
_state: &mut Self::State,
|
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let serialized = postcard::to_allocvec(&event)?;
|
|
||||||
self.llmp.send_buf(LLMP_TAG_EVENT_TO_BOTH, &serialized)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
||||||
where
|
where
|
||||||
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
|
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user