#!/usr/bin/env awk -f function log10(n) { return log(n)/log(10.0) } function merge_meas(est_val, est_unc, meas_val, meas_unc) { # add sanity (staleness) check on previous estimate #z_est = (meas_val - est_val)/est_unc #z_meas = (meas_val - est_val)/meas_unc # Kalman filtering compares variances, # convert uncertainties to square units est_unc = (0.5*est_unc)^2.0 meas_unc = (0.5*meas_unc)^2.0 K = (est_unc)/((est_unc) + (meas_unc)) est_val = est_val + K*(meas_val - est_val) est_unc = (est_unc*meas_unc)/(est_unc + meas_unc) # convert uncertainties back to original units est_unc = 2.0*sqrt(est_unc) meas_unc = 2.0*sqrt(meas_unc) return sprintf(OFMT OFS OFMT ORS, est_val, est_unc) } function sigfig(val, unc) { omag_val = log10(val) omag_unc = log10(unc) omag_high = sqrt((omag_val)^2.0 + (omag_unc)^2.0) omag_low = ((omag_val)^-1.0 + (omag_unc)^-1.0)^-1.0 sfig_unc = sprintf("%.f", sqrt((omag_high - omag_low)^2.0 + 6.0^2.0)) sfig_val = sprintf("%.f", sqrt(sfig_unc^2.0 + 9.0^2.0)) ofmt_val = "%." sfig_val "g" ofmt_unc = "%." sfig_unc "g" return sprintf(ofmt_val OFS ofmt_unc, val, unc) } function unc_g(val) { # order of magnitude omag_val = log10(val) # trim punctuation from val sub("[eE].*$", "", val) gsub("[.+-]", "", val) omag_unc = sprintf("%d", omag_val - length(val) + 1.0) return sprintf("%g", 10.0^(omag_unc)) } function ck_cptime() { t_sys_meas[1] = systime() t_sys_meas[2] = 1.0 "sysctl kern.cp_time" | getline cptime_cmd close("sysctl kern.cp_time") split(merge_meas(t_sys_meas[1], t_sys_meas[2], systime(), 1.0), t_sys_meas) sub("^.*=", "", cptime_cmd) gsub(",", OFS, cptime_cmd) #split(cptime_cmd, cptime_arr, ",") return sprintf("%s", cptime_cmd) } function ck_time(unm) { if (unm ~ /FreeBSD/ || unm ~ /Linux/) { "date +%s.%N" | getline t close("date +%s.%N") } else { "date +%s" | getline t close("date +%s") } return t } function ck_uptime(unm) { # check uptime cmd "uptime" | getline t_up_cmd close("uptime") # evaluate measured uptime t_up_meas[1] = 0.0 t_up_meas[2] = ck_time(unm) sub("^[ ]*[0-9]:[0-9]*[ ]", "", t_up_cmd) sub("^.* up ", "", t_up_cmd) sub(", load.*$", "", t_up_cmd) split(t_up_cmd, t_up_cmd_arr, ",") for (i in t_up_cmd_arr) { if (t_up_cmd_arr[i] ~ /day/) { split(t_up_cmd_arr[i], days) (days[1] + 0.0) ? t_up_meas[1] += 86400.0*(days[1] + 0.0) : t_up_meas[1] += 0.0 (t_up_meas[2] + 0.0) > 86400.0 ? t_up_meas[2] = 86400.0 : t_up_meas[2] += 0.0 } if (t_up_cmd_arr[i] ~ /hr/) { split(t_up_cmd_arr[i], hrs) (hrs[1] + 0.0) ? t_up_meas[1] += 3600.0*(hrs[1] + 0.0) : t_up_meas[1] += 0.0 (t_up_meas[2] + 0.0) > 3600.0 ? t_up_meas[2] = 3600.0 : t_up_meas[2] += 0.0 } if (t_up_cmd_arr[i] ~ /min/) { split(t_up_cmd_arr[i], mins) (mins[1] + 0.0) ? t_up_meas[1] += 60.0*(mins[1] + 0.0) : t_up_meas[1] += 0.0 (t_up_meas[2] + 0.0) > 60.0 ? t_up_meas[2] = 60.0 : t_up_meas[2] += 0.0 } if (t_up_cmd_arr[i] ~ /sec/) { split(t_up_cmd_arr[i], sec) (sec[1] + 0.0) ? t_up_meas[1] += sec[1] : t_up_meas[1] += 0.0 (t_up_meas[2] + 0.0) > 1.0 ? t_up_meas[2] = 1.0 : t_up_meas[2] += 0.0 } if (t_up_cmd_arr[i] ~ /:/) { split(t_up_cmd_arr[i], hrs_min, ":") t_up_meas[1] += 3600.0*(hrs_min[1] + 0.0) (t_up_meas[2] + 0.0) > 3600.0 ? t_up_meas[2] = 3600.0 : t_up_meas[2] += 0.0 t_up_meas[1] += 60.0*(hrs_min[2] + 0.0) (t_up_meas[2] + 0.0) > 60.0 ? t_up_meas[2] = 60.0 : t_up_meas[2] += 0.0 } } if (uname ~ /FreeBSD/ || uname ~ /Linux/) { split(ck_proc_uptime(uname), t_pu_meas) t_pu_meas[2] = unc_g(t_pu_meas[1]) split(merge_meas(t_up_meas[1], t_up_meas[2], t_pu_meas[1], t_pu_meas[2]), t_up_meas) } return sigfig(t_up_meas[1], t_up_meas[2]) } function ck_proc_uptime(unm) { proc_file = "" if (unm ~ /FreeBSD/) { proc_file = "/compat/linux/proc/uptime" } if (unm ~ /Linux/) { proc_file = "/proc/uptime" } getline proc_uptime < proc_file close(proc_file) return proc_uptime } BEGIN { OFMT="%f" pi = 4.0*atan2(1.0, 1.0) c0 = 299792458 # m/sec "uname" | getline uname close("uname") #print("_systime_", systime()) #print("_boottime_", ck_boottime()) #print( uname, ck_cptime() ) ## check systime, check uptime, check systime again t_meas[1] = ck_time(uname) split(ck_uptime(uname), t_up_meas) t_meas[2] = ck_time(uname) ## convert to [val, unc] vector t_meas[2] -= t_meas[1] t_meas[1] += 0.5*t_meas[2] if ( t_meas[2] == 0.0 ) { t_meas[2] = unc_g(t_meas[1]) } t_meas_str = sigfig(t_meas[1], t_meas[2]) ## estimate dt #dt[1] = t_meas[1] - t_prev[1] #dt[2] = t_meas[2] + t_prev[2] print( t_meas_str, ck_cptime() ) }