Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 2014-04-02 08:08, Michael Van Canneyt wrote: > On Tue, 1 Apr 2014, Mattias Gaertner wrote: >> Thanks. GetTickCount64 now uses it on Linux. > > The implementation in Sysutils now does so too, and uses a fallback using > gettimeofday. Thanks, I'll update EpikTimer to simply use that for 2.7.1 and later. BTW: EpikTimer has been using CLOCK_MONOTONIC for 2+ years already - as a fallback for 64-bit non-Windows systems. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, Apr 02, 2014 at 03:11:32PM +0200, Luca Olivetti wrote: > > I don't see _RAW and _COARSE anywhere in the mentioned opengroup link. > > Keep in mind this is UNIX gettickcount, not linux gettickcount. > > Correct, but the function clock_gettime is currently only defined for > Linux (at least I grepped the sources for fpc 2.6.4 and only found it > there). Still, I think this heavy OS dependent code and ifdeffing is not good. gettickcount should be removed from unix/ to something OS specific. At best one $if to list the OSes that use the generic way that can stay -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 02 Apr 2014 16:54:18 +0200 zeljko wrote: > >[...] > Ok, but what about NTP and adjtime() ? For small differences NTP uses incremental adjustments. The clock "ticks" a bit slower or faster until the kernel clock is in sync with the time server. Applications do not notice this, unless they compare with other time sources. Keep in mind that this is about milliseconds since start, not about country time or date. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 04/02/2014 03:29 PM, Mattias Gaertner wrote: On Wed, 02 Apr 2014 15:12:09 +0200 zeljko wrote: [...] On Wed, 02 Apr 2014 14:01:26 +0200 zeljko wrote: [...] clock change due to the daylight [...] See for example here: http://man7.org/linux/man-pages/man2/clock_gettime.2.html Do we read same man page ? Yes. Daylight changes are "discontinuous jumps", so CLOCK_MONOTONIC is not affected by it. Ok, but what about NTP and adjtime() ? z. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
El 02/04/14 14:29, Marco van de Voort ha escrit: > On Wed, Apr 02, 2014 at 01:19:39PM +0200, Luca Olivetti wrote: >>> CLOCK_MONOTONIC_RAW would better emulate the WinAPI >>> function GetTickCount. >> >> Well, yes, isn't that the function we're trying to emulate? >> >> (note that I personally don't need the precision, for me >> CLOCK_MONOTONIC_COARSE would probably be more than enough). > > I don't see _RAW and _COARSE anywhere in the mentioned opengroup link. > Keep in mind this is UNIX gettickcount, not linux gettickcount. Correct, but the function clock_gettime is currently only defined for Linux (at least I grepped the sources for fpc 2.6.4 and only found it there). Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 02 Apr 2014 15:12:09 +0200 zeljko wrote: >[...] > > On Wed, 02 Apr 2014 14:01:26 +0200 > > zeljko wrote: >[...] > clock change due to the daylight >[...] > > See for example here: > > http://man7.org/linux/man-pages/man2/clock_gettime.2.html > > Do we read same man page ? Yes. Daylight changes are "discontinuous jumps", so CLOCK_MONOTONIC is not affected by it. > CLOCK_MONOTONIC >Clock that cannot be set and represents monotonic time >since some unspecified starting point. This clock is >not affected by discontinuous jumps in the system time >(e.g., if the system administrator manually changes the >clock), *but is affected by the incremental adjustments >performed by adjtime(3) and NTP*. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
El 02/04/14 14:28, Mattias Gaertner ha escrit: > Sigh. Again: CLOCK_MONOTONIC is monotonic. It does not go > backwards and especially it does not apply timezone, daylight or user > time changes. It only fixes shortcomings of the machine counters. It's not supposed to go backward, but in some versions of the kernel it appears that it did: http://stackoverflow.com/questions/3657289/linux-clock-gettimeclock-monotonic-strange-non-monotonic-behavior See also http://stackoverflow.com/questions/14270300/what-is-the-difference-between-clock-monotonic-clock-monotonic-raw I also read (I think on stackoverflow but I cannot find the page right now), that one doesn't take into account the time during a suspension while the other does (I don't remember which is which) and that's an important difference depending on the application. Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 04/02/2014 02:28 PM, Mattias Gaertner wrote: On Wed, 02 Apr 2014 14:01:26 +0200 zeljko wrote: [...] My guess is that there no need to speculate what most programs need but what is more precise or better to say what is correct. They measure different things. The precision depends on what you expect. IMO CLOCK_MONOTONIC is affected by eg. ntp/adjtime() so result of GetTickCount() is not correct in all cases. Imagine daemon service which relies on GetTickCount and then clock change due to the daylight via Sigh. Again: CLOCK_MONOTONIC is monotonic. It does not go backwards and especially it does not apply timezone, daylight or user time changes. It only fixes shortcomings of the machine counters. See for example here: http://man7.org/linux/man-pages/man2/clock_gettime.2.html Do we read same man page ? CLOCK_MONOTONIC Clock that cannot be set and represents monotonic time since some unspecified starting point. This clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), *but is affected by the incremental adjustments performed by adjtime(3) and NTP*. CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific) Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that *is not subject to NTP adjustments or the incremental adjustments performed by adjtime(3)*. zeljko -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 2 Apr 2014, zeljko wrote: On 04/02/2014 01:10 PM, Mattias Gaertner wrote: On Wed, 02 Apr 2014 13:45:08 +0300 Anton Kavalenka wrote: [...] Yes - CLOCK_MONOTONICC_RAW is prefreable, because general GetTickCount() is number of millisecond ticks since system startup. It cannot be adjusted by time services, it just grows up every 1 msec. Ant typical GetTickCount() usage - find a difference between subsequent values. It would be amazing when difference gets negative. The NTP changes in CLOCK_MONOTONIC only accelerates or slows it down. It tries to fix the ticks for e.g. busy systems or VMs. It is still monotonic. CLOCK_MONOTONIC_RAW would better emulate the WinAPI function GetTickCount. I guess most programs need CLOCK_MONOTONIC. My guess is that there no need to speculate what most programs need but what is more precise or better to say what is correct. IMO CLOCK_MONOTONIC is affected by eg. ntp/adjtime() so result of GetTickCount() is not correct in all cases. Imagine daemon service which relies on GetTickCount and then clock change due to the daylight via ntp (eg. ATicks := GetTickCount , and after function "if GetTickCount - ATicks > X THEN sendalarm_email_to_admin_because_this_job_takes_too_much_time". Maybe I'm wrong, but we should set CLOCK_MONOTONIC_RAW instead of CLOCK_MONOTONIC for linux targets if kernel version matches minimum for CLOCK_MONOTONIC_RAW (same thing should be done in fpc - Michael already commited CLOCK_MONOTONIC afair). Looking at the documentation of GetTickCount(64), I'd say that the _RAW function is the better one. So we can do a get with CLOCK_MONOTONIC_RAW, if it returns EINVAL we retry with CLOCK_MONOTONIC. And if that fails, we fall back to gettimeofday. I see no reason why it cannot be changed like this. Main point is that it is transparant to the user. Michae -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, Apr 02, 2014 at 02:29:00PM +0200, Marco van de Voort wrote: > I don't see _RAW and _COARSE anywhere in the mentioned opengroup link. > Keep in mind this is UNIX gettickcount, not linux gettickcount. Seems freebsd (7 in this case) also has a load of options, also further MONOTONIC ones. _PRECISE and FAST. Seems on FreeBSD UPTIME is the way to go. These are also monotonic, and like WIndows gettickcount since boot. /* These macros are also in sys/time.h. */ #if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 #define CLOCK_REALTIME 0 #ifdef __BSD_VISIBLE #define CLOCK_VIRTUAL 1 #define CLOCK_PROF 2 #endif #define CLOCK_MONOTONIC 4 #define CLOCK_UPTIME5 /* FreeBSD-specific. */ #define CLOCK_UPTIME_PRECISE7 /* FreeBSD-specific. */ #define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */ #define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */ #define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */ #define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */ #define CLOCK_MONOTONIC_FAST12 /* FreeBSD-specific. */ #define CLOCK_SECOND13 /* FreeBSD-specific. */ #define CLOCK_THREAD_CPUTIME_ID 14 #endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */ -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 02 Apr 2014 14:01:26 +0200 zeljko wrote: >[...] > My guess is that there no need to speculate what most programs need but > what is more precise or better to say what is correct. They measure different things. The precision depends on what you expect. > IMO CLOCK_MONOTONIC is affected by eg. ntp/adjtime() so result of > GetTickCount() is not correct in all cases. > Imagine daemon service which relies on GetTickCount and then clock > change due to the daylight via Sigh. Again: CLOCK_MONOTONIC is monotonic. It does not go backwards and especially it does not apply timezone, daylight or user time changes. It only fixes shortcomings of the machine counters. See for example here: http://man7.org/linux/man-pages/man2/clock_gettime.2.html Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, Apr 02, 2014 at 01:19:39PM +0200, Luca Olivetti wrote: > > CLOCK_MONOTONIC_RAW would better emulate the WinAPI > > function GetTickCount. > > Well, yes, isn't that the function we're trying to emulate? > > (note that I personally don't need the precision, for me > CLOCK_MONOTONIC_COARSE would probably be more than enough). I don't see _RAW and _COARSE anywhere in the mentioned opengroup link. Keep in mind this is UNIX gettickcount, not linux gettickcount. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
El 02/04/14 13:10, Mattias Gaertner ha escrit: > CLOCK_MONOTONIC_RAW would better emulate the WinAPI > function GetTickCount. Well, yes, isn't that the function we're trying to emulate? (note that I personally don't need the precision, for me CLOCK_MONOTONIC_COARSE would probably be more than enough). Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 02 Apr 2014 13:45:08 +0300 Anton Kavalenka wrote: >[...] > Yes - CLOCK_MONOTONICC_RAW is prefreable, because general GetTickCount() > is number of millisecond ticks since system startup. It cannot be > adjusted by time services, it just grows up every 1 msec. > Ant typical GetTickCount() usage - find a difference between subsequent > values. > It would be amazing when difference gets negative. The NTP changes in CLOCK_MONOTONIC only accelerates or slows it down. It tries to fix the ticks for e.g. busy systems or VMs. It is still monotonic. CLOCK_MONOTONIC_RAW would better emulate the WinAPI function GetTickCount. I guess most programs need CLOCK_MONOTONIC. OTOH if you need precision you should not use GetTickCount, so the discussion is somewhat pointless. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 04/02/2014 01:10 PM, Mattias Gaertner wrote: On Wed, 02 Apr 2014 13:45:08 +0300 Anton Kavalenka wrote: [...] Yes - CLOCK_MONOTONICC_RAW is prefreable, because general GetTickCount() is number of millisecond ticks since system startup. It cannot be adjusted by time services, it just grows up every 1 msec. Ant typical GetTickCount() usage - find a difference between subsequent values. It would be amazing when difference gets negative. The NTP changes in CLOCK_MONOTONIC only accelerates or slows it down. It tries to fix the ticks for e.g. busy systems or VMs. It is still monotonic. CLOCK_MONOTONIC_RAW would better emulate the WinAPI function GetTickCount. I guess most programs need CLOCK_MONOTONIC. My guess is that there no need to speculate what most programs need but what is more precise or better to say what is correct. IMO CLOCK_MONOTONIC is affected by eg. ntp/adjtime() so result of GetTickCount() is not correct in all cases. Imagine daemon service which relies on GetTickCount and then clock change due to the daylight via ntp (eg. ATicks := GetTickCount , and after function "if GetTickCount - ATicks > X THEN sendalarm_email_to_admin_because_this_job_takes_too_much_time". Maybe I'm wrong, but we should set CLOCK_MONOTONIC_RAW instead of CLOCK_MONOTONIC for linux targets if kernel version matches minimum for CLOCK_MONOTONIC_RAW (same thing should be done in fpc - Michael already commited CLOCK_MONOTONIC afair). z. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 02 Apr 2014 13:19:39 +0200 Luca Olivetti wrote: > El 02/04/14 13:10, Mattias Gaertner ha escrit: > > > CLOCK_MONOTONIC_RAW would better emulate the WinAPI > > function GetTickCount. > > Well, yes, isn't that the function we're trying to emulate? I meant: it would be nearer to the shortcomings of the WinAPI functions. I guess there are not many programs which need the system ticks. I guess the majority need the milliseconds. > (note that I personally don't need the precision, for me > CLOCK_MONOTONIC_COARSE would probably be more than enough). Yes. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 02.04.2014 11:53, zeljko wrote: On 04/02/2014 10:01 AM, Mattias Gaertner wrote: On Wed, 02 Apr 2014 09:47:45 +0200 Luca Olivetti wrote: [...] Btw, in theory CLOCK_MONOTONIC_RAW should be even better, though it's only available from linux 2.6.28 CLOCK_MONOTONIC_RAW lacks the fixes by NTP. That's not good for Now(), but it's perfect solution for getTickCount(). GetTickCount() should not be aware of ntp or adjtime() changes - so in that case CLOCK_MONOTONIC_RAW is the only correct solution. z. Yes - CLOCK_MONOTONICC_RAW is prefreable, because general GetTickCount() is number of millisecond ticks since system startup. It cannot be adjusted by time services, it just grows up every 1 msec. Ant typical GetTickCount() usage - find a difference between subsequent values. It would be amazing when difference gets negative. regards, Anton -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 04/02/2014 10:01 AM, Mattias Gaertner wrote: On Wed, 02 Apr 2014 09:47:45 +0200 Luca Olivetti wrote: [...] Btw, in theory CLOCK_MONOTONIC_RAW should be even better, though it's only available from linux 2.6.28 CLOCK_MONOTONIC_RAW lacks the fixes by NTP. That's not good for Now(), but it's perfect solution for getTickCount(). GetTickCount() should not be aware of ntp or adjtime() changes - so in that case CLOCK_MONOTONIC_RAW is the only correct solution. z. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 2 Apr 2014, Luca Olivetti wrote: 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 wrote: [...] function GetTickCount64: QWord; var tp: timespec; begin clock_gettime(CLOCK_MONOTONIC, @tp); Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); 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. Indeed. That's why Pascal offers var arguments instead of pointers, so you notice this kind of thing when compiling :( Fixed. Thanks for pointing it out. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
El 02/04/14 10:01, Mattias Gaertner ha escrit: > On Wed, 02 Apr 2014 09:47:45 +0200 > Luca Olivetti wrote: > >> [...] >> Btw, in theory CLOCK_MONOTONIC_RAW should be even better, though it's >> only available from linux 2.6.28 > > CLOCK_MONOTONIC_RAW lacks the fixes by NTP. Isn't that's desirable for the semantic of GetTickCount? Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Wed, 02 Apr 2014 09:47:45 +0200 Luca Olivetti wrote: >[...] > Btw, in theory CLOCK_MONOTONIC_RAW should be even better, though it's > only available from linux 2.6.28 CLOCK_MONOTONIC_RAW lacks the fixes by NTP. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
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 wrote: >>> [...] function GetTickCount64: QWord; var tp: timespec; begin clock_gettime(CLOCK_MONOTONIC, @tp); Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); 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,@ts); > Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 100); > 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 100); > exit; > end; > {$ENDIF} > clock_gettime(CLOCK_REALTIME,@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 100); > exit; > end; > {$ENDIF} > clock_gettime(CLOCK_REALTIME,@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 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
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 wrote: >> >>> [...] >>> function GetTickCount64: QWord; >>> var >>> tp: timespec; >>> begin >>> clock_gettime(CLOCK_MONOTONIC, @tp); >>> Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); >>> 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. var ts:TTimeSpec; begin {$IFDEF HAVECLOCKGETTIME} if clock_gettime(CLOCK_MONOTONIC, @ts)<0 then {$ENDIF} clock_gettime(CLOCK_REALTIME,@ts); Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 100); 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 100); exit; end; {$ENDIF} clock_gettime(CLOCK_REALTIME,@tv); 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 100); exit; end; {$ENDIF} clock_gettime(CLOCK_REALTIME,@tv); 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 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Tue, 1 Apr 2014, Mattias Gaertner wrote: On Tue, 01 Apr 2014 12:20:53 +0200 Luca Olivetti wrote: [...] function GetTickCount64: QWord; var tp: timespec; begin clock_gettime(CLOCK_MONOTONIC, @tp); Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); end; [...] Thanks. GetTickCount64 now uses it on Linux. The implementation in Sysutils now does so too, and uses a fallback using gettimeofday. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
El 01/04/14 20:03, Mattias Gaertner ha escrit: > On Tue, 01 Apr 2014 12:20:53 +0200 > Luca Olivetti wrote: > >> [...] >> function GetTickCount64: QWord; >> var >> tp: timespec; >> begin >> clock_gettime(CLOCK_MONOTONIC, @tp); >> Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); >> end; >> [...] > > Thanks. GetTickCount64 now uses it on Linux. Wow, that was fast. Thank you. Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Tue, 01 Apr 2014 12:20:53 +0200 Luca Olivetti wrote: >[...] > function GetTickCount64: QWord; > var > tp: timespec; > begin > clock_gettime(CLOCK_MONOTONIC, @tp); > Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); > end; >[...] Thanks. GetTickCount64 now uses it on Linux. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 04/01/2014 01:57 PM, Henry Vermaak wrote: On Tue, Apr 01, 2014 at 12:45:54PM +0200, zeljko wrote: On 04/01/2014 12:20 PM, Luca Olivetti wrote: For linux a more accurate implementation could be function GetTickCount64: QWord; var tp: timespec; begin clock_gettime(CLOCK_MONOTONIC, @tp); Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); end; And I say linux because CLOCK_MONOTONIC is only defined there in fpc, though it should be available even in other systems: CLOCK_MONOTONIC is available only for kernels >= 2.6.26. No, it's been around since before 2.6. You're right. I've been on CLOCK_MONOTONIC_RAW which is available since 2.6.28 actually so my complete information was wrong ;) zeljko -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On Tue, Apr 01, 2014 at 12:45:54PM +0200, zeljko wrote: > On 04/01/2014 12:20 PM, Luca Olivetti wrote: > > >For linux a more accurate implementation could be > > > >function GetTickCount64: QWord; > >var > > tp: timespec; > >begin > > clock_gettime(CLOCK_MONOTONIC, @tp); > > Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); > >end; > > > > > >And I say linux because CLOCK_MONOTONIC is only defined there in fpc, > >though it should be available even in other systems: > > CLOCK_MONOTONIC is available only for kernels >= 2.6.26. No, it's been around since before 2.6. Henry -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] Better implementation of GetTickcount using clock_gettime
On 04/01/2014 12:20 PM, Luca Olivetti wrote: For linux a more accurate implementation could be function GetTickCount64: QWord; var tp: timespec; begin clock_gettime(CLOCK_MONOTONIC, @tp); Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); end; And I say linux because CLOCK_MONOTONIC is only defined there in fpc, though it should be available even in other systems: CLOCK_MONOTONIC is available only for kernels >= 2.6.26. zeljko -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] Better implementation of GetTickcount using clock_gettime
I use GetTickCount a lot to keep track of timeouts. On windows, it is guaranteed to be monotonic, so my usual if GetTickCount-StartTime>Timeout then.. works fine (yes, even when the time wraps around, provided StartTime is defined as DWORD and Timeout is smaller than a DWORD, of course I could use GetTickCount64 but usually the 32bits version is enough). For unix the implementation uses fpgettimeofday but that's not monotonic, so it could break the above code. For linux a more accurate implementation could be function GetTickCount64: QWord; var tp: timespec; begin clock_gettime(CLOCK_MONOTONIC, @tp); Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 100); end; And I say linux because CLOCK_MONOTONIC is only defined there in fpc, though it should be available even in other systems: http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus