[pypy-commit] pypy default: Move clock_{gettime, getres, settime} entirely to rpython/rlib/rtime, with tests

arigo pypy.commits at gmail.com
Sat Oct 1 04:37:05 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r87483:fbace1f687b0
Date: 2016-10-01 10:25 +0200
http://bitbucket.org/pypy/pypy/changeset/fbace1f687b0/

Log:	Move clock_{gettime,getres,settime} entirely to rpython/rlib/rtime,
	with tests

diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -67,10 +67,17 @@
         includes=['time.h'],
         libraries=libraries
     )
+    _NO_MISSING_RT = rffi_platform.Has('printf("%d", clock_gettime(0, 0))')
     TIMESPEC = rffi_platform.Struct('struct timespec', [('tv_sec', rffi.LONG),
                                                         ('tv_nsec', rffi.LONG)])
 
-constant_names = ['RUSAGE_SELF', 'EINTR', 'CLOCK_PROCESS_CPUTIME_ID']
+constant_names = ['RUSAGE_SELF', 'EINTR',
+                  'CLOCK_REALTIME',
+                  'CLOCK_MONOTONIC',
+                  'CLOCK_MONOTONIC_RAW',
+                  'CLOCK_PROCESS_CPUTIME_ID',
+                  'CLOCK_THREAD_CPUTIME_ID',
+]
 for const in constant_names:
     setattr(CConfig, const, rffi_platform.DefinedConstantInteger(const))
 defs_names = ['GETTIMEOFDAY_NO_TZ']
@@ -158,16 +165,33 @@
         divisor = 0.0
         counter_start = 0
     state = State()
-elif CLOCK_PROCESS_CPUTIME_ID is not None:
+
+HAS_CLOCK_GETTIME = (CLOCK_MONOTONIC is not None)
+if HAS_CLOCK_GETTIME:
     # Linux and other POSIX systems with clock_gettime()
+    # TIMESPEC:
     globals().update(rffi_platform.configure(CConfigForClockGetTime))
-    TIMESPEC = TIMESPEC
-    CLOCK_PROCESS_CPUTIME_ID = CLOCK_PROCESS_CPUTIME_ID
-    eci_with_lrt = eci.merge(ExternalCompilationInfo(libraries=['rt']))
+    # do we need to add -lrt?
+    eciclock = CConfigForClockGetTime._compilation_info_
+    if not _NO_MISSING_RT:
+        eciclock = eciclock.merge(ExternalCompilationInfo(libraries=['rt']))
+    # the functions:
+    c_clock_getres = external("clock_getres",
+                              [lltype.Signed, lltype.Ptr(TIMESPEC)],
+                              rffi.INT, releasegil=False,
+                              save_err=rffi.RFFI_SAVE_ERRNO,
+                              compilation_info=eciclock)
     c_clock_gettime = external('clock_gettime',
                                [lltype.Signed, lltype.Ptr(TIMESPEC)],
                                rffi.INT, releasegil=False,
-                               compilation_info=eci_with_lrt)
+                               save_err=rffi.RFFI_SAVE_ERRNO,
+                               compilation_info=eciclock)
+    c_clock_settime = external('clock_settime',
+                               [lltype.Signed, lltype.Ptr(TIMESPEC)],
+                               rffi.INT, releasegil=False,
+                               save_err=rffi.RFFI_SAVE_ERRNO,
+                               compilation_info=eciclock)
+
 if need_rusage:
     RUSAGE = RUSAGE
     RUSAGE_SELF = RUSAGE_SELF or 0
@@ -191,18 +215,16 @@
 def clock():
     if _WIN32:
         return win_perf_counter()
-    elif CLOCK_PROCESS_CPUTIME_ID is not None:
+    elif HAS_CLOCK_GETTIME and CLOCK_PROCESS_CPUTIME_ID is not None:
         with lltype.scoped_alloc(TIMESPEC) as a:
-            c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a)
-            result = (float(rffi.getintfield(a, 'c_tv_sec')) +
-                      float(rffi.getintfield(a, 'c_tv_nsec')) * 0.000000001)
-        return result
-    else:
-        with lltype.scoped_alloc(RUSAGE) as a:
-            c_getrusage(RUSAGE_SELF, a)
-            result = (decode_timeval(a.c_ru_utime) +
-                      decode_timeval(a.c_ru_stime))
-        return result
+            if c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a) == 0:
+                return (float(rffi.getintfield(a, 'c_tv_sec')) +
+                        float(rffi.getintfield(a, 'c_tv_nsec')) * 0.000000001)
+    with lltype.scoped_alloc(RUSAGE) as a:
+        c_getrusage(RUSAGE_SELF, a)
+        result = (decode_timeval(a.c_ru_utime) +
+                  decode_timeval(a.c_ru_stime))
+    return result
 
 # _______________________________________________________________
 # time.sleep()
diff --git a/rpython/rlib/test/test_rtime.py b/rpython/rlib/test/test_rtime.py
--- a/rpython/rlib/test/test_rtime.py
+++ b/rpython/rlib/test/test_rtime.py
@@ -1,7 +1,9 @@
 
 from rpython.rtyper.test.tool import BaseRtypingTest
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib import rtime
 
-import time, sys
+import time, sys, py
 
 class TestTime(BaseRtypingTest):
     def test_time_time(self):
@@ -53,3 +55,27 @@
         t1 = time.time()
         assert t0 <= t1
         assert t1 - t0 >= 0.15
+
+    def test_clock_gettime(self):
+        if not rtime.HAS_CLOCK_GETTIME:
+            py.test.skip("no clock_gettime()")
+        lst = []
+        for i in range(50):
+            with lltype.scoped_alloc(rtime.TIMESPEC) as a1:
+                res = rtime.c_clock_gettime(rtime.CLOCK_MONOTONIC, a1)
+                assert res == 0
+                t = (float(rffi.getintfield(a1, 'c_tv_sec')) +
+                     float(rffi.getintfield(a1, 'c_tv_nsec')) * 0.000000001)
+                lst.append(t)
+        assert lst == sorted(lst)
+
+    def test_clock_getres(self):
+        if not rtime.HAS_CLOCK_GETTIME:
+            py.test.skip("no clock_gettime()")
+        lst = []
+        with lltype.scoped_alloc(rtime.TIMESPEC) as a1:
+            res = rtime.c_clock_getres(rtime.CLOCK_MONOTONIC, a1)
+            assert res == 0
+            t = (float(rffi.getintfield(a1, 'c_tv_sec')) +
+                 float(rffi.getintfield(a1, 'c_tv_nsec')) * 0.000000001)
+        assert 0.0 < t <= 1.0


More information about the pypy-commit mailing list