[Lazarus] Better implementation of GetTickcount using clock_gettime

Luca Olivetti luca at wetron.es
Wed Apr 2 09:57:56 CEST 2014


El 02/04/14 09:47, Luca Olivetti ha escrit:
> El 02/04/14 09:08, Michael Van Canneyt ha escrit:
>>
>>
>> On Tue, 1 Apr 2014, Mattias Gaertner wrote:
>>
>>> On Tue, 01 Apr 2014 12:20:53 +0200
>>> Luca Olivetti <luca at wetron.es> wrote:
>>>
>>>> [...]
>>>> function GetTickCount64: QWord;
>>>> var
>>>>   tp: timespec;
>>>> begin
>>>>   clock_gettime(CLOCK_MONOTONIC, @tp);
>>>>   Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 1000000);
>>>> end;
>>>> [...]
>>>
>>> Thanks. GetTickCount64 now uses it on Linux.
>>
>> The implementation in Sysutils now does so too, and uses a fallback
>> using gettimeofday.
> 
> I checked the revision and it looks wrong: fpgettimeofday uses a
> TTimeVal (resolution microseconds), while clock_gettime uses TTimeSpec
> (resolution nanoseconds). A suitable (I think) fallback could be
> CLOCK_REALTIME, e.g.

Oops, the fallback after the {$ENDIF} in the second and third version
was supposed to call fpgettimeofday, but you get the idea

> 
> 
> var
>   ts:TTimeSpec;
> begin
> {$IFDEF HAVECLOCKGETTIME}
>   if clock_gettime(CLOCK_MONOTONIC, @ts)<0 then
> {$ENDIF}
>   clock_gettime(CLOCK_REALTIME, at ts);
>   Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 1000000);
> end;
> 
> The problem is that the clock_gettime function is only defined for linux
> (isn't it supposed to be available in any posix system?) so maybe:
> 
> var
>   tv:TTimeVal;
> {$IFDEF HAVECLOCKGETTIME}
>   ts:TTimeSpec;
> {$ENDIF}
> begin
> {$IFDEF HAVECLOCKGETTIME}
>   if clock_gettime(CLOCK_MONOTONIC, @ts)=0 then
>   begin
>     Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 1000000);
>     exit;
>   end;
> {$ENDIF}
>   clock_gettime(CLOCK_REALTIME, at tv);

    fpgettimeofday(@tv, nil);


>   Result := (Int64(tv.tv_sec) * 1000) + (tv.tv_usec div 1000);
> end;
> 
> 
> Btw, in theory CLOCK_MONOTONIC_RAW should be even better, though it's
> only available from linux 2.6.28
> 
> var
>   tv:TTimeVal;
> {$IFDEF HAVECLOCKGETTIME}
>   r:cint;
>   ts:TTimeSpec;
> {$ENDIF}
> begin
> {$IFDEF HAVECLOCKGETTIME}
>   r:=clock_gettime(CLOCK_MONOTONIC_RAW, @ts);
>   if r<0 then
>     r:=clock_gettime(CLOCK_MONOTONIC, @ts)=0;
>   if r=0 then
>   begin
>     Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 1000000);
>     exit;
>   end;
> {$ENDIF}
>   clock_gettime(CLOCK_REALTIME, at tv);

    fpgettimeofday(@tv, nil);


>   Result := (Int64(tv.tv_sec) * 1000) + (tv.tv_usec div 1000);
> end;
> 
> 
> and then there's CLOCK_MONOTONIC_COARSE......
> 
> 
> Bye
> 


-- 
Luca Olivetti
Wetron Automation Technology http://www.wetron.es
Tel. +34 935883004  Fax +34 935883007




More information about the Lazarus mailing list