Author: Armin Rigo <[email protected]>
Branch:
Changeset: r83737:0c48102c8709
Date: 2016-04-18 12:09 +0200
http://bitbucket.org/pypy/pypy/changeset/0c48102c8709/
Log: port _pypy_wait
diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py
--- a/lib_pypy/_pypy_wait.py
+++ b/lib_pypy/_pypy_wait.py
@@ -1,51 +1,22 @@
-from resource import _struct_rusage, struct_rusage
-from ctypes import CDLL, c_int, POINTER, byref
-from ctypes.util import find_library
+from resource import ffi, lib, _make_struct_rusage
__all__ = ["wait3", "wait4"]
-libc = CDLL(find_library("c"))
-c_wait3 = libc.wait3
-c_wait3.argtypes = [POINTER(c_int), c_int, POINTER(_struct_rusage)]
-c_wait3.restype = c_int
-
-c_wait4 = libc.wait4
-c_wait4.argtypes = [c_int, POINTER(c_int), c_int, POINTER(_struct_rusage)]
-c_wait4.restype = c_int
-
-def create_struct_rusage(c_struct):
- return struct_rusage((
- float(c_struct.ru_utime),
- float(c_struct.ru_stime),
- c_struct.ru_maxrss,
- c_struct.ru_ixrss,
- c_struct.ru_idrss,
- c_struct.ru_isrss,
- c_struct.ru_minflt,
- c_struct.ru_majflt,
- c_struct.ru_nswap,
- c_struct.ru_inblock,
- c_struct.ru_oublock,
- c_struct.ru_msgsnd,
- c_struct.ru_msgrcv,
- c_struct.ru_nsignals,
- c_struct.ru_nvcsw,
- c_struct.ru_nivcsw))
def wait3(options):
- status = c_int()
- _rusage = _struct_rusage()
- pid = c_wait3(byref(status), c_int(options), byref(_rusage))
+ status = ffi.new("int *")
+ ru = ffi.new("struct rusage *")
+ pid = lib.wait3(status, options, ru)
- rusage = create_struct_rusage(_rusage)
+ rusage = _make_struct_rusage(ru)
- return pid, status.value, rusage
+ return pid, status[0], rusage
def wait4(pid, options):
- status = c_int()
- _rusage = _struct_rusage()
- pid = c_wait4(c_int(pid), byref(status), c_int(options), byref(_rusage))
+ status = ffi.new("int *")
+ ru = ffi.new("struct rusage *")
+ pid = lib.wait4(pid, status, options, ru)
- rusage = create_struct_rusage(_rusage)
+ rusage = _make_struct_rusage(ru)
- return pid, status.value, rusage
+ return pid, status[0], rusage
diff --git a/lib_pypy/_resource_build.py b/lib_pypy/_resource_build.py
--- a/lib_pypy/_resource_build.py
+++ b/lib_pypy/_resource_build.py
@@ -30,7 +30,10 @@
ffi.set_source("_resource_cffi", """
+#include <sys/types.h>
+#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/wait.h>
static const struct my_rlimit_def {
const char *name;
@@ -42,13 +45,14 @@
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
-static int my_getrusage(int who, struct rusage *result, double times[2])
+static double my_utime(struct rusage *input)
{
- if (getrusage(who, result) == -1)
- return -1;
- times[0] = doubletime(result->ru_utime);
- times[1] = doubletime(result->ru_stime);
- return 0;
+ return doubletime(input->ru_utime);
+}
+
+static double my_stime(struct rusage *input)
+{
+ return doubletime(input->ru_stime);
}
static int my_getrlimit(int resource, long long result[2])
@@ -99,9 +103,14 @@
...;
};
-void my_getrusage(int who, struct rusage *result, double times[2]);
+static double my_utime(struct rusage *);
+static double my_stime(struct rusage *);
+void getrusage(int who, struct rusage *result);
int my_getrlimit(int resource, long long result[2]);
int my_setrlimit(int resource, long long cur, long long max);
+
+int wait3(int *status, int options, struct rusage *rusage);
+int wait4(int pid, int *status, int options, struct rusage *rusage);
""")
diff --git a/lib_pypy/resource.py b/lib_pypy/resource.py
--- a/lib_pypy/resource.py
+++ b/lib_pypy/resource.py
@@ -38,20 +38,10 @@
ru_nvcsw = _structseq.structseqfield(14, "voluntary context switches")
ru_nivcsw = _structseq.structseqfield(15, "involuntary context switches")
-
-@builtinify
-def getrusage(who):
- ru = ffi.new("struct rusage *")
- times = ffi.new("double[2]")
- ret = lib.my_getrusage(who, ru, times)
- if ret == -1:
- errno = ffi.errno
- if errno == EINVAL:
- raise ValueError("invalid who parameter")
- raise error(errno)
+def _make_struct_rusage(ru):
return struct_rusage((
- times[0],
- times[1],
+ lib.my_utime(ru),
+ lib.my_stime(ru),
ru.ru_maxrss,
ru.ru_ixrss,
ru.ru_idrss,
@@ -69,6 +59,15 @@
))
@builtinify
+def getrusage(who):
+ ru = ffi.new("struct rusage *")
+ if lib.getrusage(who, ru) == -1:
+ if ffi.errno == EINVAL:
+ raise ValueError("invalid who parameter")
+ raise error(ffi.errno)
+ return _make_struct_rusage(ru)
+
+@builtinify
def getrlimit(resource):
if not (0 <= resource < lib.RLIM_NLIMITS):
return ValueError("invalid resource specified")
diff --git a/pypy/module/test_lib_pypy/test_os_wait.py
b/pypy/module/test_lib_pypy/test_os_wait.py
--- a/pypy/module/test_lib_pypy/test_os_wait.py
+++ b/pypy/module/test_lib_pypy/test_os_wait.py
@@ -1,51 +1,36 @@
-# Generates the resource cache (it might be there already, but maybe not)
+# Assumes that _resource_cffi is there already
from __future__ import absolute_import
import os
+import py
+from pypy.module.test_lib_pypy import test_resource # side-effect: skip()
-import py
-from lib_pypy.ctypes_config_cache import rebuild
-from pypy.module.test_lib_pypy.support import import_lib_pypy
+from lib_pypy import _pypy_wait
+def test_os_wait3():
+ wait3 = _pypy_wait.wait3
+ exit_status = 0x33
+ child = os.fork()
+ if child == 0: # in child
+ os._exit(exit_status)
+ else:
+ pid, status, rusage = wait3(0)
+ assert child == pid
+ assert os.WIFEXITED(status)
+ assert os.WEXITSTATUS(status) == exit_status
+ assert isinstance(rusage.ru_utime, float)
+ assert isinstance(rusage.ru_maxrss, int)
-class AppTestOsWait:
-
- spaceconfig = dict(usemodules=('_rawffi', 'itertools'))
-
- def setup_class(cls):
- if not hasattr(os, "fork"):
- py.test.skip("Need fork() to test wait3/wait4()")
- rebuild.rebuild_one('resource.ctc.py')
- cls.w__pypy_wait = import_lib_pypy(
- cls.space, '_pypy_wait',
- '_pypy_wait not supported on this platform')
-
- def test_os_wait3(self):
- import os
- wait3 = self._pypy_wait.wait3
- exit_status = 0x33
- child = os.fork()
- if child == 0: # in child
- os._exit(exit_status)
- else:
- pid, status, rusage = wait3(0)
- assert child == pid
- assert os.WIFEXITED(status)
- assert os.WEXITSTATUS(status) == exit_status
- assert isinstance(rusage.ru_utime, float)
- assert isinstance(rusage.ru_maxrss, int)
-
- def test_os_wait4(self):
- import os
- wait4 = self._pypy_wait.wait4
- exit_status = 0x33
- child = os.fork()
- if child == 0: # in child
- os._exit(exit_status)
- else:
- pid, status, rusage = wait4(child, 0)
- assert child == pid
- assert os.WIFEXITED(status)
- assert os.WEXITSTATUS(status) == exit_status
- assert isinstance(rusage.ru_utime, float)
- assert isinstance(rusage.ru_maxrss, int)
+def test_os_wait4():
+ wait4 = _pypy_wait.wait4
+ exit_status = 0x33
+ child = os.fork()
+ if child == 0: # in child
+ os._exit(exit_status)
+ else:
+ pid, status, rusage = wait4(child, 0)
+ assert child == pid
+ assert os.WIFEXITED(status)
+ assert os.WEXITSTATUS(status) == exit_status
+ assert isinstance(rusage.ru_utime, float)
+ assert isinstance(rusage.ru_maxrss, int)
diff --git a/pypy/module/test_lib_pypy/test_resource.py
b/pypy/module/test_lib_pypy/test_resource.py
--- a/pypy/module/test_lib_pypy/test_resource.py
+++ b/pypy/module/test_lib_pypy/test_resource.py
@@ -4,7 +4,10 @@
if os.name != 'posix':
skip('resource.h only available on unix')
-from lib_pypy import resource
+try:
+ from lib_pypy import resource
+except ImportError as e:
+ skip(str(e))
def test_getrusage():
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit