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

Reply via email to