#!/bin/bash
# core/timer - duration measuring support
set -e
lib_load 'sys/tool/bc'
######
# Internal Functions
timer_now() { date '+%s.%N'; }
timer_var_running() { echo "$1"; }
timer_var_start() { echo "${1}_start"; }
timer_var_final() { echo "${1}_final"; }
timer_var_marks() { echo "${1}_marks"; }
######
# Timer Mark Interface
timer_mark() {
min_args 1 "$@"
local var when
var=$(timer_var_marks "$1")
when=${2:-$(timer_now)}
[ "$when" ] || error "timer $1: unable to set mark"
eval "$var+=( $when )"
}
timer_mark_all() {
has_args 1 "$@"
local marksvar=$(timer_var_marks "$1")
eval "echo \"\${${marksvar}[*]}\""
}
timer_mark_count() {
has_args 1 "$@"
local marksvar
marksvar=$(timer_var_marks "$1")
eval "echo \$((\${#$marksvar[*]}))"
}
timer_mark_first() {
has_args 1 "$@"
local marksvar
marksvar=$(timer_var_marks "$1")
eval "echo \"\$$marksvar\""
}
timer_mark_get() {
has_args 2 "$@"
local marksvar
marksvar=$(timer_var_marks "$1")
eval "echo \"\${${marksvar}[$2]}\""
}
timer_mark_measure() {
has_args 3 "$@"
local name=$1
local idxstart=$2
local idxfinal=$3
local count
count=$(timer_mark_count "$name")
if ! [ $idxstart -lt $count -a $idxfinal -lt $count ]; then
local msg="cannot measure from $idxstart to $idxfinal"
error "timer $name: $msg with $count marks"
fi
local start final elapsed
start=$(timer_mark_get $name $idxstart)
final=$(timer_mark_get $name $idxfinal)
bc_gen_sub $final $start | bc_run
}
######
# Timer Lap Interface
timer_laps() {
has_args 1 "$@"
local count
count=$(timer_mark_count "$1")
if [ $count -gt 1 ]; then
echo $((count - 1))
else
echo 0
fi
}
timer_has_laps() {
has_args 1 "$@"
local laps=$(timer_laps "$1")
[ $laps -gt 0 ]
}
timer_lap_measure() {
has_args 3 "$@"
local name=$1
if ! timer_has_laps "$name"; then
warn "timer: $name: no laps recorded"
return
fi
timer_mark_measure "$2" "$3"
}
timer_lap_last() {
has_args 1 "$@"
timer_lap_measure "$1" -2 -1
}
######
# Timer Query
timer_exists() {
local -n running=$(timer_var_running "$1")
[ "$running" ]
}
timer_is_running() {
has_args 1 "$@"
local -n running=$(timer_var_running "$1")
[ "$running" ] && $running
}
timer_running() {
local -n running=$(timer_var_running "$1")
running=$2
}
######
# Timer Control
timer_start() {
has_args 1 "$@"
local name=$1
if timer_is_running "$name"; then
warn "$name: timer already running"
return
fi
timer_running true
local -n start=$(timer_var_start "$name")
start=$(timer_now)
timer_mark $name $start
}
timer_stop() {
has_args 1 "$@"
local name=$1
local -n final=$(timer_var_final "$name")
final=$(timer_now)
timer_mark $name $final
timer_running false
}
######
# Timer Reporting
timer_elapsed() {
timer_elapsed_hms "$@"
}
timer_elapsed_hms() {
local elapsed
elapsed=$(timer_elapsed_seconds "$@")
local sec=${elapsed%.*}
local nsec=${elapsed#*.}
local hrs=$((sec / 3600))
[ $hrs -gt 0 ] && echo "$hrs hours" || hrs=''
secs=$((secs % 3600))
local min=$((sec / 60))
[ "$hrs" -o $min -gt 0 ] && echo "${hrs:+, }$min minutes" || min=''
sec=$((sec % 60))
echo "${min:+, }$sec.$nsec seconds"
}
timer_elapsed_seconds() {
has_args 1 "$@"
echo "$(timer_mark_measure "$1" 0 -1)"
}
Generated on Tue Apr 25 21:20:18 PDT 2017 by mcsh i7 v0.18.0.