[pypy-svn] r75472 - pypy/trunk/pypy/rpython/module

arigo at codespeak.net arigo at codespeak.net
Sat Jun 19 17:22:06 CEST 2010


Author: arigo
Date: Sat Jun 19 17:22:04 2010
New Revision: 75472

Modified:
   pypy/trunk/pypy/rpython/module/ll_time.py
Log:
Give up using clock() directly.  It's a mess on OS/X because
depending on the includes we get a version that returns either
milliseconds or microseconds, and a different CLOCKS_PER_SEC.
But the latter is hard-coded in the C source, while the version
of clock() that will be used depends on how the C source is
linked.

Instead, use getrusage() which returns numbers as a pair of
nice 'struct timeval'.



Modified: pypy/trunk/pypy/rpython/module/ll_time.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/ll_time.py	(original)
+++ pypy/trunk/pypy/rpython/module/ll_time.py	Sat Jun 19 17:22:04 2010
@@ -17,24 +17,28 @@
     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/timeb.h']
+                'sys/types.h', 'unistd.h', 'sys/timeb.h',
+                'sys/resource.h']
+    need_rusage = True
 
 
 class CConfig:
     _compilation_info_ = ExternalCompilationInfo(
         includes=includes
     )
-    CLOCK_T = platform.SimpleType('clock_t', rffi.INT)
     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 == 'freebsd7':
     libraries = ['compat']
@@ -49,21 +53,20 @@
     TIMEB = platform.Struct(STRUCT_TIMEB, [('time', rffi.INT),
                                            ('millitm', rffi.INT)])
 
-constant_names = ['CLOCKS_PER_SEC', 'CLK_TCK', 'EINTR']
+constant_names = ['RUSAGE_SELF', 'EINTR']
 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.cast(lltype.Signed, t.c_tv_sec)) +
+            float(rffi.cast(lltype.Signed, t.c_tv_usec)) * 0.000001)
+
 class RegisterTime(BaseLazyRegistering):
     def __init__(self):
         self.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
         self.TIMEVALP = lltype.Ptr(self.TIMEVAL)
 
     @registering(time.time)
@@ -109,10 +112,7 @@
                     errcode = c_gettimeofday(t, void)
 
                 if rffi.cast(rffi.LONG, errcode) == 0:
-                    result = float(rffi.cast(lltype.Signed, t.c_tv_sec)) \
-                        + float(rffi.cast(lltype.Signed, t.c_tv_usec)) \
-                        * 0.000001
-                                 
+                    result = decode_timeval(t)
                 lltype.free(t, flavor='raw')
             if result != -1:
                 return result
@@ -129,8 +129,6 @@
 
     @registering(time.clock)
     def register_time_clock(self):
-        c_clock = self.llexternal('clock', [], self.CLOCK_T,
-                                  threadsafe=False)
         if sys.platform == 'win32':
             # hacking to avoid LARGE_INTEGER which is a union...
             A = lltype.FixedSizeArray(lltype.SignedLongLong, 1)
@@ -157,9 +155,19 @@
                 lltype.free(a, flavor='raw')
                 return float(diff) / state.divisor
         else:
+            RUSAGE = self.RUSAGE
+            RUSAGE_SELF = self.RUSAGE_SELF or 0
+            c_getrusage = self.llexternal('getrusage', 
+                                          [rffi.INT, lltype.Ptr(RUSAGE)],
+                                          lltype.Void,
+                                          threadsafe=False)
             def time_clock_llimpl():
-                result = c_clock()
-                return float(result) / self.CLOCKS_PER_SEC
+                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')



More information about the Pypy-commit mailing list