aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2020-03-29 18:23:51 +0200
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2020-03-29 18:23:51 +0200
commite7c3bf6047246a4612aa2c64ab38b3ea9ecf610c (patch)
treec9dd4ff135f5d57edd7e814b7b118222e69925c5
parentRestructuring and dependency version bump. (diff)
downloadwireguard-rs-e7c3bf6047246a4612aa2c64ab38b3ea9ecf610c.tar.xz
wireguard-rs-e7c3bf6047246a4612aa2c64ab38b3ea9ecf610c.zip
Experiment with locking performance.
-rw-r--r--src/wireguard/router/device.rs5
-rw-r--r--src/wireguard/router/mod.rs2
-rw-r--r--src/wireguard/router/mutex.rs91
-rw-r--r--src/wireguard/router/peer.rs14
-rw-r--r--src/wireguard/router/queue.rs3
-rw-r--r--src/wireguard/router/receive.rs2
-rw-r--r--src/wireguard/router/route.rs3
-rw-r--r--src/wireguard/router/send.rs5
-rw-r--r--src/wireguard/router/tests/bench.rs22
9 files changed, 126 insertions, 21 deletions
diff --git a/src/wireguard/router/device.rs b/src/wireguard/router/device.rs
index 7c90f22..0fec686 100644
--- a/src/wireguard/router/device.rs
+++ b/src/wireguard/router/device.rs
@@ -6,7 +6,10 @@ use std::thread;
use std::time::Instant;
use log;
-use spin::{Mutex, RwLock};
+
+// TESTING
+use super::mutex::*;
+
use zerocopy::LayoutVerified;
use super::anti_replay::AntiReplay;
diff --git a/src/wireguard/router/mod.rs b/src/wireguard/router/mod.rs
index 7ab291b..16e16b7 100644
--- a/src/wireguard/router/mod.rs
+++ b/src/wireguard/router/mod.rs
@@ -12,6 +12,8 @@ mod receive;
mod send;
mod worker;
+mod mutex;
+
#[cfg(test)]
mod tests;
diff --git a/src/wireguard/router/mutex.rs b/src/wireguard/router/mutex.rs
new file mode 100644
index 0000000..aaf0b5e
--- /dev/null
+++ b/src/wireguard/router/mutex.rs
@@ -0,0 +1,91 @@
+/*
+use std::sync::Mutex as StdMutex;
+use std::sync::MutexGuard;
+
+use std::sync::RwLock as StdRwLock;
+use std::sync::RwLockReadGuard;
+use std::sync::RwLockWriteGuard;
+
+pub struct Mutex<T> {
+ mutex: StdMutex<T>,
+}
+
+pub struct RwLock<T> {
+ rwlock: StdRwLock<T>,
+}
+
+impl<T> Mutex<T> {
+ pub fn new(v: T) -> Mutex<T> {
+ Mutex {
+ mutex: StdMutex::new(v),
+ }
+ }
+
+ pub fn lock(&self) -> MutexGuard<T> {
+ self.mutex.lock().unwrap()
+ }
+}
+
+impl<T> RwLock<T> {
+ pub fn new(v: T) -> RwLock<T> {
+ RwLock {
+ rwlock: StdRwLock::new(v),
+ }
+ }
+
+ pub fn read(&self) -> RwLockReadGuard<T> {
+ self.rwlock.read().unwrap()
+ }
+
+ pub fn write(&self) -> RwLockWriteGuard<T> {
+ self.rwlock.write().unwrap()
+ }
+}
+*/
+
+use spin::Mutex as StdMutex;
+use spin::MutexGuard;
+
+use spin::RwLock as StdRwLock;
+use spin::RwLockReadGuard;
+use spin::RwLockWriteGuard;
+
+pub struct Mutex<T> {
+ mutex: StdMutex<T>,
+}
+
+pub struct RwLock<T> {
+ rwlock: StdRwLock<T>,
+}
+
+impl<T> Mutex<T> {
+ pub fn new(v: T) -> Mutex<T> {
+ Mutex {
+ mutex: StdMutex::new(v),
+ }
+ }
+
+ pub fn lock(&self) -> MutexGuard<T> {
+ self.mutex.lock()
+ }
+
+ pub fn try_lock(&self) -> Option<MutexGuard<T>> {
+ self.mutex.try_lock()
+ }
+}
+
+impl<T> RwLock<T> {
+ pub fn new(v: T) -> RwLock<T> {
+ RwLock {
+ rwlock: StdRwLock::new(v),
+ }
+ }
+
+ pub fn read(&self) -> RwLockReadGuard<T> {
+ self.rwlock.read()
+ }
+
+ pub fn write(&self) -> RwLockWriteGuard<T> {
+ self.rwlock.write()
+ }
+}
diff --git a/src/wireguard/router/peer.rs b/src/wireguard/router/peer.rs
index 67d90d8..6ba9ad1 100644
--- a/src/wireguard/router/peer.rs
+++ b/src/wireguard/router/peer.rs
@@ -21,12 +21,14 @@ use core::sync::atomic::AtomicBool;
use alloc::sync::Arc;
+// TESTING
+use super::mutex::Mutex;
+
// TODO: consider no_std alternatives
use std::net::{IpAddr, SocketAddr};
use arraydeque::{ArrayDeque, Wrapping};
use log;
-use spin::Mutex;
pub struct KeyWheel {
next: Option<Arc<KeyPair>>, // next key state (unconfirmed)
@@ -111,7 +113,7 @@ impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> DecryptionSta
DecryptionState {
confirmed: AtomicBool::new(keypair.initiator),
keypair: keypair.clone(),
- protector: spin::Mutex::new(AntiReplay::new()),
+ protector: Mutex::new(AntiReplay::new()),
death: keypair.birth + REJECT_AFTER_TIME,
peer,
}
@@ -168,15 +170,15 @@ pub fn new_peer<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>>(
device,
inbound: Queue::new(),
outbound: Queue::new(),
- enc_key: spin::Mutex::new(None),
- endpoint: spin::Mutex::new(None),
- keys: spin::Mutex::new(KeyWheel {
+ enc_key: Mutex::new(None),
+ endpoint: Mutex::new(None),
+ keys: Mutex::new(KeyWheel {
next: None,
current: None,
previous: None,
retired: vec![],
}),
- staged_packets: spin::Mutex::new(ArrayDeque::new()),
+ staged_packets: Mutex::new(ArrayDeque::new()),
}),
}
};
diff --git a/src/wireguard/router/queue.rs b/src/wireguard/router/queue.rs
index d5d657a..22882fd 100644
--- a/src/wireguard/router/queue.rs
+++ b/src/wireguard/router/queue.rs
@@ -1,5 +1,6 @@
+use super::mutex::Mutex;
+
use arraydeque::ArrayDeque;
-use spin::Mutex;
use core::mem;
use core::sync::atomic::{AtomicUsize, Ordering};
diff --git a/src/wireguard/router/receive.rs b/src/wireguard/router/receive.rs
index 15eb8fb..863c973 100644
--- a/src/wireguard/router/receive.rs
+++ b/src/wireguard/router/receive.rs
@@ -6,11 +6,11 @@ use super::types::Callbacks;
use super::{REJECT_AFTER_MESSAGES, SIZE_TAG};
use super::super::{tun, udp, Endpoint};
+use super::mutex::Mutex;
use alloc::sync::Arc;
use core::sync::atomic::{AtomicBool, Ordering};
use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305};
-use spin::Mutex;
use zerocopy::{AsBytes, LayoutVerified};
struct Inner<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
diff --git a/src/wireguard/router/route.rs b/src/wireguard/router/route.rs
index a556010..4afe820 100644
--- a/src/wireguard/router/route.rs
+++ b/src/wireguard/router/route.rs
@@ -3,7 +3,8 @@ use super::ip::*;
// TODO: no_std alternatives
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
-use spin::RwLock;
+use super::mutex::RwLock;
+
use treebitmap::address::Address;
use treebitmap::IpLookupTable;
use zerocopy::LayoutVerified;
diff --git a/src/wireguard/router/send.rs b/src/wireguard/router/send.rs
index 7e14209..e14a401 100644
--- a/src/wireguard/router/send.rs
+++ b/src/wireguard/router/send.rs
@@ -11,9 +11,10 @@ use alloc::sync::Arc;
use core::sync::atomic::{AtomicBool, Ordering};
use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305};
-use spin::Mutex;
use zerocopy::{AsBytes, LayoutVerified};
+use super::mutex::Mutex;
+
struct Inner<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
ready: AtomicBool,
buffer: Mutex<Vec<u8>>,
@@ -127,7 +128,7 @@ impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> SequentialJob
// send to peer
let job = &self.0;
- let msg = job.buffer.lock();
+ let msg = job.buffer.try_lock().unwrap(); // never contested
let xmit = job.peer.send_raw(&msg[..]).is_ok();
// trigger callback (for timers)
diff --git a/src/wireguard/router/tests/bench.rs b/src/wireguard/router/tests/bench.rs
index f025dc9..b05f6a2 100644
--- a/src/wireguard/router/tests/bench.rs
+++ b/src/wireguard/router/tests/bench.rs
@@ -80,7 +80,7 @@ fn profiler_start(name: &str) {
#[bench]
fn bench_router_outbound(b: &mut Bencher) {
- // 10 GB transmission per iteration
+ // 1 GB transmission per iteration
const BYTES_PER_ITER: usize = 100 * 1024 * 1024 * 1024;
// inner payload of IPv4 packet is 1440 bytes
@@ -118,16 +118,20 @@ fn bench_router_outbound(b: &mut Bencher) {
#[cfg(feature = "profiler")]
profiler_start("outbound");
- // repeatedly transmit 10 GB
- b.iter(|| {
- opaque.reset();
- while opaque.sent() < BYTES_PER_ITER / packet.len() {
- router
- .send(msg.to_vec())
- .expect("failed to crypto-route packet");
- }
+ // repeatedly transmit 1 GB
+ let summary = b.bench(|bench| {
+ bench.iter(|| {
+ opaque.reset();
+ while opaque.sent() < BYTES_PER_ITER / packet.len() {
+ router
+ .send(msg.to_vec())
+ .expect("failed to crypto-route packet");
+ }
+ })
});
+ println!("{:?}", summary);
+
// stop profiler
#[cfg(feature = "profiler")]
profiler_stop();