Skip to content

Commit

Permalink
Improve syscalls worker
Browse files Browse the repository at this point in the history
Remove unneeded thread spawning (this will produce more load), allow to
run in a tight loop and to specify the syscall.
  • Loading branch information
erthalion committed Aug 12, 2024
1 parent 73912ca commit d00073c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 8 deletions.
29 changes: 28 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core_affinity::CoreId;
use serde::Deserialize;
use std::fmt::Display;
use syscalls::Sysno;

pub mod worker;

Expand Down Expand Up @@ -42,6 +43,18 @@ fn default_duration() -> u64 {
0
}

fn default_syscalls_arrival_rate() -> f64 {
0.0
}

fn default_syscalls_tight_loop() -> bool {
false
}

fn default_syscalls_syscall_nr() -> u32 {
Sysno::getpid as u32
}

/// Workload specific configuration, contains one enum value for each
/// workload type.
#[derive(Debug, Copy, Clone, Deserialize)]
Expand Down Expand Up @@ -69,7 +82,16 @@ pub enum Workload {
/// How to invoke syscalls
Syscalls {
/// How often to invoke a syscall.
#[serde(default = "default_syscalls_arrival_rate")]
arrival_rate: f64,

/// Run in a tight loop
#[serde(default = "default_syscalls_tight_loop")]
tight_loop: bool,

/// Which syscall to trigger
#[serde(default = "default_syscalls_syscall_nr")]
syscall_nr: u32,
},

/// How to open network connections
Expand Down Expand Up @@ -295,7 +317,12 @@ mod tests {
..
} = config;
assert_eq!(restart_interval, 10);
if let Workload::Syscalls { arrival_rate } = workload {
if let Workload::Syscalls {
arrival_rate,
tight_loop,
syscall_nr,
} = workload
{
assert_eq!(arrival_rate, 10.0);
} else {
panic!("wrong workload type found");
Expand Down
44 changes: 37 additions & 7 deletions src/worker/syscalls.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::time::{Duration, Instant};
use std::{fmt::Display, thread, time};

use core_affinity::CoreId;
Expand All @@ -22,11 +23,11 @@ impl SyscallsWorker {
}
}

fn do_syscall(&self) -> std::io::Result<()> {
match unsafe { syscall!(Sysno::getpid) } {
fn do_syscall(&self, syscall: Sysno) -> std::io::Result<()> {
match unsafe { syscall!(syscall) } {
Ok(_) => Ok(()),
Err(err) => {
warn!("Syscall failed: {}", err);
info!("Syscall failed: {}", err);
Ok(())
}
}
Expand All @@ -37,16 +38,45 @@ impl Worker for SyscallsWorker {
fn run_payload(&self) -> Result<(), WorkerError> {
info!("{self}");

let Workload::Syscalls { arrival_rate } = self.workload.workload else {
let mut counter = 0;
let mut start = Instant::now();

let Workload::Syscalls {
arrival_rate,
tight_loop,
syscall_nr,
} = self.workload.workload
else {
unreachable!()
};

let syscall = Sysno::from(syscall_nr);
info!("Running syscall {syscall}");

loop {
let worker = *self;
thread::spawn(move || {
worker.do_syscall().unwrap();
});

if start.elapsed().as_secs() > 10 {
warn!(
"CPU {}, {}",
self.config.cpu.id,
counter / start.elapsed().as_secs()
);
start = Instant::now();
counter = 0;
}

counter += 1;
// Do the syscall directly, without spawning a thread (it would
// introduce too much overhead for a quick syscall).
worker.do_syscall(syscall).unwrap();

// If running in a tight loop, go to the next iteration
if tight_loop {
continue;
}

// Otherwise calculate waiting time
let interval: f64 =
thread_rng().sample(Exp::new(arrival_rate).unwrap());
info!(
Expand Down

0 comments on commit d00073c

Please sign in to comment.