PEP 418: I'm not quite sure, but it looks like QueryPerformanceCounter() *is* monotonic

This commit is contained in:
Victor Stinner 2012-03-28 01:45:51 +02:00
parent d1d1094798
commit 8d75780f92
1 changed files with 32 additions and 11 deletions

View File

@ -62,7 +62,7 @@ The system time is the "wall clock". It can be set manually by the system
administrator or automatically by a NTP daemon. It can jump backward and administrator or automatically by a NTP daemon. It can jump backward and
forward, and is not monotonic. forward, and is not monotonic.
It is avaialble on all platforms and cannot fail. It is available on all platforms and cannot fail.
Pseudo-code:: Pseudo-code::
@ -104,30 +104,47 @@ Pseudo-code::
if os.name == 'nt': if os.name == 'nt':
if hasattr(time, '_GetTickCount64'): if hasattr(time, '_GetTickCount64'):
monotonic = _time.GetTickCount64 _get_tick_count = _time.GetTickCount64
else: else:
def monotonic(): def _get_tick_count():
ticks = _time.GetTickCount() ticks = _time.GetTickCount()
if ticks < monotonic.last: if ticks < _get_tick_count.last:
# Integer overflow detected # Integer overflow detected
monotonic.delta += 2**32 _get_tick_count.delta += 2**32
monotonic.last = ticks _get_tick_count.last = ticks
return ticks + monotonic.delta return ticks + _get_tick_count.delta
monotonic.last = 0 _get_tick_count.last = 0
monotonic.delta = 0 _get_tick_count.delta = 0
if os.name == 'mac':
def monotonic():
if monotonic.use_performance_counter:
try:
return _time.QueryPerformanceCounter()
except OSError:
# QueryPerformanceFrequency() may fail, if the installed
# hardware does not support a high-resolution performance
# counter for example
monotonic.use_performance_counter = False
# Fallback to GetTickCount/GetTickCount64 which has
# a lower resolution
return _get_tick_count()
monotonic.use_performance_counter = True
elif os.name == 'mac':
def monotonic(): def monotonic():
if monotonic.factor is None: if monotonic.factor is None:
factor = _time.mach_timebase_info() factor = _time.mach_timebase_info()
monotonic.factor = timebase[0] / timebase[1] monotonic.factor = timebase[0] / timebase[1]
return _time.mach_absolute_time() * monotonic.factor return _time.mach_absolute_time() * monotonic.factor
monotonic.factor = None monotonic.factor = None
elif hasattr(time, "clock_gettime") and hasattr(time, "CLOCK_MONOTONIC"): elif hasattr(time, "clock_gettime") and hasattr(time, "CLOCK_MONOTONIC"):
def monotonic(): def monotonic():
if monotonic.use_monotonic_raw: if monotonic.use_monotonic_raw:
try: try:
return time.clock_gettime(time.CLOCK_MONOTONIC_RAW) return time.clock_gettime(time.CLOCK_MONOTONIC_RAW)
except OSError: except OSError:
# CLOCK_MONOTONIC_RAW requires a Linux kernel >= 2.6.28
monotonic.use_monotonic_raw = False monotonic.use_monotonic_raw = False
return time.clock_gettime(time.CLOCK_MONOTONIC) return time.clock_gettime(time.CLOCK_MONOTONIC)
monotonic.use_monotonic_raw = hasattr(time, "CLOCK_MONOTONIC_RAW") monotonic.use_monotonic_raw = hasattr(time, "CLOCK_MONOTONIC_RAW")
@ -320,7 +337,7 @@ had a bug (see `KB896256 <http://support.microsoft.com/?id=896256>`_): on a
multiprocessor computer, QueryPerformanceCounter() returned a different value multiprocessor computer, QueryPerformanceCounter() returned a different value
for each processor. for each processor.
QueryPerformanceCounter() is not monotonic. QueryPerformanceCounter() is monotonic.
QueryPerformanceFrequency() fails if the installed hardware does not support a QueryPerformanceFrequency() fails if the installed hardware does not support a
high-resolution performance counter. high-resolution performance counter.
@ -395,4 +412,8 @@ Links
<http://qt-project.org/doc/qt-4.8/qelapsedtimer.html>`_ <http://qt-project.org/doc/qt-4.8/qelapsedtimer.html>`_
* `Windows: Game Timing and Multicore Processors * `Windows: Game Timing and Multicore Processors
<http://msdn.microsoft.com/en-us/library/ee417693.aspx>`_ <http://msdn.microsoft.com/en-us/library/ee417693.aspx>`_
* `Implement a Continuously Updating, High-Resolution Time Provider for Windows
<http://msdn.microsoft.com/en-us/magazine/cc163996.aspx>`_
* `Perl: Time::HiRes
<http://perldoc.perl.org/Time/HiRes.html>`_