From c25a50a1f4677b3e08b32e804e9b3df4e3eccf9e Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov <9erthalion6@gmail.com> Date: Mon, 12 Aug 2024 12:41:18 +0200 Subject: [PATCH] Improve syscalls worker Remove unneeded thread spawning (this will produce more load), allow to run in a tight loop and to specify the syscall. --- src/lib.rs | 22 ++++++++++++++++++++++ src/worker/syscalls.rs | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9593b12..a9b8810 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ use core_affinity::CoreId; use serde::Deserialize; use std::fmt::Display; +use syscalls::{Sysno}; pub mod worker; @@ -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)] @@ -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 diff --git a/src/worker/syscalls.rs b/src/worker/syscalls.rs index 9290bc3..59515b1 100644 --- a/src/worker/syscalls.rs +++ b/src/worker/syscalls.rs @@ -1,4 +1,5 @@ use std::{fmt::Display, thread, time}; +use std::time::{Instant, Duration}; use core_affinity::CoreId; use log::{info, warn}; @@ -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(()) } } @@ -37,16 +38,41 @@ 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!(