476 changes: 476 additions & 0 deletions pypy/module/cpyext/test/test_signature.py

Large diffs are not rendered by default.

21 changes: 15 additions & 6 deletions rpython/jit/metainterp/test/test_fficall.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import py
import py, pytest
from _pytest.monkeypatch import monkeypatch
import sys
import ctypes, math
Expand Down Expand Up @@ -49,10 +49,13 @@ def _run(self, atypes, rtype, avalues, rvalue,
expected_call_release_gil_i=1,
expected_call_release_gil_f=0,
expected_call_release_gil_n=0,
expected_call_may_force_i=0,
expected_call_may_force_f=0,
expected_call_may_force_n=0,
supports_floats=True,
supports_longlong=False,
supports_singlefloats=False):
supports_singlefloats=False,
releasegil=True):

cif_description = get_description(atypes, rtype)

Expand All @@ -75,7 +78,7 @@ def verify(*args):
unroll_avalues = unrolling_iterable(avalues)
BIG_ENDIAN = (sys.byteorder == 'big')

def fake_call_impl_any(cif_description, func_addr, exchange_buffer):
def fake_call_impl_any(cif_description, func_addr, exchange_buffer, releasegil=True):
ofs = 16
for avalue in unroll_avalues:
TYPE = rffi.CArray(lltype.typeOf(avalue))
Expand Down Expand Up @@ -117,7 +120,7 @@ def f(i):
rffi.cast(lltype.Ptr(TYPE), targetptr)[0] = avalue
targetptr = rffi.ptradd(targetptr, 16)

jit_ffi_call(cif_description, func_addr, exbuf)
jit_ffi_call(cif_description, func_addr, exbuf, releasegil=releasegil)

if rvalue is None:
res = 654321
Expand Down Expand Up @@ -152,9 +155,9 @@ def matching_result(res, rvalue):
# longlong and floats are passed around as longlongs.
res = float2longlong(res)
assert matching_result(res, rvalue)
self.check_operations_history(call_may_force_i=0,
self.check_operations_history(call_may_force_i=expected_call_may_force_i,
call_may_force_f=expected_call_may_force_f,
call_may_force_n=0,
call_may_force_n=expected_call_may_force_n,
call_release_gil_i=expected_call_release_gil_i,
call_release_gil_f=expected_call_release_gil_f,
call_release_gil_n=expected_call_release_gil_n)
Expand Down Expand Up @@ -386,3 +389,9 @@ def test_calldescrof_dynamic_returning_none(self):
expected_call_may_force_f=1)
finally:
LLGraphCPU.calldescrof_dynamic = old

@pytest.mark.xfail
def test_simple_call_int_dont_release_gil(self):
self._run([types.signed] * 2, types.signed, [456, 789], -42, releasegil=False,
expected_call_release_gil_i=0, expected_call_may_force_i=1)

4 changes: 4 additions & 0 deletions rpython/rlib/clibffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ def get_libc_name():
c_ffi_call = external('ffi_call', [FFI_CIFP, rffi.VOIDP, rffi.VOIDP,
VOIDPP], c_ffi_call_return_type,
save_err=rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
c_ffi_call_no_release_gil = external('ffi_call', [FFI_CIFP, rffi.VOIDP, rffi.VOIDP,
VOIDPP], c_ffi_call_return_type,
save_err=rffi.RFFI_ERR_ALL |
rffi.RFFI_ALT_ERRNO, releasegil=False)
# Note: the RFFI_ALT_ERRNO flag matches the one in pyjitpl.direct_libffi_call
CALLBACK_TP = rffi.CCallback([FFI_CIFP, rffi.VOIDP, rffi.VOIDPP, rffi.VOIDP],
lltype.Void)
Expand Down
19 changes: 13 additions & 6 deletions rpython/rlib/jit_libffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def jit_ffi_prep_cif(cif_description):
## have just read it from when called *in interpreter mode* only.


def jit_ffi_call(cif_description, func_addr, exchange_buffer):
def jit_ffi_call(cif_description, func_addr, exchange_buffer, releasegil=True):
"""Wrapper around ffi_call(). Must receive a CIF_DESCRIPTION_P that
describes the layout of the 'exchange_buffer'.
Expand Down Expand Up @@ -131,7 +131,8 @@ def jit_ffi_call(cif_description, func_addr, exchange_buffer):
#
# Since call_release_gil is not generated, there is no need to
# jit_ffi_save_result
jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer)
jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer,
releasegil=releasegil)


_short_sint_types = unrolling_iterable([rffi.SIGNEDCHAR, rffi.SHORT, rffi.INT])
Expand Down Expand Up @@ -231,7 +232,7 @@ def jit_ffi_call_impl_void(cif_description, func_addr, exchange_buffer):
jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer)
return None

def jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer):
def jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer, releasegil=True):
"""
This is the function which actually calls libffi. All the rest is just
infrastructure to convince the JIT to pass a typed result box to
Expand All @@ -243,9 +244,15 @@ def jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer):
buffer_array[i] = data
resultdata = rffi.ptradd(exchange_buffer,
cif_description.exchange_result)
clibffi.c_ffi_call(cif_description.cif, func_addr,
rffi.cast(rffi.VOIDP, resultdata),
buffer_array)
if releasegil:
clibffi.c_ffi_call(cif_description.cif, func_addr,
rffi.cast(rffi.VOIDP, resultdata),
buffer_array)
else:
clibffi.c_ffi_call_no_release_gil(cif_description.cif, func_addr,
rffi.cast(rffi.VOIDP, resultdata),
buffer_array)



# ____________________________________________________________
Expand Down