[pypy-svn] r45948 - in pypy/branch/pypy-more-rtti-inprogress: rpython rpython/module rpython/module/test translator/c

fijal at codespeak.net fijal at codespeak.net
Fri Aug 24 12:49:55 CEST 2007


Author: fijal
Date: Fri Aug 24 12:49:55 2007
New Revision: 45948

Added:
   pypy/branch/pypy-more-rtti-inprogress/rpython/module/test/test_ll_time.py   (contents, props changed)
Modified:
   pypy/branch/pypy-more-rtti-inprogress/rpython/extfuncregistry.py
   pypy/branch/pypy-more-rtti-inprogress/rpython/extfunctable.py
   pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_time.py
   pypy/branch/pypy-more-rtti-inprogress/translator/c/extfunc.py
Log:
Move time.{time, clock, sleep} into rffi. Only posix version,
I need to set up window machine to finish those. Leave ll_time.c as
a reference for windows impl.


Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/extfuncregistry.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/extfuncregistry.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/extfuncregistry.py	Fri Aug 24 12:49:55 2007
@@ -10,6 +10,7 @@
 from pypy.rpython.lltypesystem.module import ll_math
 from pypy.rpython.ootypesystem.module import ll_math as oo_math
 from pypy.rpython.module import ll_os
+from pypy.rpython.module import ll_time
 try:
     import termios
 except ImportError:

Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/extfunctable.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/extfunctable.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/extfunctable.py	Fri Aug 24 12:49:55 2007
@@ -151,9 +151,6 @@
 # external function declarations
 declare(os.path.exists, bool        , 'll_os_path/exists')
 declare(os.path.isdir, bool         , 'll_os_path/isdir')
-declare(time.time   , float         , 'll_time/time')
-declare(time.clock  , float         , 'll_time/clock')
-declare(time.sleep  , noneannotation, 'll_time/sleep')
 
 # ___________________________________________________________
 # win/NT hack: patch ntpath.isabs() to be RPythonic

Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_time.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_time.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_time.py	Fri Aug 24 12:49:55 2007
@@ -1,20 +1,140 @@
 """
-Dummy low-level implementations for the external functions of the 'time' module.
+Low-level implementations for the external functions of the 'time' module.
 """
 
-# See ll_os.py.
-
-import time
-
-
-def ll_time_time():
-    return time.time()
-ll_time_time.suggested_primitive = True
-
-def ll_time_clock():
-    return time.clock()
-ll_time_clock.suggested_primitive = True
-
-def ll_time_sleep(t):
-    time.sleep(t)
-ll_time_sleep.suggested_primitive = True
+import time, sys, math
+from pypy.rpython.lltypesystem import rffi
+from pypy.rpython.tool import rffi_platform as platform
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.extfunc import BaseLazyRegistering, registering
+
+class CConfig:
+    if sys.platform.startswith('win'):
+        includes = ['sys/time.h', 'windows.h']
+    else:
+        includes = ['time.h', 'errno.h', 'sys/select.h', 'sys/types.h',
+                    'unistd.h', 'sys/timeb.h']
+    # XXX argh, argh, argh, should be automatic
+    _header_ = "\n".join(["#include <%s>" % name for name in includes])
+    CLOCK_T = platform.SimpleType('clock_t', rffi.INT)
+    TIMEVAL = platform.Struct('struct timeval', [('tv_sec', rffi.INT),
+                                                 ('tv_usec', rffi.INT)])
+    TIMEB = platform.Struct('struct timeb', [('time', rffi.INT),
+                                             ('millitm', rffi.INT)])
+    TIME_T = platform.SimpleType('time_t', rffi.INT)
+
+constant_names = ['CLOCKS_PER_SEC', 'CLK_TCK', 'EINTR']
+for const in constant_names:
+    setattr(CConfig, const, platform.DefinedConstantInteger(const))
+defs_names = ['HAVE_FTIME', 'HAVE_GETTIMEOFDAY', 'GETTIMEOFDAY_NO_TZ']
+for const in defs_names:
+    setattr(CConfig, const, platform.Defined(const))
+
+class RegisterTime(BaseLazyRegistering):
+    def __init__(self):
+        self.__dict__.update(platform.configure(CConfig))
+        if self.CLOCKS_PER_SEC is None:
+            if self.CLK_TCK is None:
+                self.CLOCKS_PER_SEC = 1000000
+            else:
+                self.CLOCKS_PER_SEC = self.CLK_TCK
+        # XXX another to-be-automated issue
+        self.includes = CConfig.includes
+        self.TIMEVALP = lltype.Ptr(self.TIMEVAL)
+        self.TIMEBP = lltype.Ptr(self.TIMEB)
+
+    @registering(time.time)
+    def register_time_time(self):
+        if sys.platform == 'win32':
+            xxx
+        else:
+            # AWFUL
+            if self.HAVE_GETTIMEOFDAY:
+                if self.GETTIMEOFDAY_NO_TZ:
+                    c_gettimeofday = rffi.llexternal('gettimeofday',
+                                     [self.TIMEVALP], rffi.INT,
+                                     includes=self.includes)
+                else:
+                    c_gettimeofday = rffi.llexternal('gettimeofday',
+                                     [self.TIMEVALP, rffi.VOIDP], rffi.INT,
+                                     includes=self.includes)
+            else:
+                c_gettimeofday = None
+            
+            if self.HAVE_FTIME:
+                c_ftime = rffi.llexternal('ftime', [self.TIMEB], rffi.VOID,
+                                          includes=self.includes)
+            else:
+                c_ftime = None # not to confuse flow objspace
+
+            c_time = rffi.llexternal('time', [rffi.VOIDP], self.TIME_T,
+                                     includes=self.includes)
+
+            def time_time_llimpl():
+                void = lltype.nullptr(rffi.VOIDP.TO)
+                result = -1.0
+                if self.HAVE_GETTIMEOFDAY:
+                    t = lltype.malloc(self.TIMEVAL, flavor='raw')
+
+                    if self.GETTIMEOFDAY_NO_TZ:
+                        if c_gettimeofday(t) == 0:
+                            result = float(t.c_tv_sec) + \
+                                     float(t.c_tv_usec) * 0.000001
+                    else:
+                        if c_gettimeofday(t, void) == 0:
+                            result = float(t.c_tv_sec) + \
+                                     float(t.c_tv_usec) * 0.000001
+                    lltype.free(t, flavor='raw')
+                if result != -1:
+                    return result
+                if self.HAVE_FTIME:
+                    t = lltype.malloc(self.TIMEB, flavor='raw')
+                    c_ftime(t)
+                    result = float(t.c_time) + float(t.c_millitm) * 0.001
+                    lltype.free(t, flavor='raw')
+                    return result
+                return float(c_time(void))
+        self.register(time.time, [], float, llimpl=time_time_llimpl,
+                      export_name='ll_time.time')
+
+    @registering(time.clock)
+    def register_time_clock(self):
+        c_clock = rffi.llexternal('clock', [], self.CLOCK_T,
+                                  includes=self.includes)
+        
+        if sys.platform == 'win32':
+            xxx
+        else:
+            def time_clock_llimpl():
+                result = c_clock()
+                return float(result) / self.CLOCKS_PER_SEC
+        self.register(time.clock, [], float, llimpl=time_clock_llimpl,
+                      export_name='ll_time.clock')
+
+    @registering(time.sleep)
+    def register_time_sleep(self):
+        if sys.platform == 'win32':
+            xxx
+        else:
+            c_select = rffi.llexternal('select', [rffi.INT, rffi.VOIDP,
+                                                  rffi.VOIDP, rffi.VOIDP,
+                                                  self.TIMEVALP],
+                                       rffi.INT, includes=self.includes)
+            
+            def time_sleep_llimpl(secs):
+                # XXX cannot put it into try: finally: because
+                # someone forgotten to call hop.exception_is_here
+                void = lltype.nullptr(rffi.VOIDP.TO)
+                t = lltype.malloc(self.TIMEVAL, flavor='raw')
+                #try:
+                frac = secs % 1.0
+                t.c_tv_sec = int(secs)
+                t.c_tv_usec = int(frac*1000000.0)
+                if c_select(0, void, void, void, t) != 0:
+                    # XXX EINTR
+                    lltype.free(t, flavor='raw')
+                    raise IOError("Select failed")
+                #finally:
+                lltype.free(t, flavor='raw')
+        self.register(time.sleep, [float], None, llimpl=time_sleep_llimpl,
+                      export_name='ll_time.sleep')

