Skip to content

Commit

Permalink
modify RPC server to use arrayvec instead of hash table
Browse files Browse the repository at this point in the history
  • Loading branch information
hunhoffe committed Aug 3, 2023
1 parent 1917f4f commit a3f8060
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ edition = "2018"

[dependencies]
abomonation = { git="https://github.com/hunhoffe/abomonation.git", branch="no-std", default-features = false }
arrayvec = { version = "0.7.0", default-features = false }
core2 = { version = "0.3", default-features = false, features = [ "alloc" ] }
hashbrown = { version = "0.11", features = [ "nightly" ] }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
log = "0.4"
rawtime = "0.0.10"
Expand Down
1 change: 1 addition & 0 deletions lib/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extern crate std;

extern crate abomonation;
extern crate alloc;
extern crate arrayvec;
extern crate core2;
extern crate smoltcp;
extern crate vmxnet3;
Expand Down
26 changes: 18 additions & 8 deletions lib/rpc/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use alloc::boxed::Box;
use hashbrown::HashMap;
use arrayvec::ArrayVec;
use log::debug;

use crate::rpc::*;
Expand All @@ -14,9 +14,11 @@ pub type RPCHandler = fn(hdr: &mut RPCHeader, payload: &mut [u8]) -> Result<(),
/// RPC Client registration function
pub type RegistrationHandler = fn(hdr: &mut RPCHeader, payload: &mut [u8]) -> Result<(), RPCError>;

const MAX_RPC_TYPE: usize = 256;

pub struct Server<'a> {
transport: Box<dyn Transport + Send + Sync + 'a>,
handlers: HashMap<RPCType, &'a RPCHandler>,
handlers: ArrayVec<Option<&'a RPCHandler>, MAX_RPC_TYPE>,
hdr: RPCHeader,
data: [u8; 8192],
}
Expand All @@ -26,10 +28,14 @@ impl<'t, 'a> Server<'a> {
where
't: 'a,
{
let mut handlers = ArrayVec::new();
for _i in 0..MAX_RPC_TYPE {
handlers.push(None);
}
// Initialize the server struct
Server {
transport,
handlers: HashMap::new(),
handlers,
hdr: RPCHeader::default(),
data: [0u8; 8192],
}
Expand All @@ -40,10 +46,11 @@ impl<'t, 'a> Server<'a> {
where
'c: 'a,
{
if self.handlers.contains_key(&rpc_id) {
return Err(RPCError::DuplicateRPCType);
assert!((rpc_id as usize) < MAX_RPC_TYPE);
match self.handlers[rpc_id as usize] {
Some(_) => return Err(RPCError::DuplicateRPCType),
None => self.handlers[rpc_id as usize] = Some(handler),
}
self.handlers.insert(rpc_id, handler);
Ok(())
}

Expand Down Expand Up @@ -71,7 +78,7 @@ impl<'t, 'a> Server<'a> {
/// Handle 1 RPC per client
pub fn handle(&mut self) -> Result<(), RPCError> {
let rpc_id = self.receive()?;
match self.handlers.get(&rpc_id) {
match self.handlers[rpc_id as usize] {
Some(func) => {
func(&mut self.hdr, &mut self.data)?;
self.reply()?
Expand All @@ -86,7 +93,7 @@ impl<'t, 'a> Server<'a> {
/// Try to handle 1 RPC per client, if data is available (non-blocking if RPCs not available)
pub fn try_handle(&mut self) -> Result<bool, RPCError> {
match self.try_receive()? {
Some(rpc_id) => match self.handlers.get(&rpc_id) {
Some(rpc_id) => match self.handlers[rpc_id as usize] {
Some(func) => {
func(&mut self.hdr, &mut self.data)?;
self.reply()?;
Expand All @@ -109,6 +116,7 @@ impl<'t, 'a> Server<'a> {
}

/// receives next RPC call with RPC ID
#[inline(always)]
fn receive(&mut self) -> Result<RPCType, RPCError> {
// Receive request header
self.transport
Expand All @@ -117,6 +125,7 @@ impl<'t, 'a> Server<'a> {
}

/// receives next RPC call with RPC ID
#[inline(always)]
fn try_receive(&mut self) -> Result<Option<RPCType>, RPCError> {
// Receive request header
if !self
Expand All @@ -130,6 +139,7 @@ impl<'t, 'a> Server<'a> {
}

/// Replies an RPC call with results
#[inline(always)]
fn reply(&mut self) -> Result<(), RPCError> {
self.transport
.send_msg(&self.hdr, &[&self.data[..self.hdr.msg_len as usize]])
Expand Down

0 comments on commit a3f8060

Please sign in to comment.