From defafdf707c56830a66f3dfd7a1bdd47efd67fa3 Mon Sep 17 00:00:00 2001 From: David Peter Date: Tue, 22 Feb 2022 10:29:58 +0100 Subject: [PATCH] Refactor timer module --- src/benchmark/executor.rs | 1 - src/shell.rs | 5 ++--- src/timer/mod.rs | 22 ++-------------------- src/timer/unix_timer.rs | 23 +++++------------------ src/timer/wallclocktimer.rs | 16 +++------------- src/timer/windows_timer.rs | 24 ++++++------------------ 6 files changed, 18 insertions(+), 73 deletions(-) diff --git a/src/benchmark/executor.rs b/src/benchmark/executor.rs index 76b34c3..2af328b 100644 --- a/src/benchmark/executor.rs +++ b/src/benchmark/executor.rs @@ -5,7 +5,6 @@ use crate::options::{CmdFailureAction, CommandOutputPolicy, Options, OutputStyle use crate::output::progress_bar::get_progress_bar; use crate::shell::execute_and_time; use crate::timer::wallclocktimer::WallClockTimer; -use crate::timer::{TimerStart, TimerStop}; use crate::util::units::Second; use super::timing_result::TimingResult; diff --git a/src/shell.rs b/src/shell.rs index ed64e30..b5e1e85 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,7 +1,6 @@ use std::process::{ExitStatus, Stdio}; use crate::options::Shell; -use crate::timer::get_cpu_timer; use anyhow::{Context, Result}; @@ -30,7 +29,7 @@ pub fn execute_and_time( command: &str, shell: &Shell, ) -> Result { - let cpu_timer = get_cpu_timer(); + let cpu_timer = crate::timer::unix_timer::CPUTimer::start(); let status = shell .command() @@ -76,7 +75,7 @@ pub fn execute_and_time( .stderr(stderr) .spawn() .with_context(|| format!("Failed to run command '{}'", command))?; - let cpu_timer = get_cpu_timer(&child); + let cpu_timer = crate::timer::windows_timer::CPUTimer::start_for_process(&child); let status = child.wait()?; let (user_time, system_time) = cpu_timer.stop(); diff --git a/src/timer/mod.rs b/src/timer/mod.rs index 45378c8..fe6a178 100644 --- a/src/timer/mod.rs +++ b/src/timer/mod.rs @@ -1,30 +1,12 @@ -use std::process::Child; - use crate::util::units::Second; pub mod wallclocktimer; #[cfg(windows)] -mod windows_timer; -#[cfg(windows)] -pub use self::windows_timer::get_cpu_timer; +pub mod windows_timer; #[cfg(not(windows))] -mod unix_timer; -#[cfg(not(windows))] -pub use self::unix_timer::get_cpu_timer; - -/// Defines start functionality of a timer. -pub trait TimerStart { - fn start() -> Self; - fn start_for_process(process: &Child) -> Self; -} - -/// Defines stop functionality of a timer. -pub trait TimerStop { - type Result; - fn stop(&self) -> Self::Result; -} +pub mod unix_timer; #[derive(Debug, Copy, Clone)] pub struct CPUTimes { diff --git a/src/timer/unix_timer.rs b/src/timer/unix_timer.rs index ed9d39f..ae3b62c 100644 --- a/src/timer/unix_timer.rs +++ b/src/timer/unix_timer.rs @@ -1,35 +1,22 @@ #![cfg(not(windows))] use std::mem; -use std::process::Child; -use crate::timer::{CPUInterval, CPUTimes, TimerStart, TimerStop}; +use crate::timer::{CPUInterval, CPUTimes}; use crate::util::units::Second; -pub fn get_cpu_timer() -> Box> { - Box::new(CPUTimer::start()) -} - -struct CPUTimer { +pub struct CPUTimer { start_cpu: CPUTimes, } -impl TimerStart for CPUTimer { - fn start() -> Self { +impl CPUTimer { + pub fn start() -> Self { CPUTimer { start_cpu: get_cpu_times(), } } - fn start_for_process(_: &Child) -> Self { - Self::start() - } -} - -impl TimerStop for CPUTimer { - type Result = (Second, Second); - - fn stop(&self) -> Self::Result { + pub fn stop(&self) -> (Second, Second) { let end_cpu = get_cpu_times(); let cpu_interval = cpu_time_interval(&self.start_cpu, &end_cpu); (cpu_interval.user, cpu_interval.system) diff --git a/src/timer/wallclocktimer.rs b/src/timer/wallclocktimer.rs index 0f67f1b..7f01b36 100644 --- a/src/timer/wallclocktimer.rs +++ b/src/timer/wallclocktimer.rs @@ -1,29 +1,19 @@ -use std::process::Child; use std::time::Instant; -use crate::timer::{TimerStart, TimerStop}; use crate::util::units::Second; pub struct WallClockTimer { start: Instant, } -impl TimerStart for WallClockTimer { - fn start() -> WallClockTimer { +impl WallClockTimer { + pub fn start() -> WallClockTimer { WallClockTimer { start: Instant::now(), } } - fn start_for_process(_: &Child) -> Self { - Self::start() - } -} - -impl TimerStop for WallClockTimer { - type Result = Second; - - fn stop(&self) -> Second { + pub fn stop(&self) -> Second { let duration = self.start.elapsed(); duration.as_secs() as f64 + f64::from(duration.subsec_nanos()) * 1e-9 } diff --git a/src/timer/windows_timer.rs b/src/timer/windows_timer.rs index 10c3151..4e8bcf4 100644 --- a/src/timer/windows_timer.rs +++ b/src/timer/windows_timer.rs @@ -7,35 +7,23 @@ use std::process::Child; use winapi::um::processthreadsapi::GetProcessTimes; use winapi::um::winnt::HANDLE; -use crate::timer::{CPUTimes, TimerStart, TimerStop}; +use crate::timer::CPUTimes; use crate::util::units::Second; const HUNDRED_NS_PER_MS: i64 = 10; -pub fn get_cpu_timer(process: &Child) -> Box> { - Box::new(CPUTimer::start_for_process(process)) -} - -struct CPUTimer { +pub struct CPUTimer { handle: RawHandle, } -impl TimerStart for CPUTimer { - fn start() -> Self { - panic!() - } - - fn start_for_process(process: &Child) -> Self { +impl CPUTimer { + pub fn start_for_process(process: &Child) -> Self { CPUTimer { handle: process.as_raw_handle(), } } -} -impl TimerStop for CPUTimer { - type Result = (Second, Second); - - fn stop(&self) -> Self::Result { + pub fn stop(&self) -> (Second, Second) { let times = get_cpu_times(self.handle); ( times.user_usec as f64 * 1e-6, @@ -62,7 +50,7 @@ fn get_cpu_times(handle: RawHandle) -> CPUTimes { // GetProcessTimes will exit with non-zero if success as per: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683223(v=vs.85).aspx if res != 0 { // Extract times as laid out here: https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure - // Both user_time and kernel_time are spans that the proces spent in either. + // Both user_time and kernel_time are spans that the process spent in either. let user: i64 = (((user_time.dwHighDateTime as i64) << 32) + user_time.dwLowDateTime as i64) / HUNDRED_NS_PER_MS;