[Python-checkins] peps: PEP 418: rename time.steady() to time.try_monotonic(); add time.hires()

victor.stinner python-checkins at python.org
Tue Mar 27 19:27:07 CEST 2012


http://hg.python.org/peps/rev/d97faf471fe1
changeset:   4153:d97faf471fe1
user:        Victor Stinner <vstinner at wyplay.com>
date:        Tue Mar 27 19:27:28 2012 +0200
summary:
  PEP 418: rename time.steady() to time.try_monotonic(); add time.hires()

files:
  pep-0418.txt |  134 +++++++++++++++++++++++++++++++-------
  1 files changed, 109 insertions(+), 25 deletions(-)


diff --git a/pep-0418.txt b/pep-0418.txt
--- a/pep-0418.txt
+++ b/pep-0418.txt
@@ -1,5 +1,5 @@
 PEP: 418
-Title: Add monotonic clock
+Title: Add monotonic and high-resolution time functions
 Version: $Revision$
 Last-Modified: $Date$
 Author: Victor Stinner <victor.stinner at gmail.com>
@@ -13,7 +13,8 @@
 Abstract
 ========
 
-Add time.monotonic() and time.steady() functions to Python 3.3.
+Add time.monotonic(), time.hires() and time.try_monotonic() functions to Python
+3.3.
 
 
 Rationale
@@ -21,14 +22,14 @@
 
 Use cases:
 
- * Display the current time to a human: use system clock. time.time() or
-   datetime.datetime.now()
+ * Display the current time to a human (e.g. display a calendar or draw a wall
+   clock): use system clock. time.time() or datetime.datetime.now()
  * Implement a timeout: use monotonic clock, or fallback to the clock with
-   the highest resolution. time.steady()
- * Benchmark and profiling: time.steady()
+   the highest resolution. time.try_monotonic()
+ * Benchmark and profiling: time.hires(), with a manual fallback to time.time()
  * Event scheduler: time.monotonic()
 
-time.steady() tries to use a monotonic clock, but it falls back to a
+time.try_monotonic() tries to use a monotonic clock, but it falls back to a
 non-monotonic clock if no monotonic clock is available or if reading a
 monotonic clock failed.
 
@@ -54,23 +55,106 @@
 Functions
 =========
 
-time.monotonic
---------------
+time.time()
+-----------
 
-Monotonic clock advancing at a steady rate relative to real time. It cannot go
-backward. It may be adjusted. The reference point of the returned value is
-undefined so only the difference of consecutive calls is valid.
+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
+forward, and is not monotonic.
 
-May raise an OSError on error.
+ * Windows: GetSystemTimeAsFileTime()
+ * clock_gettime(CLOCK_REALTIME), gettimeofday(), ftime() or time()
 
+It is avaialble on all platforms and cannot fail.
 
