+ result := i * 0.0000001;\r
+end;\r
+\r
+\r
+function unixtimefloat_coarse:float;\r
+begin\r
+ //don't do the coarse method if worse than about 16 ms. on win9x it may be only a 55 ms resolution\r
+ //but i have also seen it is less (like 1 ms)\r
+ //don't call measure_ticks_freq on NT because it is expensive and unnecessary\r
+ init_win_version;\r
+ if not win_isnt then begin\r
+ if not ticks_freq_known then measure_ticks_freq;\r
+ end;\r
+ if win_isnt or (ticks_freq < 0.017) then begin\r
+ result := unixtimefloat_systemtime;\r
+ exit;\r
+ end;\r
+\r
+ result := unixtimefloat;\r
+end;\r
+\r
+function monotimefloat_coarse:float;\r
+begin\r
+ init_win_version;\r
+ if not win_isnt then begin\r
+ if not ticks_freq_known then measure_ticks_freq;\r
+ end;\r
+ if win_isnt or (ticks_freq < 0.017) then begin\r
+ result := mmtimeint64 * 0.001;\r
+ exit;\r
+ end;\r
+ result := monotimefloat;\r
+end;\r
+\r
+\r
+//simulate gettimeofday on windows so one can always use gettimeofday if preferred\r
+function gettimeofday(var tv:ttimeval):integer;\r
+var\r
+ e:float;\r
+ i:int64;\r
+begin\r
+ result := -1;\r
+\r
+ if not btimenowin8 then begin\r
+ i := win8time_as_unix_100ns;\r
+ if (i > 0) then begin\r
+ tv.tv_sec := i div 10000000;\r
+ tv.tv_usec := (i mod 10000000) div 10;\r
+ result := 0;\r
+ exit;\r
+ end;\r
+ end;\r
+\r
+ e := unixtimefloat;\r
+ if (e > 0) then result := 0;\r
+ tv.tv_sec := trunc(e);\r
+ tv.tv_usec := trunc(frac(e)*1000000);\r
+end;\r
+\r
+\r
+function btime_gettime(clockid:integer;tp:pbtimespec):integer;\r
+var\r
+ f:float;\r
+ i:int64;\r
+\r
+{$ifdef cpu386}{$ifdef has_extended}{$define itotp_float}{$endif}{$endif}\r
+procedure i100ns_to_tp_and_success;\r
+{$ifdef itotp_float}\r
+var\r
+ f:float;\r
+{$endif}\r
+begin\r
+ //in 32 bits delphi, float is 10 times faster than int64 here (30 vs 300 ns for the conversion)\r
+ //and with extended available, there is no loss of precision\r
+\r
+ {$ifdef itotp_float}\r
+ f := i / 10000000.0;\r
+ tp.tv_sec := trunc(f);\r
+ tp.tv_nsec := round(frac(f) * 1000000000.0);\r
+ {$else}\r
+ tp.tv_sec := i div 10000000;\r
+ tp.tv_nsec := (i mod 10000000) * 100;\r
+ {$endif}\r
+\r
+ result := 0; //success\r
+end;\r
+\r
+procedure f_to_tp_and_success;\r
+begin\r
+ tp.tv_sec := trunc(f);\r
+ tp.tv_nsec := round(frac(f) * 1000000000.0);\r
+ result := 0; //success\r
+end;\r
+\r
+begin\r
+ result := -1; //error\r
+\r
+ case clockid of\r
+ CLOCK_REALTIME: begin\r
+ //implement this case directly for full precision even without extended floats\r
+ if not btimenowin8 then begin\r
+ i := win8time_as_unix_100ns;\r
+ if (i > 0) then begin\r
+ i100ns_to_tp_and_success;\r
+ exit;\r
+ end;\r
+ end;\r
+ f := unixtimefloat;\r
+ f_to_tp_and_success;\r
+ end;\r
+ CLOCK_MONOTONIC: begin\r
+ f := monotimefloat;\r
+ f_to_tp_and_success;\r
+ end;\r
+ CLOCK_REALTIME_COARSE: begin\r
+ f := unixtimefloat_coarse;\r
+ f_to_tp_and_success;\r
+ end;\r
+ CLOCK_MONOTONIC_COARSE: begin\r
+ f := monotimefloat_coarse;\r
+ f_to_tp_and_success;\r
+ end;\r
+ CLOCK_UPTIME: begin\r
+ i := unbiasedtime_100ns;\r
+ if (i > 0) then begin\r
+ i100ns_to_tp_and_success;\r
+ exit;\r
+ end;\r
+ f := qpctimefloat;\r
+ f_to_tp_and_success;\r
+ end;\r
+ end;\r