[pypy-commit] pypy py3.3: Implement time.clock_gettime(), time.clock_settime(), time.clock_getres() and time.CLOCK_xxx constants.
mjacob
noreply at buildbot.pypy.org
Fri Aug 14 01:49:30 CEST 2015
Author: Manuel Jacob <me at manueljacob.de>
Branch: py3.3
Changeset: r78979:0387064aa761
Date: 2015-08-14 01:49 +0200
http://bitbucket.org/pypy/pypy/changeset/0387064aa761/
Log: Implement time.clock_gettime(), time.clock_settime(),
time.clock_getres() and time.CLOCK_xxx constants.
diff --git a/pypy/module/time/__init__.py b/pypy/module/time/__init__.py
--- a/pypy/module/time/__init__.py
+++ b/pypy/module/time/__init__.py
@@ -1,5 +1,6 @@
from pypy.interpreter.mixedmodule import MixedModule
+from .interp_time import CLOCK_CONSTANTS, cConfig
import os
_WIN = os.name == "nt"
@@ -21,8 +22,16 @@
}
if os.name == "posix":
+ interpleveldefs['clock_gettime'] = 'interp_time.clock_gettime'
+ interpleveldefs['clock_settime'] = 'interp_time.clock_settime'
+ interpleveldefs['clock_getres'] = 'interp_time.clock_getres'
interpleveldefs['tzset'] = 'interp_time.tzset'
+ for constant in CLOCK_CONSTANTS:
+ value = getattr(cConfig, constant)
+ if value is not None:
+ interpleveldefs[constant] = 'space.wrap(interp_time.cConfig.%s)' % constant
+
appleveldefs = {
'struct_time': 'app_time.struct_time',
'__doc__': 'app_time.__doc__',
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
@@ -4,8 +4,10 @@
from pypy.interpreter.gateway import unwrap_spec
from rpython.rtyper.lltypesystem import lltype
from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.rtime import c_clock_gettime, TIMESPEC
from rpython.rlib import rposix
from rpython.translator.tool.cbuild import ExternalCompilationInfo
+import math
import os
import sys
import time as pytime
@@ -113,6 +115,13 @@
clock_t = platform.SimpleType("clock_t", rffi.ULONG)
has_gettimeofday = platform.Has('gettimeofday')
+CLOCK_CONSTANTS = ['CLOCK_HIGHRES', 'CLOCK_MONOTONIC', 'CLOCK_MONOTONIC_RAW',
+ 'CLOCK_PROCESS_CPUTIME_ID', 'CLOCK_REALTIME',
+ 'CLOCK_THREAD_CPUTIME_ID']
+
+for constant in CLOCK_CONSTANTS:
+ setattr(CConfig, constant, platform.DefinedConstantInteger(constant))
+
if _POSIX:
calling_conv = 'c'
CConfig.timeval = platform.Struct("struct timeval",
@@ -178,6 +187,12 @@
c_localtime = external('localtime', [rffi.TIME_TP], TM_P,
save_err=rffi.RFFI_SAVE_ERRNO)
if _POSIX:
+ c_clock_settime = external('clock_settime',
+ [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ c_clock_getres = external('clock_getres',
+ [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
c_tzset = external('tzset', [], lltype.Void)
if _WIN:
win_eci = ExternalCompilationInfo(
@@ -595,6 +610,39 @@
return space.wrap(float(tt))
if _POSIX:
+ @unwrap_spec(clk_id='c_int')
+ def clock_gettime(space, clk_id):
+ with lltype.scoped_alloc(TIMESPEC) as timespec:
+ ret = c_clock_gettime(clk_id, timespec)
+ if ret != 0:
+ raise OperationError(space.w_OSError,
+ space.wrap(_get_error_msg()))
+ result = (float(rffi.getintfield(timespec, 'c_tv_sec')) +
+ float(rffi.getintfield(timespec, 'c_tv_nsec')) * 1e-9)
+ return space.wrap(result)
+
+ @unwrap_spec(clk_id='c_int', secs=float)
+ def clock_settime(space, clk_id, secs):
+ with lltype.scoped_alloc(TIMESPEC) as timespec:
+ frac = math.fmod(secs, 1.0)
+ rffi.setintfield(timespec, 'c_tv_sec', int(secs))
+ rffi.setintfield(timespec, 'c_tv_nsec', int(frac * 1e9))
+ ret = c_clock_settime(clk_id, timespec)
+ if ret != 0:
+ raise OperationError(space.w_OSError,
+ space.wrap(_get_error_msg()))
+
+ @unwrap_spec(clk_id='c_int')
+ def clock_getres(space, clk_id):
+ with lltype.scoped_alloc(TIMESPEC) as timespec:
+ ret = c_clock_getres(clk_id, timespec)
+ if ret != 0:
+ raise OperationError(space.w_OSError,
+ space.wrap(_get_error_msg()))
+ result = (float(rffi.getintfield(timespec, 'c_tv_sec')) +
+ float(rffi.getintfield(timespec, 'c_tv_nsec')) * 1e-9)
+ return space.wrap(result)
+
def tzset(space):
"""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
@@ -34,6 +34,28 @@
t2 = time.time()
assert t1 != t2 # the resolution should be at least 0.01 secs
+ def test_clock_realtime(self):
+ import os
+ if os.name != "posix":
+ skip("clock_gettime available only under Unix")
+ import time
+ t1 = time.clock_gettime(time.CLOCK_REALTIME)
+ assert isinstance(t1, float)
+ time.sleep(time.clock_getres(time.CLOCK_REALTIME))
+ t2 = time.clock_gettime(time.CLOCK_REALTIME)
+ assert t1 != t2
+
+ def test_clock_monotonic(self):
+ import os
+ if os.name != "posix":
+ skip("clock_gettime available only under Unix")
+ import time
+ t1 = time.clock_gettime(time.CLOCK_MONOTONIC)
+ assert isinstance(t1, float)
+ time.sleep(time.clock_getres(time.CLOCK_MONOTONIC))
+ t2 = time.clock_gettime(time.CLOCK_MONOTONIC)
+ assert t1 < t2
+
def test_ctime(self):
import time
raises(TypeError, time.ctime, "foo")
More information about the pypy-commit
mailing list