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

Reply via email to