This implements the special variable NANOSECONDS in Bash.
Rationale:
Bash on Cygwin has some terrible clock resolution for EPOCHREALTIME:
Numerous consecutive references to EPOCHREALTIME can all yield the same
number, thus rendering EPOCHREALTIME unusable for precise time-measurement.
Luckily, it turns out that CLOCK_MONOTONIC has a perfect nanosecond-
resolution there. With this new NANOSECONDS var, a script can have the
option to chose which clock will suite it best on different platforms.
As an added bonus, I have always wanted to have a raw clock reading,
so I don't have to worry about the overhead of removing decimal points
when doing math on some readings.
Patch (apply with `patch -p0'):
This implements the special variable NANOSECONDS in Bash.
Patch (apply with `patch -p0'):
--- variables.c
+++ ../bash-5.3-patched/variables.c 2025-05-20 07:33:03.893066500 -0500
@@ -234,6 +234,7 @@ static SHELL_VAR *get_subshell (SHELL_VA
static SHELL_VAR *get_epochseconds (SHELL_VAR *);
static SHELL_VAR *get_epochrealtime (SHELL_VAR *);
+static SHELL_VAR *get_nanoseconds (SHELL_VAR *);
static SHELL_VAR *get_bashpid (SHELL_VAR *);
@@ -1508,6 +1509,13 @@ get_epochrealtime (SHELL_VAR *var)
}
static SHELL_VAR *
+get_nanoseconds (SHELL_VAR *var) {
+ struct timespec ts;
+ clock_gettime (CLOCK_MONOTONIC, &ts); /* No fall-back, that is intended! */
+ return (set_int_value (var, (ts.tv_sec * 1000000000 + ts.tv_nsec), 0));
+}
+
+static SHELL_VAR *
get_bashpid (SHELL_VAR *var)
{
int pid;
@@ -1868,6 +1876,8 @@ initialize_dynamic_variables (void)
VSETATTR (v, att_regenerate);
INIT_DYNAMIC_VAR ("EPOCHREALTIME", (char *)NULL, get_epochrealtime,
null_assign);
VSETATTR (v, att_regenerate);
+ INIT_DYNAMIC_VAR ("NANOSECONDS", (char *)NULL, get_nanoseconds, null_assign);
+ VSETATTR (v, att_regenerate);
#if defined (HISTORY)
INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd,
(sh_var_assign_func_t *)NULL);
--
2.51.0