[pypy-commit] pypy py3k: Merged in marky1991/pypy_new/py3k (pull request #454)

pjenvey pypy.commits at gmail.com
Mon Jun 20 18:16:18 EDT 2016


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r85294:ba36ebd247e1
Date: 2016-06-20 15:15 -0700
http://bitbucket.org/pypy/pypy/changeset/ba36ebd247e1/

Log:	Merged in marky1991/pypy_new/py3k (pull request #454)

	Py3k: Update Fallback Code in Time to Match CPython

diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -418,7 +418,7 @@
     RegrTest('test_threading.py', usemodules="thread", core=True),
     RegrTest('test_threading_local.py', usemodules="thread", core=True),
     RegrTest('test_threadsignals.py', usemodules="thread"),
-    RegrTest('test_time.py', core=True, usemodules="struct"),
+    RegrTest('test_time.py', core=True, usemodules="struct thread _rawffi"),
     RegrTest('test_timeit.py'),
     RegrTest('test_timeout.py'),
     RegrTest('test_tk.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
@@ -3,8 +3,10 @@
 from pypy.interpreter.error import OperationError, oefmt, strerror as _strerror, exception_from_saved_errno
 from pypy.interpreter.gateway import unwrap_spec
 from rpython.rtyper.lltypesystem import lltype
-from rpython.rlib.rarithmetic import intmask
-from rpython.rlib.rtime import win_perf_counter
+from rpython.rlib.rarithmetic import intmask, r_ulonglong, r_longfloat
+from rpython.rlib.rtime import (win_perf_counter, TIMEB, c_ftime,
+                                GETTIMEOFDAY_NO_TZ, TIMEVAL,
+                                HAVE_GETTIMEOFDAY, HAVE_FTIME)
 from rpython.rlib import rposix, rtime
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 import math
@@ -81,16 +83,6 @@
         [rffi.VOIDP],
         rffi.ULONGLONG, compilation_info=eci)
 
-    from rpython.rlib.rdynload import GetModuleHandle, dlsym
-    hKernel32 = GetModuleHandle("KERNEL32")
-    try:
-        _GetTickCount64_handle = dlsym(hKernel32, 'GetTickCount64')
-        def _GetTickCount64():
-            return pypy_GetTickCount64(_GetTickCount64_handle)
-    except KeyError:
-        _GetTickCount64_handle = lltype.nullptr(rffi.VOIDP.TO)
-
-    HAS_GETTICKCOUNT64 = _GetTickCount64_handle != lltype.nullptr(rffi.VOIDP.TO)
     class GlobalState:
         def __init__(self):
             self.init()
@@ -126,13 +118,31 @@
         def get_interrupt_event(self):
             return globalState.interrupt_event
 
-    # XXX: Can I just use one of the state classes above?
-    # I don't really get why an instance is better than a plain module
-    # attr, but following advice from armin
     class TimeState(object):
+        GetTickCount64_handle = lltype.nullptr(rffi.VOIDP.TO)
         def __init__(self):
             self.n_overflow = 0
             self.last_ticks = 0
+
+        def check_GetTickCount64(self, *args):
+            if (self.GetTickCount64_handle !=
+                lltype.nullptr(rffi.VOIDP.TO)):
+                return True
+            from rpython.rlib.rdynload import GetModuleHandle, dlsym
+            hKernel32 = GetModuleHandle("KERNEL32")
+            try:
+                GetTickCount64_handle = dlsym(hKernel32, 'GetTickCount64')
+            except KeyError:
+                return False
+            self.GetTickCount64_handle = GetTickCount64_handle
+            return True
+
+        def GetTickCount64(self, *args):
+            assert (self.GetTickCount64_handle !=
+                    lltype.nullptr(rffi.VOIDP.TO))
+            return pypy_GetTickCount64(
+                self.GetTickCount64_handle, *args)
+
     time_state = TimeState()
 
 _includes = ["time.h"]
@@ -182,13 +192,6 @@
         ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
         ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
 
-    # TODO: Figure out how to implement this...
-    CConfig.ULARGE_INTEGER = platform.Struct("struct ULARGE_INTEGER", [
-        ("tm_sec", rffi.INT),
-        ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
-        ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
-        ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
-
 if _MACOSX:
     CConfig.TIMEBASE_INFO = platform.Struct("struct mach_timebase_info", [
         ("numer", rffi.UINT),
@@ -228,35 +231,75 @@
 tm = cConfig.tm
 glob_buf = lltype.malloc(tm, flavor='raw', zero=True, immortal=True)
 
-if cConfig.has_gettimeofday:
-    c_gettimeofday = external('gettimeofday',
-                              [cConfig.timeval, rffi.VOIDP], rffi.INT)
-    if _WIN:
-        GetSystemTimeAsFileTime = external('GetSystemTimeAsFileTime',
-                                           [rwin32.FILETIME],
-                                           lltype.VOID)
-        def gettimeofday(space, w_info=None):
-            with lltype.scoped_alloc(rwin32.FILETIME) as system_time:
-                GetSystemTimeAsFileTime(system_time)
-                # XXX:
-                #seconds = float(timeval.tv_sec) + timeval.tv_usec * 1e-6
-                # XXX: w_info
-            return space.w_None
-    else:
-        def gettimeofday(space, w_info=None):
-            with lltype.scoped_alloc(CConfig.timeval) as timeval:
-                ret = c_gettimeofday(timeval, rffi.NULL)
-                if ret != 0:
-                    raise exception_from_saved_errno(space, space.w_OSError)
+if _WIN:
+    _GetSystemTimeAsFileTime = rwin32.winexternal('GetSystemTimeAsFileTime',
+                                                  [lltype.Ptr(rwin32.FILETIME)],
+                                                  lltype.Void)
+    LPDWORD = rwin32.LPDWORD
+    _GetSystemTimeAdjustment = rwin32.winexternal(
+                                            'GetSystemTimeAdjustment',
+                                            [LPDWORD, LPDWORD, rwin32.LPBOOL], 
+                                            rffi.INT)
+    def gettimeofday(space, w_info=None):
+        with lltype.scoped_alloc(rwin32.FILETIME) as system_time:
+            _GetSystemTimeAsFileTime(system_time)
+            quad_part = (system_time.c_dwLowDateTime |
+                         (r_ulonglong(system_time.c_dwHighDateTime) << 32))
+            # 11,644,473,600,000,000: number of microseconds between
+            # the 1st january 1601 and the 1st january 1970 (369 years + 80 leap
+            # days).
 
+            # We can't use that big number when translating for
+            # 32-bit system (which windows always is currently)
+            # XXX: Need to come up with a better solution
+            offset = (r_ulonglong(16384) * r_ulonglong(27) * r_ulonglong(390625)
+                     * r_ulonglong(79) * r_ulonglong(853))
+            microseconds = quad_part / 10 - offset
+            tv_sec = microseconds / 1000000
+            tv_usec = microseconds % 1000000
+            if w_info:
+                with lltype.scoped_alloc(LPDWORD.TO, 1) as time_adjustment, \
+                     lltype.scoped_alloc(LPDWORD.TO, 1) as time_increment, \
+                     lltype.scoped_alloc(rwin32.LPBOOL.TO, 1) as is_time_adjustment_disabled:
+                    _GetSystemTimeAdjustment(time_adjustment, time_increment,
+                                             is_time_adjustment_disabled)
+                    
+                    _setinfo(space, w_info, "GetSystemTimeAsFileTime()",
+                             time_increment[0] * 1e-7, False, True)
+            return space.wrap(tv_sec + tv_usec * 1e-6)
+else:
+    if HAVE_GETTIMEOFDAY:
+        if GETTIMEOFDAY_NO_TZ:
+            c_gettimeofday = external('gettimeofday',
+                                      [lltype.Ptr(TIMEVAL)], rffi.INT)
+        else:
+            c_gettimeofday = external('gettimeofday',
+                                      [lltype.Ptr(TIMEVAL), rffi.VOIDP], rffi.INT)
+    def gettimeofday(space, w_info=None):
+        if HAVE_GETTIMEOFDAY:
+            with lltype.scoped_alloc(TIMEVAL) as timeval:
+                if GETTIMEOFDAY_NO_TZ:
+                    errcode = c_gettimeofday(timeval)
+                else:
+                    void = lltype.nullptr(rffi.VOIDP.TO)
+                    errcode = c_gettimeofday(timeval, void)
+                if rffi.cast(rffi.LONG, errcode) == 0:
+                    if w_info is not None:
+                        _setinfo(space, w_info, "gettimeofday()", 1e-6, False, True)
+                    return space.wrap(timeval.c_tv_sec + timeval.c_tv_usec * 1e-6)
+        if HAVE_FTIME:
+            with lltype.scoped_alloc(TIMEB) as t:
+                c_ftime(t)
+                result = (float(intmask(t.c_time)) +
+                          float(intmask(t.c_millitm)) * 0.001)
                 if w_info is not None:
-                    _setinfo(space, w_info,
-                             "gettimeofday()", 1e-6, False, True)
-
-                seconds = float(timeval.tv_sec) + timeval.tv_usec * 1e-6
-            return space.wrap(seconds)
-
-
+                    _setinfo(space, w_info, "ftime()", 1e-3,
+                             False, True) 
+            return space.wrap(result)
+        else:
+            if w_info:
+                _setinfo(space, w_info, "time()", 1.0, False, True)
+            return space.wrap(c_time(lltype.nullptr(rffi.TIME_TP.TO)))
 
 TM_P = lltype.Ptr(tm)
 c_time = external('time', [rffi.TIME_TP], rffi.TIME_T)
@@ -584,22 +627,8 @@
                         _setinfo(space, w_info, "clock_gettime(CLOCK_REALTIME)",
                                  res, False, True)
                 return space.wrap(_timespec_to_seconds(timespec))
-
-    # XXX: rewrite the final fallback into gettimeofday w/ windows
-    # GetSystemTimeAsFileTime() support
-    secs = pytime.time()
-    if w_info is not None:
-        # XXX: time.time delegates to the host python's time.time
-        # (rtime.time) so duplicate its internals for now
-        if rtime.HAVE_GETTIMEOFDAY:
-            implementation = "gettimeofday()"
-            resolution = 1e-6
-        else: # assume using ftime(3)
-            implementation = "ftime()"
-            resolution = 1e-3
-        _setinfo(space, w_info, implementation, resolution, False, True)
-    return space.wrap(secs)
-
+    else:
+        return gettimeofday(space, w_info)
 
 def ctime(space, w_seconds=None):
     """ctime([seconds]) -> string
@@ -800,20 +829,13 @@
 
 
 if _WIN:
-    # untested so far
     _GetTickCount = rwin32.winexternal('GetTickCount', [], rwin32.DWORD)
-    LPDWORD = rwin32.LPDWORD
-    _GetSystemTimeAdjustment = rwin32.winexternal(
-                                            'GetSystemTimeAdjustment',
-                                            [LPDWORD, LPDWORD, rwin32.LPBOOL],
-                                            rffi.INT)
     def monotonic(space, w_info=None):
         result = 0
+        HAS_GETTICKCOUNT64 = time_state.check_GetTickCount64()
         if HAS_GETTICKCOUNT64:
-            print('has count64'.encode('ascii'))
-            result = _GetTickCount64() * 1e-3
+            result = time_state.GetTickCount64() * 1e-3
         else:
-            print("nocount64")
             ticks = _GetTickCount()
             if ticks < time_state.last_ticks:
                 time_state.n_overflow += 1
@@ -828,11 +850,9 @@
             else:
                 implementation = "GetTickCount()"
             resolution = 1e-7
-            print("creating a thing".encode("ascii"))
             with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as time_adjustment, \
                  lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as time_increment, \
                  lltype.scoped_alloc(rwin32.LPBOOL.TO, 1) as is_time_adjustment_disabled:
-                print("CREATED".encode("ascii"))
                 ok = _GetSystemTimeAdjustment(time_adjustment,
                                               time_increment,
                                               is_time_adjustment_disabled)
@@ -841,7 +861,6 @@
                     raise wrap_windowserror(space,
                         rwin32.lastSavedWindowsError("GetSystemTimeAdjustment"))
                 resolution = resolution * time_increment[0]
-            print("out of with".encode("ascii"))
             _setinfo(space, w_info, implementation, resolution, True, False)
         return space.wrap(result)
 
@@ -981,7 +1000,7 @@
         Return the CPU time or real time since the start of the process or since
         the first call to clock().  This has as much precision as the system
         records."""
-        return space.wrap(win_perf_counter(space, w_info=w_info))
+        return space.wrap(perf_counter(space, w_info=w_info))
 
 else:
     _clock = external('clock', [], clock_t)
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
@@ -275,6 +275,7 @@
         # input to [w]strftime is not kosher.
         if os.name == 'nt':
             raises(ValueError, time.strftime, '%f')
+            return
         elif sys.platform == 'darwin' or 'bsd' in sys.platform:
             # darwin strips % of unknown format codes
             # http://bugs.python.org/issue9811


More information about the pypy-commit mailing list