GitLab will be upgraded on 31 Jan 2023 from 2.00 pm (AEDT) to 3.00 pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

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

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