Author: Amaury Forgeot d'Arc <amaur...@gmail.com>
Branch: more-rposix
Changeset: r77011:4aa53f36a6e2
Date: 2015-05-02 00:03 +0200
http://bitbucket.org/pypy/pypy/changeset/4aa53f36a6e2/

Log:    Move module/ll_time.py to rlib/rtime.py

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
@@ -4,6 +4,7 @@
 from pypy.interpreter.gateway import unwrap_spec
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rlib.rarithmetic import intmask
+from rpython.rlib import rtime  # Register functions
 from rpython.rlib import rposix
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 import os
@@ -482,13 +483,6 @@
     secs = pytime.time()
     return space.wrap(secs)
 
-if _WIN:
-    class PCCache:
-        pass
-    pccache = PCCache()
-    pccache.divisor = 0.0
-    pccache.ctrStart = 0
-
 def clock(space):
     """clock() -> floating point number
 
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rtime.py
@@ -0,0 +1,233 @@
+"""
+RPython implementations of time.time(), time.clock(), time.select().
+"""
+
+import sys
+import math
+import time as pytime
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.rtyper.tool import rffi_platform
+from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.objectmodel import register_replacement_for
+from rpython.rlib import rposix
+
+_WIN32 = sys.platform.startswith('win')
+
+if _WIN32:
+    TIME_H = 'time.h'
+    FTIME = '_ftime64'
+    STRUCT_TIMEB = 'struct __timeb64'
+    includes = ['winsock2.h', 'windows.h',
+                TIME_H, 'sys/types.h', 'sys/timeb.h']
+    need_rusage = False
+else:
+    TIME_H = 'sys/time.h'
+    FTIME = 'ftime'
+    STRUCT_TIMEB = 'struct timeb'
+    includes = [TIME_H, 'time.h', 'errno.h', 'sys/select.h',
+                'sys/types.h', 'unistd.h',
+                'sys/time.h', 'sys/resource.h']
+
+    if not sys.platform.startswith("openbsd"):
+        includes.append('sys/timeb.h')
+
+    need_rusage = True
+
+
+eci = ExternalCompilationInfo(includes=includes)
+
+class CConfig:
+    _compilation_info_ = eci
+    TIMEVAL = rffi_platform.Struct('struct timeval', [('tv_sec', rffi.INT),
+                                                      ('tv_usec', rffi.INT)])
+    HAVE_GETTIMEOFDAY = rffi_platform.Has('gettimeofday')
+    HAVE_FTIME = rffi_platform.Has(FTIME)
+    if need_rusage:
+        RUSAGE = rffi_platform.Struct('struct rusage', [('ru_utime', TIMEVAL),
+                                                        ('ru_stime', TIMEVAL)])
+
+if sys.platform.startswith('freebsd') or sys.platform.startswith('netbsd'):
+    libraries = ['compat']
+elif sys.platform == 'linux2':
+    libraries = ['rt']
+else:
+    libraries = []
+
+class CConfigForFTime:
+    _compilation_info_ = ExternalCompilationInfo(
+        includes=[TIME_H, 'sys/timeb.h'],
+        libraries=libraries
+    )
+    TIMEB = rffi_platform.Struct(STRUCT_TIMEB, [('time', rffi.INT),
+                                                ('millitm', rffi.INT)])
+
+class CConfigForClockGetTime:
+    _compilation_info_ = ExternalCompilationInfo(
+        includes=['time.h'],
+        libraries=libraries
+    )
+    TIMESPEC = rffi_platform.Struct('struct timespec', [('tv_sec', rffi.LONG),
+                                                        ('tv_nsec', 
rffi.LONG)])
+
+constant_names = ['RUSAGE_SELF', 'EINTR', 'CLOCK_PROCESS_CPUTIME_ID']
+for const in constant_names:
+    setattr(CConfig, const, rffi_platform.DefinedConstantInteger(const))
+defs_names = ['GETTIMEOFDAY_NO_TZ']
+for const in defs_names:
+    setattr(CConfig, const, rffi_platform.Defined(const))
+
+def decode_timeval(t):
+    return (float(rffi.getintfield(t, 'c_tv_sec')) +
+            float(rffi.getintfield(t, 'c_tv_usec')) * 0.000001)
+
+
+def external(name, args, result, compilation_info=eci, **kwds):
+    return rffi.llexternal(name, args, result,
+                           compilation_info=compilation_info, **kwds)
+
+def replace_time_function(name):
+    func = getattr(pytime, name, None)
+    if func is None:
+        return lambda f: f
+    return register_replacement_for(
+        func,
+        sandboxed_name='ll_time.ll_time_%s' % name)
+
+config = rffi_platform.configure(CConfig)
+globals().update(config)
+
+# Note: time.time() is used by the framework GC during collect(),
+# which means that we have to be very careful about not allocating
+# GC memory here.  This is the reason for the _nowrapper=True.
+if HAVE_GETTIMEOFDAY:
+    if GETTIMEOFDAY_NO_TZ:
+        c_gettimeofday = external('gettimeofday',
+                                  [lltype.Ptr(TIMEVAL)], rffi.INT,
+                                  _nowrapper=True, releasegil=False)
+    else:
+        c_gettimeofday = external('gettimeofday',
+                                  [lltype.Ptr(TIMEVAL), rffi.VOIDP], rffi.INT,
+                                  _nowrapper=True, releasegil=False)
+if HAVE_FTIME:
+    globals().update(rffi_platform.configure(CConfigForFTime))
+    c_ftime = external(FTIME, [lltype.Ptr(TIMEB)],
+                         lltype.Void,
+                         _nowrapper=True, releasegil=False)
+c_time = external('time', [rffi.VOIDP], rffi.TIME_T,
+                  _nowrapper=True, releasegil=False)
+
+
+@replace_time_function('time')
+def time():
+    void = lltype.nullptr(rffi.VOIDP.TO)
+    result = -1.0
+    if HAVE_GETTIMEOFDAY:
+        with lltype.scoped_alloc(TIMEVAL) as t:
+            errcode = -1
+            if GETTIMEOFDAY_NO_TZ:
+                errcode = c_gettimeofday(t)
+            else:
+                errcode = c_gettimeofday(t, void)
+
+            if rffi.cast(rffi.LONG, errcode) == 0:
+                result = decode_timeval(t)
+        if result != -1:
+            return result
+    else: # assume using ftime(3)
+        t = lltype.malloc(TIMEB, flavor='raw')
+        c_ftime(t)
+        result = (float(intmask(t.c_time)) +
+                  float(intmask(t.c_millitm)) * 0.001)
+        lltype.free(t, flavor='raw')
+        return result
+    return float(c_time(void))
+
+
+# _______________________________________________________________
+# time.clock()
+
+if _WIN32:
+    # hacking to avoid LARGE_INTEGER which is a union...
+    A = lltype.FixedSizeArray(lltype.SignedLongLong, 1)
+    QueryPerformanceCounter = external(
+        'QueryPerformanceCounter', [lltype.Ptr(A)], lltype.Void,
+        releasegil=False)
+    QueryPerformanceFrequency = self.llexternal(
+        'QueryPerformanceFrequency', [lltype.Ptr(A)], rffi.INT,
+        releasegil=False)
+    class State(object):
+        divisor = 0.0
+        counter_start = 0
+    state = State()
+elif CLOCK_PROCESS_CPUTIME_ID is not None:
+    # Linux and other POSIX systems with clock_gettime()
+    globals().update(rffi_platform.configure(CConfigForClockGetTime))
+    TIMESPEC = TIMESPEC
+    CLOCK_PROCESS_CPUTIME_ID = CLOCK_PROCESS_CPUTIME_ID
+    c_clock_gettime = external('clock_gettime',
+                               [lltype.Signed, lltype.Ptr(TIMESPEC)],
+                               rffi.INT, releasegil=False)
+else:
+    RUSAGE = self.RUSAGE
+    RUSAGE_SELF = self.RUSAGE_SELF or 0
+    c_getrusage = self.llexternal('getrusage', 
+                                  [rffi.INT, lltype.Ptr(RUSAGE)],
+                                  lltype.Void,
+                                  releasegil=False)
+
+@replace_time_function('clock')
+def clock():
+    if _WIN32:
+        a = lltype.malloc(A, flavor='raw')
+        if state.divisor == 0.0:
+            QueryPerformanceCounter(a)
+            state.counter_start = a[0]
+            QueryPerformanceFrequency(a)
+            state.divisor = float(a[0])
+        QueryPerformanceCounter(a)
+        diff = a[0] - state.counter_start
+        lltype.free(a, flavor='raw')
+        return float(diff) / state.divisor
+    elif 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
+
+# _______________________________________________________________
+# time.sleep()
+
+if _WIN32:
+    Sleep = external('Sleep', [rffi.ULONG], lltype.Void)
+else:
+    c_select = external('select', [rffi.INT, rffi.VOIDP,
+                                   rffi.VOIDP, rffi.VOIDP,
+                                   lltype.Ptr(TIMEVAL)], rffi.INT,
+                        save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_time_function('sleep')
+def sleep(secs):
+    if _WIN32:
+        millisecs = secs * 1000.0
+        while millisecs > UINT_MAX:
+            Sleep(UINT_MAX)
+            millisecs -= UINT_MAX
+        Sleep(rffi.cast(rffi.ULONG, int(millisecs)))
+    else:
+        void = lltype.nullptr(rffi.VOIDP.TO)
+        with lltype.scoped_alloc(TIMEVAL) as t:
+            frac = math.fmod(secs, 1.0)
+            rffi.setintfield(t, 'c_tv_sec', int(secs))
+            rffi.setintfield(t, 'c_tv_usec', int(frac*1000000.0))
+
+            if rffi.cast(rffi.LONG, c_select(0, void, void, void, t)) != 0:
+                errno = rposix.get_saved_errno()
+                if errno != EINTR:
+                    raise OSError(errno, "Select failed")
diff --git a/rpython/rtyper/module/test/test_ll_time.py 
b/rpython/rlib/test/test_rtime.py
rename from rpython/rtyper/module/test/test_ll_time.py
rename to rpython/rlib/test/test_rtime.py
--- a/rpython/rtyper/module/test/test_ll_time.py
+++ b/rpython/rlib/test/test_rtime.py
@@ -1,6 +1,6 @@
 
 from rpython.rtyper.test.tool import BaseRtypingTest
-#from rpython.translator.c.test.test_genc import compile
+from rpython.rlib import rtime  # Register functions
 
 import time, sys
 
diff --git a/rpython/rtyper/extfuncregistry.py 
b/rpython/rtyper/extfuncregistry.py
--- a/rpython/rtyper/extfuncregistry.py
+++ b/rpython/rtyper/extfuncregistry.py
@@ -7,7 +7,6 @@
 
 import math
 from rpython.rtyper.lltypesystem.module import ll_math
-from rpython.rtyper.module import ll_time
 from rpython.rlib import rfloat
 
 # the following functions all take one float, return one float
diff --git a/rpython/rtyper/module/ll_time.py b/rpython/rtyper/module/ll_time.py
deleted file mode 100644
--- a/rpython/rtyper/module/ll_time.py
+++ /dev/null
@@ -1,239 +0,0 @@
-"""
-Low-level implementations for the external functions of the 'time' module.
-"""
-
-import time, sys, math
-from errno import EINTR
-from rpython.rtyper.lltypesystem import rffi
-from rpython.rtyper.tool import rffi_platform as platform
-from rpython.rtyper.lltypesystem import lltype
-from rpython.rtyper.extfunc import BaseLazyRegistering, registering, extdef
-from rpython.rlib import rposix
-from rpython.rlib.rarithmetic import intmask, UINT_MAX
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-
-if sys.platform == 'win32':
-    TIME_H = 'time.h'
-    FTIME = '_ftime64'
-    STRUCT_TIMEB = 'struct __timeb64'
-    includes = ['winsock2.h', 'windows.h',
-                TIME_H, 'sys/types.h', 'sys/timeb.h']
-    need_rusage = False
-else:
-    TIME_H = 'sys/time.h'
-    FTIME = 'ftime'
-    STRUCT_TIMEB = 'struct timeb'
-    includes = [TIME_H, 'time.h', 'errno.h', 'sys/select.h',
-                'sys/types.h', 'unistd.h',
-                'sys/time.h', 'sys/resource.h']
-
-    if not sys.platform.startswith("openbsd"):
-        includes.append('sys/timeb.h')
-
-    need_rusage = True
-
-
-class CConfig:
-    _compilation_info_ = ExternalCompilationInfo(
-        includes=includes
-    )
-    TIMEVAL = platform.Struct('struct timeval', [('tv_sec', rffi.INT),
-                                                 ('tv_usec', rffi.INT)])
-    HAVE_GETTIMEOFDAY = platform.Has('gettimeofday')
-    HAVE_FTIME = platform.Has(FTIME)
-    if need_rusage:
-        RUSAGE = platform.Struct('struct rusage', [('ru_utime', TIMEVAL),
-                                                   ('ru_stime', TIMEVAL)])
-
-if sys.platform.startswith('freebsd') or sys.platform.startswith('netbsd'):
-    libraries = ['compat']
-elif sys.platform == 'linux2':
-    libraries = ['rt']
-else:
-    libraries = []
-
-class CConfigForFTime:
-    _compilation_info_ = ExternalCompilationInfo(
-        includes=[TIME_H, 'sys/timeb.h'],
-        libraries=libraries
-    )
-    TIMEB = platform.Struct(STRUCT_TIMEB, [('time', rffi.INT),
-                                           ('millitm', rffi.INT)])
-
-class CConfigForClockGetTime:
-    _compilation_info_ = ExternalCompilationInfo(
-        includes=['time.h'],
-        libraries=libraries
-    )
-    TIMESPEC = platform.Struct('struct timespec', [('tv_sec', rffi.LONG),
-                                                   ('tv_nsec', rffi.LONG)])
-
-constant_names = ['RUSAGE_SELF', 'EINTR', 'CLOCK_PROCESS_CPUTIME_ID']
-for const in constant_names:
-    setattr(CConfig, const, platform.DefinedConstantInteger(const))
-defs_names = ['GETTIMEOFDAY_NO_TZ']
-for const in defs_names:
-    setattr(CConfig, const, platform.Defined(const))
-
-def decode_timeval(t):
-    return (float(rffi.getintfield(t, 'c_tv_sec')) +
-            float(rffi.getintfield(t, 'c_tv_usec')) * 0.000001)
-
-class RegisterTime(BaseLazyRegistering):
-    def __init__(self):
-        self.configure(CConfig)
-        self.TIMEVALP = lltype.Ptr(self.TIMEVAL)
-
-    @registering(time.time)
-    def register_time_time(self):
-        # Note: time.time() is used by the framework GC during collect(),
-        # which means that we have to be very careful about not allocating
-        # GC memory here.  This is the reason for the _nowrapper=True.
-
-        # AWFUL
-        if self.HAVE_GETTIMEOFDAY:
-            if self.GETTIMEOFDAY_NO_TZ:
-                c_gettimeofday = self.llexternal('gettimeofday',
-                                 [self.TIMEVALP], rffi.INT,
-                                  _nowrapper=True, releasegil=False)
-            else:
-                c_gettimeofday = self.llexternal('gettimeofday',
-                                 [self.TIMEVALP, rffi.VOIDP], rffi.INT,
-                                  _nowrapper=True, releasegil=False)
-            c_ftime = None # We have gettimeofday(2), so force ftime(3) OFF.
-        else:
-            c_gettimeofday = None
-
-            # Only look for ftime(3) if gettimeofday(2) was not found.
-            if self.HAVE_FTIME:
-                self.configure(CConfigForFTime)
-                c_ftime = self.llexternal(FTIME, [lltype.Ptr(self.TIMEB)],
-                                          lltype.Void,
-                                          _nowrapper=True, releasegil=False)
-            else:
-                c_ftime = None    # to not confuse the flow space
-
-        c_time = self.llexternal('time', [rffi.VOIDP], rffi.TIME_T,
-                                 _nowrapper=True, releasegil=False)
-
-        def time_time_llimpl():
-            void = lltype.nullptr(rffi.VOIDP.TO)
-            result = -1.0
-            if self.HAVE_GETTIMEOFDAY:
-                t = lltype.malloc(self.TIMEVAL, flavor='raw')
-
-                errcode = -1
-                if self.GETTIMEOFDAY_NO_TZ:
-                    errcode = c_gettimeofday(t)
-                else:
-                    errcode = c_gettimeofday(t, void)
-
-                if rffi.cast(rffi.LONG, errcode) == 0:
-                    result = decode_timeval(t)
-                lltype.free(t, flavor='raw')
-                if result != -1:
-                    return result
-            else: # assume using ftime(3)
-                t = lltype.malloc(self.TIMEB, flavor='raw')
-                c_ftime(t)
-                result = (float(intmask(t.c_time)) +
-                          float(intmask(t.c_millitm)) * 0.001)
-                lltype.free(t, flavor='raw')
-                return result
-            return float(c_time(void))
-
-        return extdef([], float, llimpl=time_time_llimpl,
-                      export_name='ll_time.ll_time_time')
-
-    @registering(time.clock)
-    def register_time_clock(self):
-        if sys.platform == 'win32':
-            # hacking to avoid LARGE_INTEGER which is a union...
-            A = lltype.FixedSizeArray(lltype.SignedLongLong, 1)
-            QueryPerformanceCounter = self.llexternal(
-                'QueryPerformanceCounter', [lltype.Ptr(A)], lltype.Void,
-                releasegil=False)
-            QueryPerformanceFrequency = self.llexternal(
-                'QueryPerformanceFrequency', [lltype.Ptr(A)], rffi.INT,
-                releasegil=False)
-            class State(object):
-                pass
-            state = State()
-            state.divisor = 0.0
-            state.counter_start = 0
-            def time_clock_llimpl():
-                a = lltype.malloc(A, flavor='raw')
-                if state.divisor == 0.0:
-                    QueryPerformanceCounter(a)
-                    state.counter_start = a[0]
-                    QueryPerformanceFrequency(a)
-                    state.divisor = float(a[0])
-                QueryPerformanceCounter(a)
-                diff = a[0] - state.counter_start
-                lltype.free(a, flavor='raw')
-                return float(diff) / state.divisor
-        elif self.CLOCK_PROCESS_CPUTIME_ID is not None:
-            # Linux and other POSIX systems with clock_gettime()
-            self.configure(CConfigForClockGetTime)
-            TIMESPEC = self.TIMESPEC
-            CLOCK_PROCESS_CPUTIME_ID = self.CLOCK_PROCESS_CPUTIME_ID
-            c_clock_gettime = self.llexternal('clock_gettime',
-                [lltype.Signed, lltype.Ptr(TIMESPEC)],
-                rffi.INT, releasegil=False)
-            def time_clock_llimpl():
-                a = lltype.malloc(TIMESPEC, flavor='raw')
-                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)
-                lltype.free(a, flavor='raw')
-                return result
-        else:
-            RUSAGE = self.RUSAGE
-            RUSAGE_SELF = self.RUSAGE_SELF or 0
-            c_getrusage = self.llexternal('getrusage', 
-                                          [rffi.INT, lltype.Ptr(RUSAGE)],
-                                          lltype.Void,
-                                          releasegil=False)
-            def time_clock_llimpl():
-                a = lltype.malloc(RUSAGE, flavor='raw')
-                c_getrusage(RUSAGE_SELF, a)
-                result = (decode_timeval(a.c_ru_utime) +
-                          decode_timeval(a.c_ru_stime))
-                lltype.free(a, flavor='raw')
-                return result
-
-        return extdef([], float, llimpl=time_clock_llimpl,
-                      export_name='ll_time.ll_time_clock')
-
-    @registering(time.sleep)
-    def register_time_sleep(self):
-        if sys.platform == 'win32':
-            Sleep = self.llexternal('Sleep', [rffi.ULONG], lltype.Void)
-            def time_sleep_llimpl(secs):
-                millisecs = secs * 1000.0
-                while millisecs > UINT_MAX:
-                    Sleep(UINT_MAX)
-                    millisecs -= UINT_MAX
-                Sleep(rffi.cast(rffi.ULONG, int(millisecs)))
-        else:
-            c_select = self.llexternal('select', [rffi.INT, rffi.VOIDP,
-                                                  rffi.VOIDP, rffi.VOIDP,
-                                                  self.TIMEVALP], rffi.INT,
-                                       save_err=rffi.RFFI_SAVE_ERRNO)
-            def time_sleep_llimpl(secs):
-                void = lltype.nullptr(rffi.VOIDP.TO)
-                t = lltype.malloc(self.TIMEVAL, flavor='raw')
-                try:
-                    frac = math.fmod(secs, 1.0)
-                    rffi.setintfield(t, 'c_tv_sec', int(secs))
-                    rffi.setintfield(t, 'c_tv_usec', int(frac*1000000.0))
-
-                    if rffi.cast(rffi.LONG, c_select(0, void, void, void, t)) 
!= 0:
-                        errno = rposix.get_saved_errno()
-                        if errno != EINTR:
-                            raise OSError(errno, "Select failed")
-                finally:
-                    lltype.free(t, flavor='raw')
-
-        return extdef([float], None, llimpl=time_sleep_llimpl,
-                      export_name='ll_time.ll_time_sleep')
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to