[pypy-commit] pypy py3.7: Merged in py3.7-time-minor-bpos (pull request #688)
arigo
pypy.commits at gmail.com
Mon Dec 30 04:21:17 EST 2019
Author: Armin Rigo <armin.rigo at gmail.com>
Branch: py3.7
Changeset: r98415:8f7bc5f6eb55
Date: 2019-12-30 09:20 +0000
http://bitbucket.org/pypy/pypy/changeset/8f7bc5f6eb55/
Log: Merged in py3.7-time-minor-bpos (pull request #688)
Py3.7 time module minor BPOs
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
@@ -10,7 +10,7 @@
str_decode_locale_surrogateescape, unicode_encode_locale_surrogateescape)
from rpython.rtyper.lltypesystem import lltype
from rpython.rlib.rarithmetic import (
- intmask, r_ulonglong, r_longfloat, r_int64, widen, ovfcheck, ovfcheck_float_to_int)
+ intmask, r_ulonglong, r_longfloat, r_int64, widen, ovfcheck, ovfcheck_float_to_int, INT_MIN)
from rpython.rlib.rtime import (GETTIMEOFDAY_NO_TZ, TIMEVAL,
HAVE_GETTIMEOFDAY, HAVE_FTIME)
from rpython.rlib import rposix, rtime
@@ -240,6 +240,8 @@
HAS_CLOCK_MONOTONIC = rtime.CLOCK_MONOTONIC is not None
HAS_MONOTONIC = (_WIN or _MACOSX or
(HAS_CLOCK_GETTIME and (HAS_CLOCK_HIGHRES or HAS_CLOCK_MONOTONIC)))
+HAS_THREAD_TIME = (_WIN or
+ (HAS_CLOCK_GETTIME and rtime.CLOCK_PROCESS_CPUTIME_ID is not None))
tm = cConfig.tm
glob_buf = lltype.malloc(tm, flavor='raw', zero=True, immortal=True)
@@ -647,6 +649,9 @@
if len(tup_w) >= 11:
rffi.setintfield(glob_buf, 'c_tm_gmtoff', space.c_int_w(tup_w[10]))
+ if (y < INT_MIN + 1900):
+ raise oefmt(space.w_OverflowError, "year out of range")
+
# tm_wday does not need checking of its upper-bound since taking "%
# 7" in _gettmarg() automatically restricts the range.
if rffi.getintfield(glob_buf, 'c_tm_wday') < -1:
@@ -1217,8 +1222,82 @@
sum of the kernel and user-space CPU time"""
return _process_time_impl(space, w_info, True)
+if HAS_THREAD_TIME:
+ if _WIN:
+ _GetCurrentThread = rwin32.winexternal('GetCurrentThread', [], rwin32.HANDLE)
+ _GetThreadTimes = rwin32.winexternal('GetThreadTimes', [rwin32.HANDLE,
+ lltype.Ptr(rwin32.FILETIME),
+ lltype.Ptr(rwin32.FILETIME),
+ lltype.Ptr(rwin32.FILETIME),
+ lltype.Ptr(rwin32.FILETIME)],
+ rwin32.BOOL)
+ def _thread_time_impl(space, w_info, return_ns):
+ thread = _GetCurrentThread()
+
+ with lltype.scoped_alloc(rwin32.FILETIME) as creation_time, \
+ lltype.scoped_alloc(rwin32.FILETIME) as exit_time, \
+ lltype.scoped_alloc(rwin32.FILETIME) as kernel_time, \
+ lltype.scoped_alloc(rwin32.FILETIME) as user_time:
+ ok = _GetThreadTimes(thread, creation_time, exit_time,
+ kernel_time, user_time)
+ if not ok:
+ raise wrap_oserror(space,
+ rwin32.lastSavedWindowsError("GetThreadTimes"))
+ ktime = (kernel_time.c_dwLowDateTime |
+ r_ulonglong(kernel_time.c_dwHighDateTime) << 32)
+ utime = (user_time.c_dwLowDateTime |
+ r_ulonglong(user_time.c_dwHighDateTime) << 32)
+
+ if w_info is not None:
+ _setinfo(space, w_info, "GetThreadTimes()", 1e-7, True, False)
+
+ # ktime and utime have a resolution of 100 nanoseconds
+ if return_ns:
+ return space.newint((r_int64(ktime) + r_int64(utime)) * 10**2)
+ else:
+ return space.newfloat((float(ktime) + float(utime)) * 1e-7)
+ else:
+ def _thread_time_impl(space, w_info, return_ns):
+ clk_id = rtime.CLOCK_THREAD_CPUTIME_ID
+ implementation = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)"
+
+ with lltype.scoped_alloc(TIMESPEC) as timespec:
+ ret = c_clock_gettime(clk_id, timespec)
+ if ret == 0:
+ if w_info is not None:
+ with lltype.scoped_alloc(TIMESPEC) as tsres:
+ ret = c_clock_getres(clk_id, tsres)
+ if ret == 0:
+ res = _timespec_to_seconds(tsres)
+ else:
+ res = 1e-9
+ _setinfo(space, w_info,
+ implementation, res, True, False)
+ if return_ns:
+ return space.newint(_timespec_to_nanoseconds(timespec))
+ else:
+ return space.newfloat(_timespec_to_seconds(timespec))
+
+ def thread_time(space, w_info=None):
+ """thread_time() -> float
+
+ Thread time for profiling: sum of the kernel and user-space CPU time."""
+ return _thread_time_impl(space, w_info, False)
+
+ def thread_time_ns(space, w_info=None):
+ """thread_time_ns() -> int
+
+ Thread time for profiling as nanoseconds:
+ sum of the kernel and user-space CPU time."""
+ return _thread_time_impl(space, w_info, True)
+
_clock = external('clock', [], rposix.CLOCK_T)
def _clock_impl(space, w_info, return_ns):
+ space.warn(space.newtext(
+ "time.clock has been deprecated in Python 3.3 and will "
+ "be removed from Python 3.8: "
+ "use time.perf_counter or time.process_time "
+ "instead"), space.w_DeprecationWarning)
if _WIN:
try:
return _win_perf_counter_impl(space, w_info, return_ns)
diff --git a/pypy/module/time/moduledef.py b/pypy/module/time/moduledef.py
--- a/pypy/module/time/moduledef.py
+++ b/pypy/module/time/moduledef.py
@@ -1,6 +1,6 @@
from pypy.interpreter.mixedmodule import MixedModule
-from .interp_time import HAS_MONOTONIC
+from .interp_time import HAS_MONOTONIC, HAS_THREAD_TIME
from rpython.rlib import rtime
import os
@@ -39,6 +39,9 @@
if HAS_MONOTONIC:
interpleveldefs['monotonic'] = 'interp_time.monotonic'
interpleveldefs['monotonic_ns'] = 'interp_time.monotonic_ns'
+ if HAS_THREAD_TIME:
+ interpleveldefs['thread_time'] = 'interp_time.thread_time'
+ interpleveldefs['thread_time_ns'] = 'interp_time.thread_time_ns'
if os.name == "posix":
interpleveldefs['tzset'] = 'interp_time.tzset'
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
@@ -21,8 +21,15 @@
raises(OverflowError, time.sleep, float('inf'))
def test_clock(self):
- import time
- time.clock()
+ import time, warnings
+ warnings.simplefilter("always")
+ with warnings.catch_warnings(record=True) as w:
+ time.clock()
+ assert len(w) == 1
+ assert str(w[0].message).startswith(
+ "time.clock has been deprecated in Python 3.3 and will "
+ "be removed from Python 3.8")
+ assert w[0].category == DeprecationWarning
assert isinstance(time.clock(), float)
def test_time(self):
@@ -90,6 +97,54 @@
assert abs(time.clock_gettime(time.CLOCK_MONOTONIC) -
time.clock_gettime_ns(time.CLOCK_MONOTONIC) * 1e-9) < 0.1
+ def test_clock_gettime(self):
+ import time
+ clock_ids = ['CLOCK_REALTIME',
+ 'CLOCK_REALTIME_COARSE',
+ 'CLOCK_MONOTONIC',
+ 'CLOCK_MONOTONIC_COARSE',
+ 'CLOCK_MONOTONIC_RAW',
+ 'CLOCK_BOOTTIME',
+ 'CLOCK_PROCESS_CPUTIME_ID',
+ 'CLOCK_THREAD_CPUTIME_ID',
+ 'CLOCK_HIGHRES',
+ 'CLOCK_PROF',
+ 'CLOCK_UPTIME',]
+ for clock_id in clock_ids:
+ clock = getattr(time, clock_id, None)
+ if clock is None:
+ continue
+ t1 = time.clock_gettime(clock)
+ assert isinstance(t1, float)
+ time.sleep(time.clock_getres(clock))
+ t2 = time.clock_gettime(clock)
+ assert t1 < t2
+
+ def test_clock_gettime(self):
+ import time
+ clock_ids = ['CLOCK_REALTIME',
+ 'CLOCK_REALTIME_COARSE',
+ 'CLOCK_MONOTONIC',
+ 'CLOCK_MONOTONIC_COARSE',
+ 'CLOCK_MONOTONIC_RAW',
+ 'CLOCK_BOOTTIME',
+ 'CLOCK_PROCESS_CPUTIME_ID',
+ 'CLOCK_THREAD_CPUTIME_ID',
+ 'CLOCK_HIGHRES',
+ 'CLOCK_PROF',
+ 'CLOCK_UPTIME',]
+ for clock_id in clock_ids:
+ clock = getattr(time, clock_id, None)
+ if clock is None:
+ continue
+ t1 = time.clock_gettime_ns(clock)
+ assert isinstance(t1, int)
+ time.sleep(time.clock_getres(clock))
+ t2 = time.clock_gettime_ns(clock)
+ assert t1 < t2
+ assert abs(time.clock_gettime(clock) -
+ time.clock_gettime_ns(clock) * 1e-9) < 0.1
+
def test_ctime(self):
import time
raises(TypeError, time.ctime, "foo")
@@ -235,6 +290,7 @@
asc = time.asctime((bigyear, 6, 1) + (0,)*6)
assert asc[-len(str(bigyear)):] == str(bigyear)
raises(OverflowError, time.asctime, (bigyear + 1,) + (0,)*8)
+ raises(OverflowError, time.asctime, (-bigyear - 2 + 1900,) + (0,)*8)
def test_struct_time(self):
import time
@@ -481,6 +537,29 @@
assert (t2 - t1) < 5 * 10**7
assert abs(time.process_time() - time.process_time_ns() * 1e-9) < 0.1
+ def test_thread_time(self):
+ import time
+ if not hasattr(time, 'thread_time'):
+ skip("need time.thread_time")
+ t1 = time.thread_time()
+ assert isinstance(t1, float)
+ time.sleep(0.1)
+ t2 = time.thread_time()
+ # thread_time_time() should not include time spent during sleep
+ assert (t2 - t1) < 0.05
+
+ def test_thread_time_ns(self):
+ import time
+ if not hasattr(time, 'thread_time_ns'):
+ skip("need time.thread_time_ns")
+ t1 = time.thread_time_ns()
+ assert isinstance(t1, int)
+ time.sleep(0.1)
+ t2 = time.process_time_ns()
+ # process_thread_ns() should not include time spent during sleep
+ assert (t2 - t1) < 5 * 10**7
+ assert abs(time.thread_time() - time.thread_time_ns() * 1e-9) < 0.1
+
def test_get_clock_info(self):
import time
clocks = ['clock', 'perf_counter', 'process_time', 'time']
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -83,6 +83,7 @@
'CLOCK_THREAD_CPUTIME_ID',
'CLOCK_HIGHRES',
'CLOCK_PROF',
+ 'CLOCK_UPTIME',
]
for const in constant_names:
setattr(CConfig, const, rffi_platform.DefinedConstantInteger(const))
More information about the pypy-commit
mailing list