Commit 12f26146 authored by John Zhang's avatar John Zhang

fix: spawning child processes for tests that requires a running Mu instance;...

fix: spawning child processes for tests that requires a running Mu instance; add option to load shared library using RTLD_GLOBAL, toegether with spawning, fix problem with test_throw that fails after running other tests
parent 6c16d1db
from util import fncptr_from_c_script, preload_libmu
from util import fncptr_from_c_script, may_spawn_proc, mu_instance_via_ctyeps
import ctypes
def test_eq_int():
fn, _ = fncptr_from_c_script("test_eq_int.c", "test_fnc")
assert fn() == 0
def mu_instance_via_ctyeps():
libmu = preload_libmu()
class MuVM(ctypes.Structure):
pass
MuVM._fields_ = [
('header', ctypes.c_voidp),
('new_context', ctypes.c_voidp), # function pointers should have the same size as c_voidp
('id_of', ctypes.c_voidp),
('name_of', ctypes.c_voidp),
('set_trap_handler', ctypes.c_voidp),
('compile_to_sharedlib', ctypes.c_voidp),
('current_thread_as_mu_thread', ctypes.CFUNCTYPE(None, ctypes.POINTER(MuVM), ctypes.c_voidp)),
]
libmu.mu_fastimpl_new.restype = ctypes.POINTER(MuVM)
mu = libmu.mu_fastimpl_new()
mu.contents.current_thread_as_mu_thread(mu, None)
return mu
@may_spawn_proc
def test_eq_ref():
mu = mu_instance_via_ctyeps()
fn, _ = fncptr_from_c_script("test_eq_ref.c", "test_fnc")
......@@ -32,6 +15,7 @@ def test_ne_int():
fn, _ = fncptr_from_c_script("test_ne_int.c", "test_fnc")
assert fn() == 1
@may_spawn_proc
def test_ne_ref():
mu = mu_instance_via_ctyeps()
fn, _ = fncptr_from_c_script("test_ne_ref.c", "test_fnc")
......
from util import fncptr_from_c_script
import ctypes
import pytest
def within_err(res, exp, err=1e15):
return abs(res - exp) < err
......@@ -67,6 +67,7 @@ def test_double_sitofp():
assert fnp() == -42.0
@pytest.mark.xfail(reason='not implemented yet')
def test_double_uitofp():
fnp, _ = fncptr_from_c_script("test_double_uitofp.c", "test_fnc", restype=ctypes.c_double)
assert fnp() == 42.0
......@@ -77,6 +78,7 @@ def test_double_fptosi():
assert fnp() == -3
@pytest.mark.xfail(reason='not implemented yet')
def test_double_fptoui():
fnp, _ = fncptr_from_c_script("test_double_fptoui.c", "test_fnc", restype=ctypes.c_uint64)
assert fnp() == 3
......
from util import fncptr_from_c_script, preload_libmu
from util import fncptr_from_c_script, mu_instance_via_ctyeps, may_spawn_proc
import ctypes
def test_select():
......@@ -6,7 +6,8 @@ def test_select():
assert fnp(0) == 20
assert fnp(1) == 10
@may_spawn_proc
def test_commoninst_pin():
mu = mu_instance_via_ctyeps()
fnp, _ = fncptr_from_c_script("test_commoninst_pin.c", 'test_pin')
assert fnp() == 6
......@@ -205,15 +205,6 @@ def test_quicksort():
lst_s = sorted(lst)
print "expected list:"
print lst_s
print "result:"
for i in range(n):
print arr[i],
else:
print
for i in range(n):
assert lst_s[i] == arr[i], "%d != %d" % (lst_s[i], arr[i])
......@@ -844,7 +835,7 @@ def test_throw():
from rpython.rlib import rmu_fast as rmu
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'test_fnc', [ctypes.c_int64],
ctypes.c_int64)
ctypes.c_int64, mode=ctypes.RTLD_GLOBAL)
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp(0) == 20
assert fnp(100) == 10
......@@ -991,7 +982,7 @@ def test_exception_stack_unwind():
"@refi64": refi64
}
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'test_fnc', [ctypes.c_int64],
ctypes.c_int64)
ctypes.c_int64, mode=ctypes.RTLD_GLOBAL)
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp(0) == 20
assert fnp(100) == 10
......
......@@ -20,6 +20,25 @@ else:
libmu_path = proj_dir.join('target', 'debug', 'libmu' + libext)
def mu_instance_via_ctyeps():
libmu = preload_libmu()
class MuVM(ctypes.Structure):
pass
MuVM._fields_ = [
('header', ctypes.c_voidp),
('new_context', ctypes.c_voidp), # function pointers should have the same size as c_voidp
('id_of', ctypes.c_voidp),
('name_of', ctypes.c_voidp),
('set_trap_handler', ctypes.c_voidp),
('compile_to_sharedlib', ctypes.c_voidp),
('current_thread_as_mu_thread', ctypes.CFUNCTYPE(None, ctypes.POINTER(MuVM), ctypes.c_voidp)),
]
libmu.mu_fastimpl_new.restype = ctypes.POINTER(MuVM)
mu = libmu.mu_fastimpl_new()
mu.contents.current_thread_as_mu_thread(mu, None)
return mu
def compile_c_script(c_src_name):
testname = c_src_name[:-2]
src_c = testsuite_dir.join(c_src_name)
......@@ -53,15 +72,15 @@ def compile_c_script(c_src_name):
return py.path.local('emit').join('lib%(testname)s' % locals() + libext)
def ctypes_fncptr_from_lib(libpath, fnc_name, argtypes=[], restype=ctypes.c_longlong):
lib = ctypes.CDLL(libpath.strpath, ctypes.RTLD_GLOBAL)
def ctypes_fncptr_from_lib(libpath, fnc_name, argtypes=[], restype=ctypes.c_longlong, mode=ctypes.RTLD_LOCAL):
lib = ctypes.CDLL(libpath.strpath, mode)
fnp = getattr(lib, fnc_name)
fnp.argtypes = argtypes
fnp.restype = restype
return fnp, lib
def rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, restype):
def rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, restype, mode=ctypes.RTLD_LOCAL):
from rpython.rtyper.lltypesystem import rffi
from rpython.translator.platform import platform
if platform.name.startswith('linux'):
......@@ -70,6 +89,9 @@ def rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, restype):
link_extra = []
libname = libpath.basename[3:libpath.basename.index(libext)]
if mode == ctypes.RTLD_GLOBAL:
lib = ctypes.CDLL(libpath.strpath, mode) # preload lib using RTLD_GLOBAL
return rffi.llexternal(fnc_name, llargtypes, restype,
compilation_info=rffi.ExternalCompilationInfo(
libraries=[libname],
......@@ -79,22 +101,22 @@ def rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, restype):
_nowrapper=True)
def fncptr_from_c_script(c_src_name, name, argtypes=[], restype=ctypes.c_ulonglong):
def fncptr_from_c_script(c_src_name, name, argtypes=[], restype=ctypes.c_ulonglong, mode=ctypes.RTLD_LOCAL):
libpath = compile_c_script(c_src_name)
return ctypes_fncptr_from_lib(libpath, name, argtypes, restype)
return ctypes_fncptr_from_lib(libpath, name, argtypes, restype, mode)
def is_ctypes(t):
return isinstance(t, type(ctypes.c_longlong))
def fncptr_from_py_script(py_fnc, heapinit_fnc, name, argtypes=[], restype=ctypes.c_longlong, **kwargs):
def fncptr_from_py_script(py_fnc, heapinit_fnc, name, argtypes=[], restype=ctypes.c_longlong, mode=ctypes.RTLD_LOCAL, **kwargs):
import os
# NOTE: requires mu-client-pypy
from rpython.rlib import rmu_fast as rmu
# load libmu before rffi so to load it with RTLD_GLOBAL
libmu = ctypes.CDLL(libmu_path.strpath, ctypes.RTLD_GLOBAL)
libmu = preload_libmu()
loglvl = os.environ.get('MU_LOG_LEVEL', 'none')
emit_dir = kwargs.get('muemitdir', os.environ.get('MU_EMIT_DIR', 'emit'))
......@@ -110,9 +132,9 @@ def fncptr_from_py_script(py_fnc, heapinit_fnc, name, argtypes=[], restype=ctype
mu.compile_to_sharedlib(libpath.strpath, [])
if (len(argtypes) > 0 and is_ctypes(argtypes[0])) or is_ctypes(restype):
return ctypes_fncptr_from_lib(libpath, name, argtypes, restype), (mu, ctx, bldr)
return ctypes_fncptr_from_lib(libpath, name, argtypes, restype, mode), (mu, ctx, bldr)
else:
return rffi_fncptr_from_lib(libpath, name, argtypes, restype), (mu, ctx, bldr)
return rffi_fncptr_from_lib(libpath, name, argtypes, restype, mode), (mu, ctx, bldr)
def preload_libmu():
......@@ -133,7 +155,7 @@ def may_spawn_proc(test_fnc):
return wrapper
def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs):
def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, mode=ctypes.RTLD_LOCAL, **kwargs):
# NOTE: requires mu-client-pypy
from rpython.rtyper.lltypesystem import rffi
from rpython.translator.interactive import Translation
......@@ -159,4 +181,4 @@ def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs):
libpath = t.compile_c()
fnc_name = 'pypy_g_' + rpy_fnc.__name__
extras = None
return rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, llrestype), extras
return rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, llrestype, mode), extras
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment