Author: Ronan Lamy <[email protected]>
Branch: cpyext-threads-gil
Changeset: r90183:8d233583a424
Date: 2017-02-18 16:47 +0000
http://bitbucket.org/pypy/pypy/changeset/8d233583a424/
Log: Move all GIL handling for PyGILState_* inside the functions
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -266,9 +266,6 @@
sig = pycode.cpython_code_signature(callable.func_code)
assert sig.argnames[0] == 'space'
self.argnames = sig.argnames[1:]
- if gil == 'pygilstate_ensure':
- assert self.argnames[-1] == 'previous_state'
- del self.argnames[-1]
assert len(self.argnames) == len(self.argtypes)
self.gil = gil
@@ -851,15 +848,11 @@
pypy_debug_catch_fatal_exception()
assert False
-def _restore_gil_state(pygilstate_release, gilstate, gil_release, _gil_auto,
tid):
+def _restore_gil_state(gil_release, _gil_auto, tid):
from rpython.rlib import rgil
# see "Handling of the GIL" above
assert cpyext_glob_tid_ptr[0] == 0
- if pygilstate_release:
- from pypy.module.cpyext import pystate
- unlock = (gilstate == pystate.PyGILState_UNLOCKED)
- else:
- unlock = gil_release or _gil_auto
+ unlock = gil_release or _gil_auto
if unlock:
rgil.release()
else:
@@ -875,11 +868,9 @@
# have the GIL, and acquire/release it
gil_acquire = (gil == "acquire" or gil == "around")
gil_release = (gil == "release" or gil == "around")
- pygilstate_ensure = (gil == "pygilstate_ensure")
- pygilstate_release = (gil == "pygilstate_release")
- assert (gil is None or gil_acquire or gil_release
- or pygilstate_ensure or pygilstate_release)
- expected_nb_args = len(argtypesw) + pygilstate_ensure
+ gil_ignore = (gil == "ignore")
+ assert (gil is None or gil_acquire or gil_release or gil_ignore)
+ expected_nb_args = len(argtypesw)
if isinstance(restype, lltype.Ptr) and error_value == 0:
error_value = lltype.nullptr(restype.TO)
@@ -893,7 +884,6 @@
def wrapper_second_level(callable, pname, *args):
from pypy.module.cpyext.pyobject import make_ref, from_ref, is_pyobj
from pypy.module.cpyext.pyobject import as_pyobj
- from pypy.module.cpyext import pystate
# we hope that malloc removal removes the newtuple() that is
# inserted exactly here by the varargs specializer
@@ -905,21 +895,12 @@
deadlock_error(pname)
rgil.acquire()
assert cpyext_glob_tid_ptr[0] == 0
- elif pygilstate_ensure:
- if cpyext_glob_tid_ptr[0] == tid:
- cpyext_glob_tid_ptr[0] = 0
- args += (pystate.PyGILState_LOCKED,)
- else:
- rgil.acquire()
- args += (pystate.PyGILState_UNLOCKED,)
+ elif gil_ignore:
+ pass
else:
if cpyext_glob_tid_ptr[0] != tid:
no_gil_error(pname)
cpyext_glob_tid_ptr[0] = 0
- if pygilstate_release:
- gilstate = rffi.cast(lltype.Signed, args[-1])
- else:
- gilstate = pystate.PyGILState_IGNORE
rffi.stackcounter.stacks_counter += 1
llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
@@ -943,8 +924,6 @@
else:
arg_conv = arg
boxed_args += (arg_conv, )
- if pygilstate_ensure:
- boxed_args += (args[-1], )
try:
result = callable(space, *boxed_args)
if not we_are_translated() and DEBUG_WRAPPER:
@@ -989,14 +968,16 @@
except Exception as e:
unexpected_exception(pname, e, tb)
- _restore_gil_state(pygilstate_release, gilstate, gil_release,
_gil_auto, tid)
+ if not gil_ignore:
+ _restore_gil_state(gil_release, _gil_auto, tid)
state.check_and_raise_exception(always=True)
return fatal_value
assert lltype.typeOf(retval) == restype
rffi.stackcounter.stacks_counter -= 1
- _restore_gil_state(pygilstate_release, gilstate, gil_release,
_gil_auto, tid)
+ if not gil_ignore:
+ _restore_gil_state(gil_release, _gil_auto, tid)
return retval
wrapper_second_level._dont_inline_ = True
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -1,10 +1,11 @@
from pypy.module.cpyext.api import (
- cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct)
+ cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct,
cpyext_glob_tid_ptr)
from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, make_ref, from_ref
from pypy.interpreter.error import OperationError
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib import rthread
from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib import rgil
PyInterpreterStateStruct = lltype.ForwardReference()
PyInterpreterState = lltype.Ptr(PyInterpreterStateStruct)
@@ -232,11 +233,15 @@
space.threadlocals.get_ec = get_possibly_deleted_ec
-@cpython_api([], PyGILState_STATE, error=CANNOT_FAIL, gil="pygilstate_ensure")
-def PyGILState_Ensure(space, previous_state):
- # The argument 'previous_state' is not part of the API; it is inserted
- # by make_wrapper() and contains PyGILState_LOCKED/UNLOCKED based on
- # the previous GIL state.
+@cpython_api([], PyGILState_STATE, error=CANNOT_FAIL, gil="ignore")
+def PyGILState_Ensure(space):
+ tid = rthread.get_or_make_ident()
+ if cpyext_glob_tid_ptr[0] == tid:
+ cpyext_glob_tid_ptr[0] = 0
+ previous_state = PyGILState_LOCKED
+ else:
+ rgil.acquire()
+ previous_state = PyGILState_UNLOCKED
must_leave = space.threadlocals.try_enter_thread(space)
ec = space.getexecutioncontext()
if not must_leave:
@@ -254,10 +259,14 @@
if not we_are_translated():
_workaround_cpython_untranslated(space)
#
+ cpyext_glob_tid_ptr[0] = tid
return rffi.cast(PyGILState_STATE, previous_state)
-@cpython_api([PyGILState_STATE], lltype.Void, gil="pygilstate_release")
+@cpython_api([PyGILState_STATE], lltype.Void, gil="ignore")
def PyGILState_Release(space, oldstate):
+ tid = rthread.get_or_make_ident()
+ assert cpyext_glob_tid_ptr[0] == tid
+ cpyext_glob_tid_ptr[0] = 0
oldstate = rffi.cast(lltype.Signed, oldstate)
ec = space.getexecutioncontext()
if ec.cpyext_gilstate_counter_noleave > 0:
@@ -266,6 +275,10 @@
assert ec.cpyext_gilstate_counter_noleave == 0
assert oldstate == PyGILState_UNLOCKED
space.threadlocals.leave_thread(space)
+ if oldstate == PyGILState_UNLOCKED:
+ rgil.release()
+ else:
+ cpyext_glob_tid_ptr[0] = tid
@cpython_api([], PyInterpreterState, error=CANNOT_FAIL)
def PyInterpreterState_Head(space):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit