This is the mail archive of the cygwin-developers mailing list for the Cygwin project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
At 11:10 PM 11/13/2005 -0500, Christopher Faylor wrote: >On Sun, Nov 13, 2005 at 10:37:50PM -0500, Pierre A. Humblet wrote: >>At 06:16 PM 11/12/2005 -0500, Christopher Faylor wrote: >>>On Fri, Nov 11, 2005 at 05:47:17PM -0500, Pierre A. Humblet wrote: >>>>I worked on the resolution issue a while back, to insure the following >>>>Posix behavior (exim relies on it): >>>>If you 1) call time() or equivalent, 2) sleep() or alarm() for some >>>>interval, 3) call time() again, then the difference between the times in >>>>3) and 1) cannot be smaller than the interval in 2). Insuring that is >>>>easier if the resolution is known. >>>>I am not sure if Cygwin still behaves that way, insuring it requiring >>>>rounding up at various places. >>> >>>I was thinking about the above in the thinking room today and it >>>occurred to me that the right way (tm) to fix this problem would be to >>>modify sleep/alarm so that the above is true. alarm might be slightly >>>trickier than sleep but I don't think it would be unbelievably hard. It >>>seems like adding a low_priority_sleep loop to nanosleep and alarm which >>>waits until the time delta was >= what was expected would be preferable >>>to forcing the resolution to 1ms for the whole program forever. >> >>I was just indicating what I had done with the time routines, this is not >>directly related to the 1 ms resolution (it was there before, as I recall). >>No matter what the resolution is, it should be possible to get it and do >>the right thing, for example in nanosleep: >> DWORD resolution = gtod.resolution (); >> DWORD req = ((rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000 >> + resolution - 1) / resolution) * resolution; >>Your approach can surely also be made to work. >>I will take another look this week, on WinME and XP. > >Ah. I thought you were saying that you were relying on the 1ms >behavior. I should have known better, though, since I have looked at >nanosleep recently. > >I am not convinced that trying to factor in the resolution into the amount >of time to sleep is going to always do the right thing but I'm not overly >worried about it, I guess. If the above expression is right then it should >continue to work even when the resolution is != 1ms, AFAICT. I made some experiments to find the clock resolution, using - NtQueryTimerResolution , see http://www.sysinternals.com/Information/HighResolutionTimers.html - GetSystemTimeAdjustment (used in sysinternals' ClockRes applet) - the method used by hires_ms::resolution in current cvs (referred to as the "timeGetTime resolution" below) - the WaitForX series Here are my results, your mileage may vary (my program is attached) 1) The timeGetTime resolution is always equal to the rounded (up or down) NtQueryTimerResolution resolution (on NT) and to the resolution actually obtained by WaitForX 2) GetSystemTimeAdjustment reports an interval that is not affected by timeBeginPeriod and that is never less than NtQueryTimerResolution (on NT). That makes technical sense to me (time of day clock adjustment period vs. timer resolution), and I am ready to consider that the timeGetTime resolution is never worse than what GetSystemTimeAdjustment reports. 3) On WinMe and Win98, the resolutions of timeGetTime and of the WaitFor calls is always 1 ms. This matches the documentation. 4) These resolutions are also 1 ms on my XP home SP2 (result may depend on other programs) 5) On an XP Pro SP2: 5a) the "normal" resolution is 1/64 s (15.625 ms), but is improved to 1/1024 s (.9765 ms) when cygwin processes such as rxvt are running. However for brief periods of time (a few seconds) it can change to 1/128, 1/256, 1/512 or 1/1024 s (without Cygwin processes, of course). 5b) The resolution is not constant inside a single process. It changes depending on what's happening in other processes. 5c) timeBeginPeriod works as advertised 6) When WaitForX asks for a timeout d, the actual delay measured by timeGetTime is never less than d. This is an observation. I could find no such statement in the Microsoft documentation, but I think it makes technical sense. This is what we can conclude: - Because of 5b), the current method in cvs for hires_ms::resolution is not reliable. It can err in both directions. - If 6) is true, and because our alarm and sleep calls ultimately rely on WaitForX, the Posix requirement at the top of this e-mail can be met without calling gtod.resolution () in nanosleep. On could simply set DWORD req = rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000 and get rid of hires_ms::resolution - clock_getres should report 1 ms on 9X and probably 15.625 ms on a "standard" NT. Instead of hard coding 15.625 ms, I believe that one could safely use the interval reported by GetSystemTimeAdjustment [see 2) above]. To play absolutely safe, one should report the worst resolution according to timeGetDevCaps. However if clock_setres has been called, then clock_getres should report that resolution. - If we don't take 6) as being guaranteed, then we should keep gtod.resolution () in nanosleep and add it in timer_thread. We should also keep using timeBeginPeriod to guarantee some value for hires_ms::resolution, or have gtod.resolution () report the same value as discussed above for clock_getres. Pierre
Attachment:
clockres.c
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |