replace internal uses of gettimeofday with monotonic time where appropriate. make...
[lcore.git] / btime.pas
index 87801b5416e3abba52d62e3832d7a3c59dc92ae6..a3428e8546c6e39d0a52e1b2d92ee0e1d352df8e 100644 (file)
--- a/btime.pas
+++ b/btime.pas
@@ -36,6 +36,7 @@ var
   tickcount:integer;\r
   settimebias:tunixtimeint;\r
   performancecountfreq:extended;\r
+  btimenowin8:boolean;\r
 \r
 function irctimefloat:float;\r
 function irctimeint:tunixtimeint;\r
@@ -120,11 +121,10 @@ uses
     {$ifdef VER1_0}\r
       linux,\r
     {$else}\r
+      {$ifdef linux}linux,{$endif} //for clock_gettime\r
+      {$ifdef freebsd}freebsd,{$endif} //for clock_gettime\r
       baseunix,unix,unixutil,sockets, {unixutil and sockets needed by unixstuff.inc on some compiler versions}\r
     {$endif}\r
-    {$ifdef linux}\r
-      dl,\r
-    {$endif}\r
   {$else}\r
     windows,unitsettc,mmsystem,\r
   {$endif}\r
@@ -175,49 +175,37 @@ end;
 function unixtimefloat:float;\r
 var\r
   tv:ttimeval;\r
+  sec:tunixtimeint;\r
 begin\r
   gettimeofday(tv);\r
-  result := tv.tv_sec+(tv.tv_usec/1000000);\r
+  sec := tv.tv_sec;\r
+  {$ifndef cpu64}\r
+  if (sec < -1) then inc(sec,$100000000); //tv_sec is 32 bits. allow -1 for invalid result\r
+  {$endif}\r
+  result := sec+(tv.tv_usec/1000000);\r
 end;\r
 \r
-{$ifdef linux}\r
-  {$define monotimefloat_implemented}\r
-  const\r
-    CLOCK_MONOTONIC = 1;\r
-  type \r
-    ptimeval = ^ttimeval;\r
-    tclock_gettime = function(clk_id: integer; tp: ptimeval): integer; cdecl;\r
+{$ifdef linux}{$define have_clock_gettime}{$endif}\r
+{$ifdef freebsd}{$define have_clock_gettime}{$endif}\r
 \r
-  var\r
-    librt_handle:pointer;\r
-    librt_inited:boolean;\r
-    clock_gettime: tclock_gettime;\r
+{$ifdef have_clock_gettime}\r
+  {$define monotimefloat_implemented}\r
 \r
   function monotimefloat:float;\r
   var\r
-    ts: ttimeval;\r
+    ts: ttimespec;\r
   begin\r
-    if not librt_inited then begin\r
-      librt_inited := true;\r
-      clock_gettime := nil;\r
-      librt_handle := dlopen('librt.so', RTLD_LAZY);\r
-      if assigned(librt_handle) then begin\r
-        clock_gettime := dlsym(librt_handle, 'clock_gettime');\r
-      end;\r
-    end;\r
-    if assigned(clock_gettime) then begin\r
-      if clock_gettime(CLOCK_MONOTONIC, @ts) = 0 then begin\r
-        //note this really returns nanoseconds\r
-        result := ts.tv_sec + ts.tv_usec / 1000000000.0;\r
-        exit;\r
-      end;\r
+    if clock_gettime(CLOCK_MONOTONIC, @ts) = 0 then begin\r
+      //note this really returns nanoseconds\r
+      result := ts.tv_sec + ts.tv_nsec / 1000000000.0;\r
+      exit;\r
     end;\r
     //fallback\r
     result := unixtimefloat;\r
   end;\r
 \r
 \r
-{$endif} {linux}\r
+{$endif}\r
 \r
 {$ifdef darwin} {mac OS X}\r
 {$define monotimefloat_implemented}\r
@@ -262,9 +250,14 @@ end;
 function unixtimeint:tunixtimeint;\r
 var\r
   tv:ttimeval;\r
+  sec:tunixtimeint;\r
 begin\r
   gettimeofday(tv);\r
-  result := tv.tv_sec;\r
+  sec := tv.tv_sec;\r
+  {$ifndef cpu64}\r
+  if (sec < 0) then inc(sec,$100000000); //tv_sec is 32 bits\r
+  {$endif}\r
+  result := sec;\r
 end;\r
 \r
 {------------------------------ end of *nix/freepascal section}\r
@@ -598,10 +591,12 @@ const
 var\r
   f,g,h:float;\r
 begin\r
-  if not win8inited then initwin8;\r
-  if assigned(@GetSystemTimePreciseAsFileTime) then begin\r
-    result := unixtimefloat_win8;\r
-    exit;\r
+  if not btimenowin8 then begin\r
+    if not win8inited then initwin8;\r
+    if assigned(@GetSystemTimePreciseAsFileTime) then begin\r
+      result := unixtimefloat_win8;\r
+      exit;\r
+    end;  \r
   end;\r
 \r
   result := monotimefloat+timefloatbias;\r