-time.steady
------------
+
+time.monotonic()
+----------------
+
+Monotonic clock advancing at a monotonic rate relative to real time. It
+cannot go backward. Its rate may be adjusted by NTP. The reference point of the
+returned value is undefined so only the difference of consecutive calls is
+valid.
+
+It is not avaialble on all platforms and raise an OSError on error.
+The monotonic clock may stop while the system is suspended.
+
+Pseudo-code::
+
+    if os.name == 'nt':
+        if hasattr(time, '_GetTickCount64'):
+            monotonic = _time.GetTickCount64
+        else:
+            def monotonic():
+                ticks = _time.GetTickCount()
+                if ticks < monotonic.last:
+                    # Integer overflow detected
+                    monotonic.delta += 2**32
+                monotonic.last = ticks
+                return ticks + monotonic.delta
+            monotonic.last = 0
+            monotonic.delta = 0
+    if os.name == 'mac':
+        def monotonic():
+            if monotonic.factor is None:
+                factor = _time.mach_timebase_info()
+                monotonic.factor = timebase[0] / timebase[1]
+            return _time.mach_absolute_time() * monotonic.factor
+        monotonic.factor = None
+    elif hasattr(time, "clock_gettime") and hasattr(time, "CLOCK_MONOTONIC"):
+        def monotonic():
+            if monotonic.use_monotonic_raw:
+                try:
+                    return time.clock_gettime(time.CLOCK_MONOTONIC_RAW)
+                except OSError:
+                    monotonic.use_monotonic_raw = False
+            return time.clock_gettime(time.CLOCK_MONOTONIC)
+        monotonic.use_monotonic_raw = hasattr(time, "CLOCK_MONOTONIC_RAW")
+
+time.hires()
+------------
+
+High-resolution clock. It has an unspecified starting point and may be
+adjusted. The clock starting point changes when the system is resumed after
+being suspended.
+
+Pseudo-code::
+
+    if os.name == 'nt':
+        def hires():
+            return _time.QueryPerformanceCounter()
+    elif hasattr(time, "clock_gettime") and hasattr(time, "CLOCK_REALTIME"):
+        def hires():
+            return time.clock_gettime(time.CLOCK_REALTIME)
+
+It is not available on all platforms and may raise an OSError.
+
+
+time.try_monotonic()
+--------------------
 
 This clock advances at a steady rate relative to real time. It may be adjusted.
 The reference point of the returned value is undefined so only the difference
 of consecutive calls is valid.
 
+Pseudo-code::
+
+    def try_monotonic():
+        if try_monotonic.use_monotonic:
+            try:
+                return time.monotonic()
+            except (AttributeError, OSError):
+                try_monotonic.use_monotonic = False
+        if try_monotonic.use_hires:
+            try:
+                return time.hires()
+            except (AttributeError, OSError):
+                try_monotonic.use_hires = False
+        return time.time()
+    try_monotonic.use_monotonic = True
+    try_monotonic.use_hires = True
+
+
 If available, a monotonic clock is used. The function falls back to another
 clock if the monotonic clock failed or is not available.
 
@@ -127,10 +211,6 @@
 System time
 -----------
 
-The system time can be set manually by the system administrator or
-automatically by a NTP daemon.  It can jump backward and forward, and is not
-monotonic.
-
 System time on Windows
 ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -242,19 +322,19 @@
 API design
 ==========
 
-Two functions: time.monotonic(), time.steady()
-----------------------------------------------
+Two functions: time.monotonic(), time.try_monotonic()
+-----------------------------------------------------
 
- * time.steady() falls back to another clock if no monotonic clock is not
+ * time.try_monotonic() falls back to another clock if no monotonic clock is not
    available or does not work, but it does never fail.
  * time.monotonic() is not always available and may raise OSError.
 
-One function with a flag: time.steady(strict=False)
----------------------------------------------------
+One function with a flag: time.try_monotonic(strict=False)
+----------------------------------------------------------
 
- * time.steady(strict=False) falls back to another clock if no monotonic clock
+ * time.try_monotonic(strict=False) falls back to another clock if no monotonic clock
    is not available or does not work, but it does never fail.
- * time.steady(strict=True) raises OSError if monotonic clock fails or
+ * time.try_monotonic(strict=True) raises OSError if monotonic clock fails or
    NotImplementedError if the system does not provide a monotonic clock
 
 "A keyword argument that gets passed as a constant in the caller is usually
@@ -266,10 +346,10 @@
 One function, no flag
 ---------------------
 
-time.steady() returns (time: float, is_monotonic: bool).
+time.try_monotonic() returns (time: float, is_monotonic: bool).
 
-An alternative is to use a function attribute: time.steady.monotonic. The
-attribute value would be None before the first call to time.steady().
+An alternative is to use a function attribute: time.try_monotonic.monotonic. The
+attribute value would be None before the first call to time.try_monotonic().
 
 
 Working around operating system bugs?

-- 
Repository URL: http://hg.python.org/peps


More information about the Python-checkins mailing list