+  clock_gettime64=403;\r
+  {$endif}\r
+{$endif} //linux\r
+\r
+\r
+\r
+{$ifdef darwin} {mac OS X}\r
+  type\r
+    tmach_timebase_info = packed record\r
+      numer: cardinal;\r
+      denom: cardinal;\r
+    end;\r
+    pmach_timebase_info = ^tmach_timebase_info;\r
+\r
+    function mach_absolute_time: int64; cdecl; external;\r
+    function mach_timebase_info(info: pmach_timebase_info): integer; cdecl; external;\r
+\r
+  var\r
+    timebase_info: tmach_timebase_info;\r
+{$endif} //darwin\r
+\r
+\r
+function btime_gettime(clockid:integer;tp:pbtimespec):integer;\r
+var\r
+{$ifdef have_clock_gettime}\r
+  ts: ttimespec;\r
+{$endif}\r
+  tv: ttimeval;\r
+{$ifdef darwin}\r
+  nanos:int64;\r
+  nanosf:extended;\r
+{$endif}\r
+\r
+begin\r
+  result := -1; //error\r
+\r
+  {$ifdef darwin}\r
+  if (clockid = CLOCK_MONOTONIC) or (clockid = CLOCK_MONOTONIC_COARSE) then begin\r
+    if timebase_info.denom = 0 then begin\r
+      mach_timebase_info(@timebase_info);\r
+    end;\r
+    if (timebase_info.denom > 0) then begin\r
+      nanos := mach_absolute_time;\r
+      if (nanos > 0) then begin\r
+        result := 0; //indicate success\r
+        if (timebase_info.denom > 10) then begin\r
+          //on powerpc mac, numer and denom are large numbers such as 1000000000 and 33333335, and extended is available\r
+          nanosf := nanos;\r
+          nanosf := (nanosf * timebase_info.numer) / timebase_info.denom;\r
+          nanos := trunc(nanosf);\r
+        end else begin\r
+          //on intel mac, numer and denom are 1 and 1. on apple silicon they are typically 125 and 3, and extended is not available\r
+          nanos := nanos div timebase_info.denom;\r
+          nanos := nanos * timebase_info.numer;\r
+        end;\r
+        tp.tv_sec := nanos div 1000000000;\r
+        tp.tv_nsec := nanos mod 1000000000;\r
+        exit;\r
+      end;\r
+    end;\r
+  end;\r
+  {$endif} //darwin\r
+\r
+  if (coarse_nosupport_cached) then begin\r
+    if (clockid = CLOCK_REALTIME_COARSE) then clockid := CLOCK_REALTIME;\r
+    if (clockid = CLOCK_MONOTONIC_COARSE) then clockid := CLOCK_MONOTONIC;\r
+  end;\r
+\r
+  {$ifdef use_syscall_gettime64}\r
+  //don't do this for monotonic for performance reasons\r
+  //the clock_gettime call below has the potential to be handled by libc, and then it is faster\r
+  //also if it failed, don't call it again to avoid slowdown of doing two calls every time\r
+  if (not ((clockid = CLOCK_MONOTONIC) or (clockid = CLOCK_MONOTONIC_COARSE) or (clockid = CLOCK_BOOTTIME) or (clockid = CLOCK_UPTIME))) and (not gettime64_nosupport_cached) then begin\r
+    result := do_syscall(clock_gettime64,clockid,tsysparam(tp));\r
+\r
+    if ((clockid = CLOCK_REALTIME) or (clockid = CLOCK_REALTIME_COARSE)) and (result <> 0) then gettime64_nosupport_cached := true;\r
+\r
+    if (result = 0) then exit;\r
+  end;\r
+  {$endif}\r
+\r
+  {$ifdef have_clock_gettime}\r
+  result := clock_gettime(clockid, @ts);\r
+  if (result <> 0) then begin\r
+    //fallback\r
+    if (clockid = CLOCK_REALTIME_COARSE) then begin\r
+      coarse_nosupport_cached := true;\r
+      result := clock_gettime(CLOCK_REALTIME, @ts);\r
+    end else\r
+    if (clockid = CLOCK_MONOTONIC_COARSE) then begin\r
+      coarse_nosupport_cached := true;\r
+      result := clock_gettime(CLOCK_MONOTONIC, @ts);\r
+    end;\r
+  end;\r
+  if (result = 0) then begin\r
+    tp.tv_sec := ts.tv_sec;\r
+    tp.tv_nsec := ts.tv_nsec;\r