diff options
| author | wukong <wukong@longaeva> | 2025-11-22 00:02:20 -0800 |
|---|---|---|
| committer | wukong <wukong@longaeva> | 2025-11-22 00:02:20 -0800 |
| commit | e9d3488a9ef1a1b5bf8e75afc719b3cce68b9853 (patch) | |
| tree | 57e82d152261d445bdfc69b91d611d86236103a9 /ckcptime.awk | |
initial commit. ckt0.awk is launched from ckt0.sh with state stored in a shell variable.
Diffstat (limited to '')
| -rw-r--r-- | ckcptime.awk | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/ckcptime.awk b/ckcptime.awk new file mode 100644 index 0000000..4bc9539 --- /dev/null +++ b/ckcptime.awk @@ -0,0 +1,177 @@ +#!/usr/bin/env awk -f + + +function log10(n) { + + return log(n)/log(10.0) + +} + + +function merge_meas(val_est, unc_est, val_meas, unc_meas) { + + # add (meas - est) delta to the measurement uncertainty + # note: this works when tracking a constant value, + # the first derivative of a constant 'should' be zero + # unc_meas = sqrt(unc_meas^2.0 + (val_meas - val_est)^2.0) + + # Kalman filtering compares variances + unc_est = (0.5*unc_est)^2.0 + unc_meas = (0.5*unc_meas)^2.0 + + G_K = (unc_est)/((unc_est) + (unc_meas)) + val_est = val_est + G_K*(val_meas - val_est) + unc_est = (unc_est*unc_meas)/(unc_est + unc_meas) + + # convert unc_est back to same units as val_est + unc_est = 2.0*sqrt(unc_est) + + return sprintf(OFMT OFS OFMT ORS, val_est, unc_est) + +} + + +function sigfig(val, unc) { + + ordmag_val = log10(val) + ordmag_unc = log10(unc) + + sigfig_unc = sprintf("%.f", 6) + sigfig_val = sprintf("%.f", (ordmag_val - ordmag_unc + sigfig_unc)) + + ofmt_val = "%." sigfig_val "g" + ofmt_unc = "%." sigfig_unc "g" + + return sprintf(ofmt_val OFS ofmt_unc ORS, val, unc) + +} + + +function ck_boottime() { + + "sysctl kern.boottime" | getline t_kboot + close("sysctl kern.boottime") + sub("^.*\{", "", t_kboot) + sub("\}.*$", "", t_kboot) + split(t_kboot, t_kboot_arr, ",") + + for (i in t_kboot_arr) { + sub("^.*= ", "", t_kboot_arr[i]) + } + + t_kboot = sprintf(t_kboot_arr[1] "." t_kboot_arr[2]) + return t_kboot + +} + + +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(OFMT OFS "%s", t_sys_meas[1], cptime_cmd) + +} + + +function ck_uptime(t0_est, t0_unc) { + + t_sys_meas[1] = systime() + t_sys_meas[2] = 1.0 + + "uptime" | getline t_up_cmd + close("uptime") + + split(merge_meas(t_sys_meas[1], t_sys_meas[2], systime(), 1.0), t_sys_meas) + + # estimate (predict) uptime + t_up_est[1] = t_sys_meas[1] - t0_est + t_up_est[2] = t_sys_meas[2] + t0_unc + + # evaluate measured uptime + t_up_meas[1] = 0.0 + t_up_meas[2] = systime() + + 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) { + + # TODO: add cases for days, months, years, etc. + if (t_up_cmd_arr[i] ~ /day/) { + split(t_up_cmd_arr[i], days) + t_up_meas[1] += 86400.0*(days[1] + 0.0) + (t_up_meas[2] > 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) + t_up_meas[1] += 3600.0*(hrs[1] + 0.0) + (t_up_meas[2] > 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) + t_up_meas[1] += (60.0*(mins[1] + 0.0)) + (t_up_meas[2] > 60.0) ? t_up_meas[2] = 60.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] > 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] > 60.0) ? t_up_meas[2] = 60.0 : t_up_meas[2] += 0.0 + } + + } + + # merge predicted and measured uptimes + split(merge_meas(t_up_est[1], t_up_est[2], t_up_meas[1], t_up_meas[2]), t_up_est) + + # evaluate measured boot time, t0 + t_boot_meas[1] = t_sys_meas[1] - t_up_meas[1] + t_boot_meas[2] = t_sys_meas[2] + t_up_meas[2] + + # merge previous and updated boot time, t0 + split(merge_meas(t0_est, t0_unc, t_boot_meas[1], t_boot_meas[2]), t_boot_est) + + return sigfig(t_boot_est[1], t_boot_est[2]) + +} + + +BEGIN { + + OFMT="%.21g" + #print("_systime_", systime()) + #print("_boottime_", ck_boottime()) + printf("%s" ORS, ck_cptime()) + + # check ARGV for previous estimate + # if (ARGC > 0) { + # ARGV[1] ? t0_est[1] = ARGV[1] : t0_est[1] = 0.0 + # ARGV[2] ? t0_est[2] = ARGV[2] : t0_est[2] = systime() + # } + #print("t0_est = ", t0_est[1]) + #print("t_boot_unc = ", t0_est[2]) + + # wait (sleep) based on uncertainty + # print(60.0/t0_est[2]) + + # check uptime, update estimate + #print(ck_uptime(t0_est[1], t0_est[2])) + +} + |