Added: pypy/branch/pypy-more-rtti-inprogress/rpython/module/test/test_ll_time.py
==============================================================================
--- (empty file)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/module/test/test_ll_time.py	Fri Aug 24 12:49:55 2007
@@ -0,0 +1,48 @@
+
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+#from pypy.translator.c.test.test_genc import compile
+
+import time
+
+class BaseTestTime(BaseRtypingTest):
+    def test_time_time(self):
+        def fn():
+            return time.time()
+        
+        t0 = time.time()
+        res = self.interpret(fn, [])
+        t1 = time.time()
+        assert t0 <= res <= t1
+
+    def test_time_clock(self):
+        def f():
+            return time.clock()
+        t0 = time.clock()
+        t1 = self.interpret(f, [])
+        t2 = time.clock()
+        t3 = self.interpret(f, [])
+        t4 = time.clock()
+        t5 = self.interpret(f, [])
+        t6 = time.clock()
+        # time.clock() and t1() might have a different notion of zero, so
+        # we can only subtract two numbers returned by the same function.
+        assert 0 <= t2-t0
+        assert 0 <= t3-t1 <= t4-t0
+        assert 0 <= t4-t2 <= t5-t1 <= t6-t0
+        assert 0 <= t5-t3 <= t6-t2
+        assert 0 <= t6-t4
+
+    def test_time_sleep(self):
+        def does_nothing():
+            time.sleep(0.19)
+        t0 = time.time()
+        self.interpret(does_nothing, [])
+        t1 = time.time()
+        assert t0 <= t1
+        assert t1 - t0 >= 0.15
+
+class TestLLType(BaseTestTime, LLRtypeMixin):
+    pass
+
+class TestOOType(BaseTestTime, OORtypeMixin):
+    pass

Modified: pypy/branch/pypy-more-rtti-inprogress/translator/c/extfunc.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/c/extfunc.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/c/extfunc.py	Fri Aug 24 12:49:55 2007
@@ -19,9 +19,6 @@
 # references to functions, so we cannot insert classmethods here.
 
 EXTERNALS = {
-    ll_time.ll_time_clock: 'LL_time_clock',
-    ll_time.ll_time_sleep: 'LL_time_sleep',
-    ll_time.ll_time_time:  'LL_time_time',
     ll_strtod.Implementation.ll_strtod_parts_to_float:
         'LL_strtod_parts_to_float',
     ll_strtod.Implementation.ll_strtod_formatd:



More information about the Pypy-commit mailing list