[pypy-commit] pypy py3.3: Implement time.monotonic(). Windows and Darwin support untested.

mjacob noreply at buildbot.pypy.org
Sun Aug 16 16:03:41 CEST 2015


Author: Manuel Jacob <me at manueljacob.de>
Branch: py3.3
Changeset: r78996:10ea3f73852a
Date: 2015-08-16 16:03 +0200
http://bitbucket.org/pypy/pypy/changeset/10ea3f73852a/

Log:	Implement time.monotonic(). Windows and Darwin support untested.

diff --git a/pypy/module/time/__init__.py b/pypy/module/time/__init__.py
--- a/pypy/module/time/__init__.py
+++ b/pypy/module/time/__init__.py
@@ -19,6 +19,7 @@
         'strftime': 'interp_time.strftime',
         'sleep' : 'interp_time.sleep',
         '_STRUCT_TM_ITEMS': 'space.wrap(interp_time._STRUCT_TM_ITEMS)',
+        'monotonic': 'interp_time.monotonic',
     }
 
     if os.name == "posix":
diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py
--- a/pypy/module/time/interp_time.py
+++ b/pypy/module/time/interp_time.py
@@ -145,6 +145,12 @@
         ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
         ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
 
+if sys.platform == 'darwin':
+    CConfig.TIMEBASE_INFO = platform.Struct("struct mach_timebase_info", [
+        ("numer", rffi.UINT),
+        ("denom", rffi.UINT),
+    ])
+
 # XXX: optionally support the 2 additional tz fields
 _STRUCT_TM_ITEMS = 9
 
@@ -710,3 +716,38 @@
         finally:
             lltype.free(outbuf, flavor='raw')
         i += i
+
+
+if _WIN:
+    # untested so far
+    _GetTickCount64 = rwin32.winexternal('GetTickCount64', [], rffi.ULONGLONG)
+
+    def monotonic(space):
+        return space.wrap(_GetTickCount64() * 1e-3)
+
+elif sys.platform == 'darwin':
+    # untested so far
+    c_mach_timebase_info = external('mach_timebase_info',
+                                    [lltype.Ptr(TIMEBASE_INFO)], lltype.Void)
+    c_mach_absolute_time = external('mach_absolute_time', [], lltype.ULONGLONG)
+
+    timebase_info = lltype.malloc(TIMEBASE_INFO, flavor='raw', zero=True,
+                                  immortal=True)
+
+    def monotonic():
+        if timebase_info.denom == 0:
+            mach_timebase_info(timebase_info)
+        time = mach_absolute_time()
+        nanosecs = time * timebase_info.numer / timebase_info.denom
+        secs = nanosecs / 10**9
+        rest = nanosecs % 10**9
+        return space.wrap(float(secs) + float(rest) * 1e-9)
+
+else:
+    assert _POSIX
+    if cConfig.CLOCK_HIGHRES is not None:
+        def monotonic(space):
+            return clock_gettime(space, cConfig.CLOCK_HIGHRES)
+    else:
+        def monotonic(space):
+            return clock_gettime(space, cConfig.CLOCK_MONOTONIC)
diff --git a/pypy/module/time/test/test_time.py b/pypy/module/time/test/test_time.py
--- a/pypy/module/time/test/test_time.py
+++ b/pypy/module/time/test/test_time.py
@@ -358,3 +358,11 @@
         new = pickle.loads(pickle.dumps(now))
         assert new == now
         assert type(new) is type(now)
+
+    def test_monotonic(self):
+        import time
+        t1 = time.monotonic()
+        assert isinstance(t1, float)
+        time.sleep(0.02)
+        t2 = time.monotonic()
+        assert t1 < t2


More information about the pypy-commit mailing list