[pypy-commit] pypy py3.7: Merged in py3.7-pep564 (pull request #677)
arigo
pypy.commits at gmail.com
Fri Nov 8 14:21:02 EST 2019
Author: Armin Rigo <armin.rigo at gmail.com>
Branch: py3.7
Changeset: r97996:d70821cfb56e
Date: 2019-11-08 19:20 +0000
http://bitbucket.org/pypy/pypy/changeset/d70821cfb56e/
Log: Merged in py3.7-pep564 (pull request #677)
PEP 564 implementation
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, widen, ovfcheck, ovfcheck_float_to_int)
+ intmask, r_ulonglong, r_longfloat, r_int64, widen, ovfcheck, ovfcheck_float_to_int)
from rpython.rlib.rtime import (GETTIMEOFDAY_NO_TZ, TIMEVAL,
HAVE_GETTIMEOFDAY, HAVE_FTIME)
from rpython.rlib import rposix, rtime
@@ -132,7 +132,7 @@
def __init__(self):
self.n_overflow = 0
self.last_ticks = 0
- self.divisor = 0.0
+ self.divisor = 0
self.counter_start = 0
def check_GetTickCount64(self, *args):
@@ -252,7 +252,7 @@
'GetSystemTimeAdjustment',
[LPDWORD, LPDWORD, rwin32.LPBOOL],
rffi.INT)
- def gettimeofday(space, w_info=None):
+ def _gettimeofday_impl(space, w_info, return_ns):
with lltype.scoped_alloc(rwin32.FILETIME) as system_time:
_GetSystemTimeAsFileTime(system_time)
quad_part = (system_time.c_dwLowDateTime |
@@ -267,8 +267,6 @@
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, \
@@ -278,7 +276,12 @@
_setinfo(space, w_info, "GetSystemTimeAsFileTime()",
time_increment[0] * 1e-7, False, True)
- return space.newfloat(tv_sec + tv_usec * 1e-6)
+ if return_ns:
+ return space.newint(r_int64(microseconds) * 10**3)
+ else:
+ tv_sec = microseconds / 10**6
+ tv_usec = microseconds % 10**6
+ return space.newfloat(tv_sec + tv_usec * 1e-6)
else:
if HAVE_GETTIMEOFDAY:
if GETTIMEOFDAY_NO_TZ:
@@ -287,7 +290,7 @@
else:
c_gettimeofday = external('gettimeofday',
[lltype.Ptr(TIMEVAL), rffi.VOIDP], rffi.INT)
- def gettimeofday(space, w_info=None):
+ def _gettimeofday_impl(space, w_info, return_ns):
if HAVE_GETTIMEOFDAY:
with lltype.scoped_alloc(TIMEVAL) as timeval:
if GETTIMEOFDAY_NO_TZ:
@@ -298,22 +301,38 @@
if rffi.cast(rffi.LONG, errcode) == 0:
if w_info is not None:
_setinfo(space, w_info, "gettimeofday()", 1e-6, False, True)
- return space.newfloat(
- widen(timeval.c_tv_sec) +
- widen(timeval.c_tv_usec) * 1e-6)
+ if return_ns:
+ return space.newint(
+ r_int64(timeval.c_tv_sec) * 10**9 +
+ r_int64(timeval.c_tv_usec) * 10**3)
+ else:
+ return space.newfloat(
+ widen(timeval.c_tv_sec) +
+ widen(timeval.c_tv_usec) * 1e-6)
if HAVE_FTIME:
with lltype.scoped_alloc(TIMEB) as t:
c_ftime(t)
- result = (widen(t.c_time) +
- widen(t.c_millitm) * 0.001)
if w_info is not None:
- _setinfo(space, w_info, "ftime()", 1e-3,
- False, True)
- return space.newfloat(result)
+ _setinfo(space, w_info, "ftime()", 1e-3, False, True)
+ if return_ns:
+ return space.newint(
+ r_int64(t.c_time) * 10**9 +
+ r_int64(intmask(t.c_millitm)) * 10**6)
+ else:
+ return space.newfloat(
+ widen(t.c_time) +
+ widen(t.c_millitm) * 1e-3)
else:
if w_info:
_setinfo(space, w_info, "time()", 1.0, False, True)
- return space.newint(c_time(lltype.nullptr(rffi.TIME_TP.TO)))
+ result = c_time(lltype.nullptr(rffi.TIME_TP.TO))
+ if return_ns:
+ return space.newint(r_int64(result) * 10**9)
+ else:
+ return space.newfloat(float(result))
+
+ def gettimeofday(space, w_info=None):
+ return _gettimeofday_impl(space, w_info, False)
TM_P = lltype.Ptr(tm)
c_time = external('time', [rffi.TIME_TP], rffi.TIME_T)
@@ -663,11 +682,7 @@
if not 0 <= rffi.getintfield(t_ref, 'c_tm_yday') <= 365:
raise oefmt(space.w_ValueError, "day of year out of range")
-def time(space, w_info=None):
- """time() -> floating point number
-
- Return the current time in seconds since the Epoch.
- Fractions of a second may be present if the system clock provides them."""
+def _time_impl(space, w_info, return_ns):
if HAS_CLOCK_GETTIME:
with lltype.scoped_alloc(TIMESPEC) as timespec:
ret = c_clock_gettime(rtime.CLOCK_REALTIME, timespec)
@@ -681,8 +696,24 @@
res = 1e-9
_setinfo(space, w_info, "clock_gettime(CLOCK_REALTIME)",
res, False, True)
- return space.newfloat(_timespec_to_seconds(timespec))
- return gettimeofday(space, w_info)
+ if return_ns:
+ return space.newint(_timespec_to_nanoseconds(timespec))
+ else:
+ return space.newfloat(_timespec_to_seconds(timespec))
+ return _gettimeofday_impl(space, w_info, return_ns)
+
+def time(space, w_info=None):
+ """time() -> floating point number
+
+ Return the current time in seconds since the Epoch.
+ Fractions of a second may be present if the system clock provides them."""
+ return _time_impl(space, w_info, False)
+
+def time_ns(space, w_info=None):
+ """time_ns() -> int
+
+ Return the current time in nanoseconds since the Epoch."""
+ return _time_impl(space, w_info, True)
def ctime(space, w_seconds=None):
"""ctime([seconds]) -> string
@@ -789,17 +820,38 @@
def _timespec_to_seconds(timespec):
return widen(timespec.c_tv_sec) + widen(timespec.c_tv_nsec) * 1e-9
- @unwrap_spec(clk_id='c_int')
- def clock_gettime(space, clk_id):
+ def _timespec_to_nanoseconds(timespec):
+ return r_int64(timespec.c_tv_sec) * 10**9 + r_int64(timespec.c_tv_nsec)
+
+ def _clock_gettime_impl(space, clk_id, return_ns):
with lltype.scoped_alloc(TIMESPEC) as timespec:
ret = c_clock_gettime(clk_id, timespec)
if ret != 0:
raise exception_from_saved_errno(space, space.w_OSError)
- secs = _timespec_to_seconds(timespec)
- return space.newfloat(secs)
+ if return_ns:
+ return space.newint(_timespec_to_nanoseconds(timespec))
+ else:
+ return space.newfloat(_timespec_to_seconds(timespec))
+
+ @unwrap_spec(clk_id='c_int')
+ def clock_gettime(space, clk_id):
+ """clock_gettime(clk_id) -> float
+
+ Return the time of the specified clock clk_id."""
+ return _clock_gettime_impl(space, clk_id, False)
+
+ @unwrap_spec(clk_id='c_int')
+ def clock_gettime_ns(space, clk_id):
+ """clock_gettime_ns(clk_id) -> int
+
+ Return the time of the specified clock clk_id as nanoseconds."""
+ return _clock_gettime_impl(space, clk_id, True)
@unwrap_spec(clk_id='c_int', secs=float)
def clock_settime(space, clk_id, secs):
+ """clock_settime(clk_id, time)
+
+ Set the time of the specified clock clk_id."""
with lltype.scoped_alloc(TIMESPEC) as timespec:
integer_secs = rffi.cast(TIMESPEC.c_tv_sec, secs)
frac = secs - widen(integer_secs)
@@ -809,8 +861,23 @@
if ret != 0:
raise exception_from_saved_errno(space, space.w_OSError)
+ @unwrap_spec(clk_id='c_int', ns=r_int64)
+ def clock_settime_ns(space, clk_id, ns):
+ """clock_settime_ns(clk_id, time)
+
+ Set the time of the specified clock clk_id with nanoseconds."""
+ with lltype.scoped_alloc(TIMESPEC) as timespec:
+ rffi.setintfield(timespec, 'c_tv_sec', ns // 10**9)
+ rffi.setintfield(timespec, 'c_tv_nsec', ns % 10**9)
+ ret = c_clock_settime(clk_id, timespec)
+ if ret != 0:
+ raise exception_from_saved_errno(space, space.w_OSError)
+
@unwrap_spec(clk_id='c_int')
def clock_getres(space, clk_id):
+ """clock_getres(clk_id) -> floating point number
+
+ Return the resolution (precision) of the specified clock clk_id."""
with lltype.scoped_alloc(TIMESPEC) as timespec:
ret = c_clock_getres(clk_id, timespec)
if ret != 0:
@@ -893,19 +960,18 @@
if HAS_MONOTONIC:
if _WIN:
_GetTickCount = rwin32.winexternal('GetTickCount', [], rwin32.DWORD)
- def monotonic(space, w_info=None):
+ def _monotonic_impl(space, w_info, return_ns):
result = 0
HAS_GETTICKCOUNT64 = time_state.check_GetTickCount64()
if HAS_GETTICKCOUNT64:
- result = time_state.GetTickCount64() * 1e-3
+ tick_count = time_state.GetTickCount64()
else:
ticks = _GetTickCount()
if ticks < time_state.last_ticks:
time_state.n_overflow += 1
time_state.last_ticks = ticks
- result = math.ldexp(time_state.n_overflow, 32)
- result = result + ticks
- result = result * 1e-3
+ tick_count = math.ldexp(time_state.n_overflow, 32)
+ tick_count = tick_count + ticks
if w_info is not None:
if HAS_GETTICKCOUNT64:
@@ -925,7 +991,11 @@
rwin32.lastSavedWindowsError("GetSystemTimeAdjustment"))
resolution = resolution * time_increment[0]
_setinfo(space, w_info, implementation, resolution, True, False)
- return space.newfloat(result)
+
+ if return_ns:
+ return space.newint(r_int64(tick_count) * 10**6)
+ else:
+ return space.newfloat(tick_count * 1e-3)
elif _MACOSX:
c_mach_timebase_info = external('mach_timebase_info',
@@ -936,30 +1006,33 @@
timebase_info = lltype.malloc(cConfig.TIMEBASE_INFO, flavor='raw',
zero=True, immortal=True)
- def monotonic(space, w_info=None):
+ def _monotonic_impl(space, w_info, return_ns):
if rffi.getintfield(timebase_info, 'c_denom') == 0:
c_mach_timebase_info(timebase_info)
time = rffi.cast(lltype.Signed, c_mach_absolute_time())
numer = rffi.getintfield(timebase_info, 'c_numer')
denom = rffi.getintfield(timebase_info, 'c_denom')
- nanosecs = time * numer / denom
+ nanosecs = r_int64(time) * numer / denom
if w_info is not None:
res = (numer / denom) * 1e-9
_setinfo(space, w_info, "mach_absolute_time()", res, True, False)
- secs = nanosecs / 10**9
- rest = nanosecs % 10**9
- return space.newfloat(float(secs) + float(rest) * 1e-9)
+ if return_ns:
+ return space.newint(nanosecs)
+ else:
+ secs = nanosecs / 10**9
+ rest = nanosecs % 10**9
+ return space.newfloat(float(secs) + float(rest) * 1e-9)
else:
assert _POSIX
- def monotonic(space, w_info=None):
+ def _monotonic_impl(space, w_info, return_ns):
if rtime.CLOCK_HIGHRES is not None:
clk_id = rtime.CLOCK_HIGHRES
implementation = "clock_gettime(CLOCK_HIGHRES)"
else:
clk_id = rtime.CLOCK_MONOTONIC
implementation = "clock_gettime(CLOCK_MONOTONIC)"
- w_result = clock_gettime(space, clk_id)
+ w_result = _clock_gettime_impl(space, clk_id, return_ns)
if w_info is not None:
with lltype.scoped_alloc(TIMESPEC) as tsres:
ret = c_clock_getres(clk_id, tsres)
@@ -970,6 +1043,18 @@
_setinfo(space, w_info, implementation, res, True, False)
return w_result
+ def monotonic(space, w_info=None):
+ """monotonic() -> float
+
+ Monotonic clock, cannot go backward."""
+ return _monotonic_impl(space, w_info, False)
+
+ def monotonic_ns(space, w_info=None):
+ """monotonic_ns() -> int
+
+ Monotonic clock, cannot go backward, as nanoseconds."""
+ return _monotonic_impl(space, w_info, True)
+
if _WIN:
# hacking to avoid LARGE_INTEGER which is a union...
QueryPerformanceCounter = external(
@@ -981,46 +1066,61 @@
QueryPerformanceFrequency = rwin32.winexternal(
'QueryPerformanceFrequency', [rffi.CArrayPtr(lltype.SignedLongLong)],
rffi.INT)
- def win_perf_counter(space, w_info=None):
+ def _win_perf_counter_impl(space, w_info, return_ns):
with lltype.scoped_alloc(rffi.CArray(rffi.lltype.SignedLongLong), 1) as a:
succeeded = True
- if time_state.divisor == 0.0:
+ if time_state.divisor == 0:
QueryPerformanceCounter(a)
time_state.counter_start = a[0]
succeeded = QueryPerformanceFrequency(a)
- time_state.divisor = float(a[0])
- if succeeded and time_state.divisor != 0.0:
+ time_state.divisor = a[0]
+ if succeeded and time_state.divisor != 0:
QueryPerformanceCounter(a)
diff = a[0] - time_state.counter_start
else:
raise ValueError("Failed to generate the result.")
- resolution = 1 / time_state.divisor
if w_info is not None:
+ resolution = 1 / float(time_state.divisor)
_setinfo(space, w_info, "QueryPerformanceCounter()", resolution,
True, False)
- return space.newfloat(float(diff) / time_state.divisor)
+ if return_ns:
+ return space.newint(r_int64(diff) * 10**9 // time_state.divisor)
+ else:
+ return space.newfloat(float(diff) / float(time_state.divisor))
- def perf_counter(space, w_info=None):
+ def _perf_counter_impl(space, w_info, return_ns):
try:
- return win_perf_counter(space, w_info=w_info)
+ return _win_perf_counter_impl(space, w_info, return_ns)
except ValueError:
if HAS_MONOTONIC:
try:
- return monotonic(space, w_info=w_info)
+ return _monotonic_impl(space, w_info, return_ns)
except Exception:
pass
- return time(space, w_info=w_info)
+ return _time_impl(space, w_info, return_ns)
else:
- def perf_counter(space, w_info=None):
+ def _perf_counter_impl(space, w_info, return_ns):
if HAS_MONOTONIC:
try:
- return monotonic(space, w_info=w_info)
+ return _monotonic_impl(space, w_info, return_ns)
except Exception:
pass
- return time(space, w_info=w_info)
+ return _time_impl(space, w_info, return_ns)
+
+def perf_counter(space, w_info=None):
+ """perf_counter() -> float
+
+ Performance counter for benchmarking."""
+ return _perf_counter_impl(space, w_info, False)
+
+def perf_counter_ns(space, w_info=None):
+ """perf_counter_ns() -> int
+
+ Performance counter for benchmarking as nanoseconds."""
+ return _perf_counter_impl(space, w_info, True)
if _WIN:
- def process_time(space, w_info=None):
+ def _process_time_impl(space, w_info, return_ns):
from rpython.rlib.rposix import GetCurrentProcess, GetProcessTimes
current_process = GetCurrentProcess()
with lltype.scoped_alloc(rwin32.FILETIME) as creation_time, \
@@ -1038,11 +1138,14 @@
r_ulonglong(user_time.c_dwHighDateTime) << 32)
if w_info is not None:
_setinfo(space, w_info, "GetProcessTimes()", 1e-7, True, False)
- return space.newfloat((float(kernel_time2) + float(user_time2)) * 1e-7)
+ if return_ns:
+ return space.newint((r_int64(kernel_time2) + r_int64(user_time2)) * 10**2)
+ else:
+ return space.newfloat((float(kernel_time2) + float(user_time2)) * 1e-7)
else:
have_times = hasattr(rposix, 'c_times')
- def process_time(space, w_info=None):
+ def _process_time_impl(space, w_info, return_ns):
if HAS_CLOCK_GETTIME and (
rtime.CLOCK_PROF is not None or
rtime.CLOCK_PROCESS_CPUTIME_ID is not None):
@@ -1064,44 +1167,61 @@
res = 1e-9
_setinfo(space, w_info,
implementation, res, True, False)
- return space.newfloat(_timespec_to_seconds(timespec))
+ if return_ns:
+ return space.newint(_timespec_to_nanoseconds(timespec))
+ else:
+ return space.newfloat(_timespec_to_seconds(timespec))
if True: # XXX available except if it isn't?
from rpython.rlib.rtime import (c_getrusage, RUSAGE, RUSAGE_SELF,
- decode_timeval)
+ decode_timeval, decode_timeval_ns)
with lltype.scoped_alloc(RUSAGE) as rusage:
ret = c_getrusage(RUSAGE_SELF, rusage)
if ret == 0:
if w_info is not None:
_setinfo(space, w_info,
"getrusage(RUSAGE_SELF)", 1e-6, True, False)
- return space.newfloat(decode_timeval(rusage.c_ru_utime) +
- decode_timeval(rusage.c_ru_stime))
+ if return_ns:
+ return space.newint(
+ decode_timeval_ns(rusage.c_ru_utime) +
+ decode_timeval_ns(rusage.c_ru_stime))
+ else:
+ return space.newfloat(decode_timeval(rusage.c_ru_utime) +
+ decode_timeval(rusage.c_ru_stime))
if have_times:
with lltype.scoped_alloc(rposix.TMS) as tms:
ret = rposix.c_times(tms)
if rffi.cast(lltype.Signed, ret) != -1:
- cpu_time = float(rffi.cast(lltype.Signed,
- tms.c_tms_utime) +
- rffi.cast(lltype.Signed,
- tms.c_tms_stime))
+ cpu_time = (rffi.cast(lltype.Signed, tms.c_tms_utime) +
+ rffi.cast(lltype.Signed, tms.c_tms_stime))
if w_info is not None:
_setinfo(space, w_info, "times()",
1.0 / rposix.CLOCK_TICKS_PER_SECOND,
True, False)
- return space.newfloat(cpu_time / rposix.CLOCK_TICKS_PER_SECOND)
- return clock(space)
+ if return_ns:
+ return space.newint(r_int64(cpu_time) * 10**9 // int(rposix.CLOCK_TICKS_PER_SECOND))
+ else:
+ return space.newfloat(float(cpu_time) / rposix.CLOCK_TICKS_PER_SECOND)
+ return _clock_impl(space, w_info, return_ns)
+
+def process_time(space, w_info=None):
+ """process_time() -> float
+
+ Process time for profiling: sum of the kernel and user-space CPU time."""
+ return _process_time_impl(space, w_info, False)
+
+def process_time_ns(space, w_info=None):
+ """process_time() -> int
+
+ Process time for profiling as nanoseconds:
+ sum of the kernel and user-space CPU time"""
+ return _process_time_impl(space, w_info, True)
_clock = external('clock', [], rposix.CLOCK_T)
-def clock(space, w_info=None):
- """clock() -> floating point number
-
- 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."""
+def _clock_impl(space, w_info, return_ns):
if _WIN:
try:
- return win_perf_counter(space, w_info=w_info)
+ return _win_perf_counter_impl(space, w_info, return_ns)
except ValueError:
pass
value = widen(_clock())
@@ -1112,7 +1232,18 @@
if w_info is not None:
_setinfo(space, w_info,
"clock()", 1.0 / CLOCKS_PER_SEC, True, False)
- return space.newfloat(float(value) / CLOCKS_PER_SEC)
+ if return_ns:
+ return space.newint(r_int64(value) * 10**9 // CLOCKS_PER_SEC)
+ else:
+ return space.newfloat(float(value) / CLOCKS_PER_SEC)
+
+def clock(space, w_info=None):
+ """clock() -> floating point number
+
+ 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 _clock_impl(space, w_info, False)
def _setinfo(space, w_info, impl, res, mono, adj):
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
@@ -11,6 +11,7 @@
interpleveldefs = {
'time': 'interp_time.time',
+ 'time_ns': 'interp_time.time_ns',
'clock': 'interp_time.clock',
'ctime': 'interp_time.ctime',
'asctime': 'interp_time.asctime',
@@ -21,18 +22,23 @@
'sleep' : 'interp_time.sleep',
'_STRUCT_TM_ITEMS': 'space.wrap(interp_time._STRUCT_TM_ITEMS)',
'perf_counter': 'interp_time.perf_counter',
+ 'perf_counter_ns': 'interp_time.perf_counter_ns',
'process_time': 'interp_time.process_time',
+ 'process_time_ns': 'interp_time.process_time_ns',
}
if rtime.HAS_CLOCK_GETTIME:
interpleveldefs['clock_gettime'] = 'interp_time.clock_gettime'
+ interpleveldefs['clock_gettime_ns'] = 'interp_time.clock_gettime_ns'
interpleveldefs['clock_settime'] = 'interp_time.clock_settime'
+ interpleveldefs['clock_settime_ns'] = 'interp_time.clock_settime_ns'
interpleveldefs['clock_getres'] = 'interp_time.clock_getres'
for constant in rtime.ALL_DEFINED_CLOCKS:
interpleveldefs[constant] = 'space.wrap(%d)' % (
getattr(rtime, constant),)
if HAS_MONOTONIC:
interpleveldefs['monotonic'] = 'interp_time.monotonic'
+ interpleveldefs['monotonic_ns'] = 'interp_time.monotonic_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
@@ -28,12 +28,22 @@
def test_time(self):
import time
t1 = time.time()
- assert isinstance(time.time(), float)
- assert time.time() != 0.0 # 0.0 means failure
+ assert isinstance(t1, float)
+ assert t1 != 0.0 # 0.0 means failure
time.sleep(0.02)
t2 = time.time()
assert t1 != t2 # the resolution should be at least 0.01 secs
+ def test_time_ns(self):
+ import time
+ t1 = time.time_ns()
+ assert isinstance(t1, int)
+ assert t1 != 0 # 0 means failure
+ time.sleep(0.02)
+ t2 = time.time_ns()
+ assert t1 != t2 # the resolution should be at least 0.01 secs
+ assert abs(time.time() - time.time_ns() * 1e-9) < 0.1
+
def test_clock_realtime(self):
import time
if not hasattr(time, 'clock_gettime'):
@@ -44,6 +54,18 @@
t2 = time.clock_gettime(time.CLOCK_REALTIME)
assert t1 != t2
+ def test_clock_realtime_ns(self):
+ import time
+ if not hasattr(time, 'clock_gettime_ns'):
+ skip("need time.clock_gettime_ns()")
+ t1 = time.clock_gettime_ns(time.CLOCK_REALTIME)
+ assert isinstance(t1, int)
+ time.sleep(time.clock_getres(time.CLOCK_REALTIME))
+ t2 = time.clock_gettime_ns(time.CLOCK_REALTIME)
+ assert t1 != t2
+ assert abs(time.clock_gettime(time.CLOCK_REALTIME) -
+ time.clock_gettime_ns(time.CLOCK_REALTIME) * 1e-9) < 0.1
+
def test_clock_monotonic(self):
import time
if not (hasattr(time, 'clock_gettime') and
@@ -55,6 +77,19 @@
t2 = time.clock_gettime(time.CLOCK_MONOTONIC)
assert t1 < t2
+ def test_clock_monotonic_ns(self):
+ import time
+ if not (hasattr(time, 'clock_gettime_ns') and
+ hasattr(time, 'CLOCK_MONOTONIC')):
+ skip("need time.clock_gettime()/CLOCK_MONOTONIC")
+ t1 = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
+ assert isinstance(t1, int)
+ time.sleep(time.clock_getres(time.CLOCK_MONOTONIC))
+ t2 = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
+ assert t1 < t2
+ assert abs(time.clock_gettime(time.CLOCK_MONOTONIC) -
+ time.clock_gettime_ns(time.CLOCK_MONOTONIC) * 1e-9) < 0.1
+
def test_ctime(self):
import time
raises(TypeError, time.ctime, "foo")
@@ -398,10 +433,24 @@
t2 = time.monotonic()
assert t1 < t2
+ def test_monotonic_ns(self):
+ import time
+ t1 = time.monotonic_ns()
+ assert isinstance(t1, int)
+ time.sleep(0.02)
+ t2 = time.monotonic_ns()
+ assert t1 < t2
+ assert abs(time.monotonic() - time.monotonic_ns() * 1e-9) < 0.1
+
def test_perf_counter(self):
import time
assert isinstance(time.perf_counter(), float)
+ def test_perf_counter_ns(self):
+ import time
+ assert isinstance(time.perf_counter_ns(), int)
+ assert abs(time.perf_counter() - time.perf_counter_ns() * 1e-9) < 0.1
+
def test_process_time(self):
import time
t1 = time.process_time()
@@ -411,6 +460,16 @@
# process_time() should not include time spent during sleep
assert (t2 - t1) < 0.05
+ def test_process_time_ns(self):
+ import time
+ t1 = time.process_time_ns()
+ assert isinstance(t1, int)
+ time.sleep(0.1)
+ t2 = time.process_time_ns()
+ # process_time_ns() should not include time spent during sleep
+ assert (t2 - t1) < 5 * 10**7
+ assert abs(time.process_time() - time.process_time_ns() * 1e-9) < 0.1
+
def test_get_clock_info(self):
import time
clocks = ['clock', 'perf_counter', 'process_time', 'time']
diff --git a/pypy/module/time/test/test_ztranslation.py b/pypy/module/time/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/time/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ checkmodule('time')
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -9,7 +9,7 @@
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.rarithmetic import intmask, UINT_MAX
+from rpython.rlib.rarithmetic import intmask, r_int64, UINT_MAX
from rpython.rlib import rposix
_WIN32 = sys.platform.startswith('win')
@@ -94,6 +94,10 @@
return (float(rffi.getintfield(t, 'c_tv_sec')) +
float(rffi.getintfield(t, 'c_tv_usec')) * 0.000001)
+def decode_timeval_ns(t):
+ return (r_int64(rffi.getintfield(t, 'c_tv_sec')) * 10**9 +
+ r_int64(rffi.getintfield(t, 'c_tv_usec')) * 10**3)
+
def external(name, args, result, compilation_info=eci, **kwds):
return rffi.llexternal(name, args, result,
More information about the pypy-commit
mailing list