Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Wednesday 02 of November 2011 23:45:53 Martin Schreiber wrote: On Wednesday 02 November 2011 17.43:56 Martin Schreiber wrote: On Wednesday 02 November 2011 17.13:49 Jonas Maebe wrote: Yes, the result slower, but it's also correct (as in it makes sure that the actual local time is returned). Just like all UTF-16 code in the RTL is slower than what Martin Schreiber would like, and we didn't change it to UCS-2 when he asked to do so for speed reasons. ??? I never asked this. I asked not to use new code page aware stringtype instead of pre cpstrnew UnicodeString, not to use 16 bit strings in component names and the like and not to use non ASCII characters in RTTI and Pascal identifiers. I fully agree with your argumentation about Now(). MSEgui already has a nowutc() function, I'll add nowlocal() which will use mselibc on Linux. The results with 10'000'000 calls: FPC Now() MSEgui nowutc() MSEgui nowlocal() Linux 15.29s 3.39s 3.57s Windows 10.00s 1.22s 1.37s Have you tried latest Michael's patch for getttimeofday ? It used 2 calls 1 to gettimeofday and 1 to fptime, now it uses only gettimeofday syscall and it's twice faster. So: your nowutc() and nowlocal() returns timings which I have with my implementation of Now() by using syscall clock_gettime(CLOCK_REALTIME). After Michal patched current trunk , gettimeofday have same timing. Overhead of Now() is now fixed in trunk. Don't know anything about windows...maybe it should be reviewed for unnecesarry calls. zeljko ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday 03 November 2011 07.44:47 zeljko wrote: The results with 10'000'000 calls: FPC Now() MSEgui nowutc() MSEgui nowlocal() Linux 15.29s 3.39s 3.57s Windows 10.00s 1.22s 1.37s Have you tried latest Michael's patch for getttimeofday ? No, I can not use trunk because of cpstrnew. I'll try the file Michael sent. Martin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
03.11.2011 15:04, Martin Schreiber wrote: No, I can not use trunk because of cpstrnew. I'll try the file Michael sent. If it is not difficult please explain exact problems with cpstrnew you have in a separate thread. It is important to know for me what problems do you have with the new ansistring type. Best regards, Paul Ishenin. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday 03 November 2011 08.11:16 Paul Ishenin wrote: 03.11.2011 15:04, Martin Schreiber wrote: No, I can not use trunk because of cpstrnew. I'll try the file Michael sent. If it is not difficult please explain exact problems with cpstrnew you have in a separate thread. It is important to know for me what problems do you have with the new ansistring type. I invested much time into debugging pre 2.0 / post 2.0 WideString and pre 2.7 UnicodeString. I do not plan to do the same for cpstrnew. I think the people who wanted the new strings should do the debugging too. Maybe it is bug free already but I can't really believe it. ;-) Martin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday 03 of November 2011 08:11:16 Paul Ishenin wrote: 03.11.2011 15:04, Martin Schreiber wrote: No, I can not use trunk because of cpstrnew. I'll try the file Michael sent. If it is not difficult please explain exact problems with cpstrnew you have in a separate thread. It is important to know for me what problems do you have with the new ansistring type. Maybe it's not problem *now*, but looking into mailing list ppl have a lot of problems, so I think that fear is only problem (at least for me). zeljko ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday 03 November 2011 08.04:17 Martin Schreiber wrote: On Thursday 03 November 2011 07.44:47 zeljko wrote: The results with 10'000'000 calls: FPC Now() MSEgui nowutc() MSEgui nowlocal() Linux 15.29s 3.39s 3.57s Windows 10.00s 1.22s 1.37s Have you tried latest Michael's patch for getttimeofday ? RTL recompiled with Michael's file: Linux FPC Now() MSEgui nowutc() MSEgui nowlocal() 11.49s 3.86s 4.03s Martin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
03.11.2011 15:29, zeljko wrote: Maybe it's not problem *now*, but looking into mailing list ppl have a lot of problems, so I think that fear is only problem (at least for me). People mostly expressed their FUD although there were few problems and there are some. But why do you think they should affect you? Do you any ansistring type except 'AnsiString' in your applications? Best regards, Paul Ishenin. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday 03 of November 2011 08:43:55 Martin Schreiber wrote: On Thursday 03 November 2011 08.04:17 Martin Schreiber wrote: On Thursday 03 November 2011 07.44:47 zeljko wrote: The results with 10'000'000 calls: FPC Now() MSEgui nowutc() MSEgui nowlocal() Linux 15.29s 3.39s 3.57s Windows 10.00s 1.22s 1.37s Have you tried latest Michael's patch for getttimeofday ? RTL recompiled with Michael's file: Linux FPC Now() MSEgui nowutc() MSEgui nowlocal() 11.49s 3.86s 4.03s That's pretty big difference. Can you compare NowReal() from attached program with your functions ? zeljko program unixclocks; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils, unix, baseunix, libc, syscall, unixutil; const CLOCK_REALTIME = 0; CLOCK_MONOTONIC = 1; CLOCK_MONOTONIC_RAW = 4; CLOCK_REALTIME_COARSE = 5; CLOCK_MONOTONIC_COARSE = 6; CLOCKS_MASK = CLOCK_REALTIME or CLOCK_MONOTONIC; procedure GetLocalTimeNew(var SystemTime: TSystemTime; const AClockType: byte); var ASpec: TimeSpec; begin if Do_SysCall(syscall_nr_clock_gettime, AClockType, TSysParam(@ASpec)) = 0 then begin with SystemTime do begin EpochToLocal(ASpec.tv_sec, year, month, day, hour, minute, second); Millisecond := ASpec.tv_nsec mod 1000; end; end; end; function NowReal: TDateTime; var SystemTime: TSystemTime; begin GetLocalTimeNew(SystemTime, CLOCK_REALTIME); Result := SystemTimeToDateTime(SystemTime); end; function NowMono: TDateTime; var SystemTime: TSystemTime; begin GetLocalTimeNew(SystemTime, CLOCK_MONOTONIC); Result := SystemTimeToDateTime(SystemTime); end; function NowLibc: TDateTime; var T: Libc.time_t; TV: Libc.TimeVal; UT: Libc.TUnixTime; begin Libc.gettimeofday(TV, nil); T := TV.tv_sec; Libc.localtime_r(@T, @UT); Result := EncodeDate(UT.tm_year + 1900, UT.tm_mon + 1, UT.tm_mday) + EncodeTime(UT.tm_hour, UT.tm_min, UT.tm_sec, TV.tv_usec div 1000); end; function GetTickCount(const AType: Integer = 0): DWord; var ATime: TDateTime; begin case AType of 1: ATime := NowReal(); 2: ATime := NowLibc(); else ATime := Now(); end; Result := DWord(Trunc(ATime * 24 * 60 * 60 * 1000)) end; const AMsrInt = 1000; var i: integer; ATicks: DWord; begin writeln('RTL ',FormatDateTime('dd.mm. hh:nn:ss.zz ',Now()),' clock_gettime() ', FormatDateTime('dd.mm. hh:nn:ss.zz ',NowReal()), ' libc ',FormatDateTime('dd.mm. hh:nn:ss.zz ',NowLibc())); ATicks := GetTickCount; for i := 0 to AMsrInt - 1 do Now(); writeln(Format('RTL Now() with %d calls = %d ms ', [AMsrInt, GetTickCount - ATicks])); ATicks := GetTickCount; for i := 0 to AMsrInt - 1 do NowReal(); writeln(Format('Kernel clock_gettime() NowReal() with %d calls = %d ms ', [AMsrInt, GetTickCount - ATicks])); ATicks := GetTickCount; for i := 0 to AMsrInt - 1 do NowLibc(); writeln(Format('Libc gettimeofday()+localtime_r() with %d calls = %d ms ', [AMsrInt, GetTickCount - ATicks])); end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] About GetTickCount
I guess that there's no GetTickCount in RTL. Is it possible to add it there ? Why ? Because current GetTickCount in lazarus uses Now() which is movable backward/forward by ntpd under unixes, and that could be a huge problem. This is what MSDN says about GetTickCount: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days (what they do after 49.7 days ? ). So, according to POSIX clock_gettime(CLOCK_MONOTONIC) is supported on linux, bsd and others, and in that case we can have exact GetTickCount. If there's no support for monotonic clock on some platform , now() can be returned anytime. zeljko ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
On Thursday 03 of November 2011 09:41:05 zeljko wrote: I guess that there's no GetTickCount in RTL. Is it possible to add it there ? Why ? Because current GetTickCount in lazarus uses Now() which is movable backward/forward by ntpd under unixes, and that could be a huge problem. This is what MSDN says about GetTickCount: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days (what they do after 49.7 days ? ). So, according to POSIX clock_gettime(CLOCK_MONOTONIC) is supported on linux, bsd and others, and in that case we can have exact GetTickCount. If there's no support for monotonic clock on some platform , now() can be returned anytime. Forget all about this, only CLOCK_MONOTONIC_RAW is something we need but it's supported as of 2.6.28 kernel ... so no way. zeljko zeljko ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
In our previous episode, zeljko said: So, according to POSIX clock_gettime(CLOCK_MONOTONIC) is supported on linux, bsd and others, and in that case we can have exact GetTickCount. If there's no support for monotonic clock on some platform , now() can be returned anytime. Forget all about this, only CLOCK_MONOTONIC_RAW is something we need but it's supported as of 2.6.28 kernel ... so no way. (and afaik POSIX doesn't specify the granularity, you need to do a separate call for that. It could be seconds) ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday 03 November 2011 09.08:35 zeljko wrote: That's pretty big difference. Can you compare NowReal() from attached program with your functions ? Linux FPC Now() MSEgui nowutc() MSEgui nowlocal() NowReal() 10.28s 3.45s 3.55s 9.86s Martin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
Withdrawn. It is only partially true. Still it can not be expanded and can overflow easily. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
Al 03/11/2011 9:41, En/na zeljko ha escrit: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days (what they do after 49.7 days ? ). It starts again from 0. If you're using it to time events (i.e. ElapsedTime:=GetTickCount-StartTime), it's not a problem, as long as you don't need to time events that last longer than 49 days *and* you don't enable overflow check (-Co) Bye -- Luca ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
On Thu, November 3, 2011 09:41, zeljko wrote: I guess that there's no GetTickCount in RTL. Is it possible to add it there ? Why ? Because current GetTickCount in lazarus uses Now() which is movable backward/forward by ntpd under unixes, and that could be a huge problem. This is what MSDN says about GetTickCount: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days (what they do after 49.7 days ? ). So, according to POSIX clock_gettime(CLOCK_MONOTONIC) is supported on linux, bsd and others, and in that case we can have exact GetTickCount. If there's no support for monotonic clock on some platform , now() can be returned anytime. There is already GetMsCount in unit Dos. It should be possible to add it to sysutils too. This does not guarantee to be monotonic, but the primary goal is a simple and fast call which should allow checking time difference between two consecutive calls. It uses GetTickCount on Win32 and similar calls on other platforms. As implemented now, it doesn't protect you from time changes on all platforms though (but that is a limitation of implementation for those platforms). Tomas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
If you want to do timing, you can also take a look at EpikTimer. I believe it doesn't work on all platforms that FPC supports, but it works on the big three (Windows, Linux, Mac). -- Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
On Thu, Nov 3, 2011 at 9:41 AM, zeljko zel...@holobit.net wrote: I guess that there's no GetTickCount in RTL. Is it possible to add it there ? If we are going to add this I would prefer to get the result in microseconds. If the platform doesnt support, then just multiply the result, but still allow the possibility. -- Felipe Monteiro de Carvalho ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Am 03.11.2011 02:39, schrieb Hans-Peter Diettrich: IMO we have to face a problem very similar to Ansi/UTF-8/16: A TDateTime variable can contain local time in a number of timezones (Ansi), or UTC values (UTF), which must be interpreted accordingly, e.g. in DateTimeToStr(). When Delphi compatible Now() provides local time TDateTime (including DST, as is on Windows), and DateTimeToStr() etc. expect a local time argument, a full emulation of these functions has to be provided on other platforms as well. But even in Delphi the programmer has to keep track whether a TDateTime contains a local or UTC based time value (e.g. if he converted the local time returned by Now to UTC). And functions like DateTimeToStr don't care whether a time value is local or UTC and in my opinion they even MUST NOT. If I use such a function I want the value of the given TDateTime printed to a string no matter what timezone I'm currently in. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Am 03.11.2011 03:12, schrieb Hans-Peter Diettrich: Also note that on platforms like Windows this would be a unnecessary call as there the current(!) timezone bias is located in a shared memory area which is mapped into each process by the kernel. I don't think that this really is how Windows works. Delphi Now() retrieves an TSystemTime record (GetLocalTime), and converts its fields into an TDateTime value(EncodeDate/Time). A simple timezone bias is inapplicable to the TSystemTime data structure, but the kernel.dll may keep its conversion information somewhere in the DATA segment. FPC's Now on Windows uses GetLocalTime as well. For its implementation please take a look here: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/time.c?revision=52912view=markup (line 277ff) The application of the timezone bias is from line 290 to 300. If there is no redirection of the time zone (used for terminal servers) then the bias is read from the beforementioned shared user data. Here is the implementation of SharedUserData in my NativeNT port of FPC (unit NDK): === source begin === function SharedUserData: PKUSER_SHARED_DATA; register; begin { this is a pointer to a page that is mapped into every process by the kernel } SharedUserData := PKUSER_SHARED_DATA(USER_SHARED_DATA); end; === source end === And USER_SHARED_DATA has the following value: === source begin === USER_SHARED_DATA = $7FFE; === source end === On POSIX platforms gettimeofday and localtime_r is used instead (Delphi XE). All this handling makes Now() quite expensive, so that (a future) FPC should provide cheaper means for getting time stamps. The problem with localtime_r itself is that it's implemented in LibC which must be avoided for the non-LibC-RTL. So FPC definitely must provide an implementation of its own for this. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
On Thu, 3 Nov 2011, Graeme Geldenhuys wrote: If you want to do timing, you can also take a look at EpikTimer. I believe it doesn't work on all platforms that FPC supports, but it works on the big three (Windows, Linux, Mac). PLEASE NEVER MENTION EPIKTIMER AGAIN. it returns Now() on all platforms except i386. It should be abandoned. epiktimer is one of the worst written components ever, for some reason surrounded by unfounded myths. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Interchangeability between array of Const and array of TVarRec. Bug?
Hi, I can pass an array of TVarRec to a procedure that expects an array of const like below: procedure Test(Args: array of const); begin //do something with args end; var a: array of TVarRec; s: String; begin SetLength(a, 2); a[0].VType := vtInteger; a[0].VInteger := 3; a[1].VType := vtAnsiString; s := 'xx'; a[1].VAnsiString := PAnsiString(s); Test(a); end. But when i try to do the inverse (pass an array of const to an array of TVarRec) i get the following error: Error: Incompatible type for arg no. 1: Got Array Of Const\Constant Open Array of ShortInt, expected Open Array Of TVarRec procedure Test(Args: array of TVarRec); begin //do something with args end; begin Test([3, 'xx']); end. Is that a bug or a limitation of the language? Using FPC 2.4.4 i386-win32 Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Sven Barth schrieb: Am 03.11.2011 02:39, schrieb Hans-Peter Diettrich: IMO we have to face a problem very similar to Ansi/UTF-8/16: A TDateTime variable can contain local time in a number of timezones (Ansi), or UTC values (UTF), which must be interpreted accordingly, e.g. in DateTimeToStr(). When Delphi compatible Now() provides local time TDateTime (including DST, as is on Windows), and DateTimeToStr() etc. expect a local time argument, a full emulation of these functions has to be provided on other platforms as well. But even in Delphi the programmer has to keep track whether a TDateTime contains a local or UTC based time value (e.g. if he converted the local time returned by Now to UTC). Right, just like the user currently must remember whether an AnsiString contains Ansi or UTF-8. But how do you want to get the UTC and put it into a TDateTime? And functions like DateTimeToStr don't care whether a time value is local or UTC and in my opinion they even MUST NOT. Splitting the TDateTime into year, month etc. is done by a DecodeDate... function, that *assumes* that TDateTime contains a local time. When you feed it an UTC time, the result is unusable. If I use such a function I want the value of the given TDateTime printed to a string no matter what timezone I'm currently in. A TDateTime only contains the number of days since the begin of the epoch (of the encoded date). Which epoch should apply? The time part contains the fraction of the day, based on midnight of which timezone? DoDi ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Sven Barth schrieb: FPC's Now on Windows uses GetLocalTime as well. For its implementation please take a look here: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/time.c?revision=52912view=markup (line 277ff) That code doesn't make sense, without additional information :-( 283 do 284 { 285 SystemTime.HighPart = SharedUserData-SystemTime.High1Time; 286 SystemTime.LowPart = SharedUserData-SystemTime.LowPart; 287 } 288 while (SystemTime.HighPart != SharedUserData-SystemTime.High2Time); As long as no functions are involved, the loop copies the same information into SystemTime, over and over again. On POSIX platforms gettimeofday and localtime_r is used instead (Delphi XE). All this handling makes Now() quite expensive, so that (a future) FPC should provide cheaper means for getting time stamps. The problem with localtime_r itself is that it's implemented in LibC which must be avoided for the non-LibC-RTL. So FPC definitely must provide an implementation of its own for this. Then something like WinAPI SystemTimeToTzSpecificLocalTime has to be implemented. That function can be used for every platform, provided that the SystemTime is stored in an platform independent way. DoDi ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
zeljko schrieb: This is what MSDN says about GetTickCount: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days (what they do after 49.7 days ? ). When the DWORD overflows, Win9x stops to work properly. NT uses an bigger data type, at least internally. IMO every OS supports an basic time counter, incremented by interrupts (BIOS, DOS) or in hardware, and starting at system boot time. A resolution of 10ns, as currently available, requires hardware support of course - and such support depends on the machine architecture. The determination of the current time adjusts the counter value, according to the clock frequency, and adds the absolute starting (boot) time. Afterwards the timzone shift can be added to that value, when local time is required. Then comes the hairy part, the conversion of that time into days, years etc., for display purposes. DoDi ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thu, 03 Nov 2011 17:38:01 +0100, Hans-Peter Diettrich drdiettri...@aol.com wrote: FPC's Now on Windows uses GetLocalTime as well. For its implementation please take a look here: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/time.c?revision=52912view=markup (line 277ff) That code doesn't make sense, without additional information :-( 283 do 284 { 285 SystemTime.HighPart = SharedUserData-SystemTime.High1Time; 286 SystemTime.LowPart = SharedUserData-SystemTime.LowPart; 287 } 288 while (SystemTime.HighPart != SharedUserData-SystemTime.High2Time); As long as no functions are involved, the loop copies the same information into SystemTime, over and over again. Nope. SystemTime.HighXTime is most probably a volatile, so it is read each time through the loop. I can only guess what High1Time and High2Time is (I'd assume they basically map to the same variable, so you're right, that is a bit strange somehow, but well...), but this is a common pattern to counterfeit wrong time reads when a wrap-around happens during reading the individual parts. Consider reading the values when the time value is $:$. First you read the $, then the time value changes to $0001: and next you read the high part as $0001. Net result: $0001:$. Thus, a big time jump happens. Seldom enough to detect in testing, but often enough to cause disastrous results at the customer site from time to time. By checking the high part again, the problem is avoided. [Well, at least as long as the reading does not take a huge amount of time, so that another wrap of the high part happens... ;)] Vinzent. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday, November 03, 2011 11:03:36 am Hans-Peter Diettrich wrote: Sven Barth schrieb: And functions like DateTimeToStr don't care whether a time value is local or UTC and in my opinion they even MUST NOT. Splitting the TDateTime into year, month etc. is done by a DecodeDate... function, that *assumes* that TDateTime contains a local time. When you feed it an UTC time, the result is unusable. What? How does it assume it's in local time? It assumes it has received the value you want decoded. The value 40850.5 treated as a TDateTime is 03 NOV 2011 @ 12:00. No matter what time zone it's expressed in, the result is the same, but in that zone. If you want a different zone, you have to add in the offset before decoding. How is that unusable? Best regards, Pete C. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Pete Cervasio schrieb: Splitting the TDateTime into year, month etc. is done by a DecodeDate... function, that *assumes* that TDateTime contains a local time. When you feed it an UTC time, the result is unusable. What? How does it assume it's in local time? It assumes it has received the value you want decoded. The value 40850.5 treated as a TDateTime is 03 NOV 2011 @ 12:00. How do you get the starting date and time of the epoch? According to Delphi help a TDateTime of 0.0 represents 12/30/1899 12:00 am, while Wikipedia states start counting the seconds from the Unix epoch of 1970-01-01T00:00:00 UTC. DoDi ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Am 03.11.2011 21:11, schrieb Hans-Peter Diettrich: Pete Cervasio schrieb: Splitting the TDateTime into year, month etc. is done by a DecodeDate... function, that *assumes* that TDateTime contains a local time. When you feed it an UTC time, the result is unusable. What? How does it assume it's in local time? It assumes it has received the value you want decoded. The value 40850.5 treated as a TDateTime is 03 NOV 2011 @ 12:00. How do you get the starting date and time of the epoch? According to Delphi help a TDateTime of 0.0 represents 12/30/1899 12:00 am, while Wikipedia states start counting the seconds from the Unix epoch of 1970-01-01T00:00:00 UTC. You are aware that the definition of TDateTime and that of the Unix timestamp are not supposed to be the same? The original TDateTime definiton (Delphi 1 and maybe also 2) started from 01/01/0001 and was later changed to todays 12/30/1899 to be COM compatible. And still: It does not matter whether we are talking about local or UTC time here. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: RE : [fpc-devel] Problem with Now() and time changed by ntpd
Am 02.11.2011 19:25, schrieb Ludo Brands: Apparently not everything is that transparent under windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724944%28v=vs.85%2 9.aspx To inform Explorer that the time zone has changed, send the WM_SETTINGCHANGE message. WM_SETTINGCHANGE simply notifies you that the user changed the time zone, because otherwise you might not be able to detect that (except you read the settings from the registry yourself). Or: http://channel9.msdn.com/coding4fun/articles/Changing-time-zones By itself, changing the time zone doesn't have any apparent effect except in new processes. In order to see the change, you need to send a system notification message. This notification is made by calling SendMessageTimeout with WM_SettingChange and a parameter of intl. This is wrong. Changing the timezone effects e.g. all following calls to GetLocalTime. See the following example program: === source begin === program timezonetest; {$apptype console} {$mode objfpc}{$H+} uses SysUtils; begin Writeln(FormatDateTime('c', Now)); Writeln('Please change the timezone and then press enter'); Readln; Writeln(FormatDateTime('c', Now)); Writeln('Done'); Readln; end. === source end === As you see there is no message processing. My normal timezone is Berlin. Now I've run the program and changed the timezone to Greenland (-3h). The output was the following: === output begin === 03.11.2011 21:16:33 Please change the timezone and then press enter 03.11.2011 17:17:10 Done === output end === So your link which talks about only affects new processes is proven wrong. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
Am 03.11.2011 17:38, schrieb Hans-Peter Diettrich: Sven Barth schrieb: FPC's Now on Windows uses GetLocalTime as well. For its implementation please take a look here: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/time.c?revision=52912view=markup (line 277ff) That code doesn't make sense, without additional information :-( 283 do 284 { 285 SystemTime.HighPart = SharedUserData-SystemTime.High1Time; 286 SystemTime.LowPart = SharedUserData-SystemTime.LowPart; 287 } 288 while (SystemTime.HighPart != SharedUserData-SystemTime.High2Time); As long as no functions are involved, the loop copies the same information into SystemTime, over and over again. As Vinzent wrote, the SystemTime field is considered volatile (take a look at %fpcdir%\rtl\nativent\ndk\ketypes.inc; I have kept the volatile keywords as comments when translating that _KUSER_SHARED_DATA struct). This code is also found throughout ReactOS (and I expect Windows as well) when the time is fetched inside one of the operating system components. I've basically copied this code for the GetLocalTime implementation of my NativeNT port and it definitely works and does not loop till the end of eternity :) On POSIX platforms gettimeofday and localtime_r is used instead (Delphi XE). All this handling makes Now() quite expensive, so that (a future) FPC should provide cheaper means for getting time stamps. The problem with localtime_r itself is that it's implemented in LibC which must be avoided for the non-LibC-RTL. So FPC definitely must provide an implementation of its own for this. Then something like WinAPI SystemTimeToTzSpecificLocalTime has to be implemented. That function can be used for every platform, provided that the SystemTime is stored in an platform independent way. Something like this, yes. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] About GetTickCount
Am 03.11.2011 18:15, schrieb Hans-Peter Diettrich: zeljko schrieb: This is what MSDN says about GetTickCount: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days (what they do after 49.7 days ? ). When the DWORD overflows, Win9x stops to work properly. NT uses an bigger data type, at least internally. It's basically a 64-bit type now. Here's ReactOS' implementation of GetTickCount64 (which is called by GetTickCount): === source begin === ULONGLONG WINAPI GetTickCount64(VOID) { ULONG Multiplier; LARGE_INTEGER TickCount; /* Loop until we get a perfect match */ for (;;) { /* Read the tick count value */ TickCount.HighPart = SharedUserData-TickCount.High1Time; TickCount.LowPart = SharedUserData-TickCount.LowPart; if (TickCount.HighPart == SharedUserData-TickCount.High2Time) break; YieldProcessor(); } /* Get the multiplier */ Multiplier = SharedUserData-TickCountMultiplier; /* Convert to milliseconds and return */ return (Int64ShrlMod32(UInt32x32To64(Multiplier, TickCount.LowPart), 24) + (Multiplier * (TickCount.HighPart 8))); } === source end === You notice the loop regarding SharedUserData again? ;) (though this time it also contains a call to YieldProcessor and a comment regarding the loop) By the way: the TickCount field (and also the SystemTime one) is a KSYSTEM_TIME struct which is defined like the following (copied from my port): === source begin === // // System Time Structure // _KSYSTEM_TIME = packed record LowPart: ULONG; High1Time: LONG; High2Time: LONG; end; KSYSTEM_TIME = _KSYSTEM_TIME; PKSYSTEM_TIME = ^KSYSTEM_TIME; === source end === Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Problem with Now() and time changed by ntpd
On Thursday, November 03, 2011 03:11:37 pm Hans-Peter Diettrich wrote: Pete Cervasio schrieb: Splitting the TDateTime into year, month etc. is done by a DecodeDate... function, that *assumes* that TDateTime contains a local time. When you feed it an UTC time, the result is unusable. What? How does it assume it's in local time? It assumes it has received the value you want decoded. The value 40850.5 treated as a TDateTime is 03 NOV 2011 @ 12:00. How do you get the starting date and time of the epoch? With the constant UnixDateDelta. Help says that it Specifies the difference between TDateTime and TIME_T values. Here's how I use it. My main software project does all its work in UTC so I use this utc_now rather than the built-in now. Conversion to local time is done only for display or logging purposes. function utc_now: TDateTime; var TimeVal: TTimeVal; TimeZone: PTimeZone; begin TimeZone := nil; GetTimeOfDay (TimeVal, TimeZone); Result := (TimeVal.tv_Sec / SecsPerDay) + ((TimeVal.tv_usec / 1000.0) / MSecsPerDay) + UnixDateDelta; end; Best regards, Pete C. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel