summaryrefslogtreecommitdiffstats
path: root/Python/pystate.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 24f9b77..c2ccc27 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -953,6 +953,8 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
PyThread_free_lock(interp->id_mutex);
}
+ _Py_qsbr_fini(interp);
+
_PyObject_FiniState(interp);
free_interpreter(interp);
@@ -1386,6 +1388,14 @@ new_threadstate(PyInterpreterState *interp, int whence)
if (new_tstate == NULL) {
return NULL;
}
+#ifdef Py_GIL_DISABLED
+ Py_ssize_t qsbr_idx = _Py_qsbr_reserve(interp);
+ if (qsbr_idx < 0) {
+ PyMem_RawFree(new_tstate);
+ return NULL;
+ }
+#endif
+
/* We serialize concurrent creation to protect global state. */
HEAD_LOCK(runtime);
@@ -1420,6 +1430,12 @@ new_threadstate(PyInterpreterState *interp, int whence)
// Must be called with lock unlocked to avoid re-entrancy deadlock.
PyMem_RawFree(new_tstate);
}
+
+#ifdef Py_GIL_DISABLED
+ // Must be called with lock unlocked to avoid lock ordering deadlocks.
+ _Py_qsbr_register(tstate, interp, qsbr_idx);
+#endif
+
return (PyThreadState *)tstate;
}
@@ -1611,6 +1627,10 @@ tstate_delete_common(PyThreadState *tstate)
}
HEAD_UNLOCK(runtime);
+#ifdef Py_GIL_DISABLED
+ _Py_qsbr_unregister((_PyThreadStateImpl *)tstate);
+#endif
+
// XXX Unbind in PyThreadState_Clear(), or earlier
// (and assert not-equal here)?
if (tstate->_status.bound_gilstate) {
@@ -1652,6 +1672,9 @@ void
_PyThreadState_DeleteCurrent(PyThreadState *tstate)
{
_Py_EnsureTstateNotNULL(tstate);
+#ifdef Py_GIL_DISABLED
+ _Py_qsbr_detach(((_PyThreadStateImpl *)tstate)->qsbr);
+#endif
tstate_set_detached(tstate);
tstate_delete_common(tstate);
current_fast_clear(tstate->interp->runtime);
@@ -1873,6 +1896,10 @@ _PyThreadState_Attach(PyThreadState *tstate)
tstate_wait_attach(tstate);
}
+#ifdef Py_GIL_DISABLED
+ _Py_qsbr_attach(((_PyThreadStateImpl *)tstate)->qsbr);
+#endif
+
// Resume previous critical section. This acquires the lock(s) from the
// top-most critical section.
if (tstate->critical_section != 0) {
@@ -1893,6 +1920,9 @@ detach_thread(PyThreadState *tstate, int detached_state)
if (tstate->critical_section != 0) {
_PyCriticalSection_SuspendAll(tstate);
}
+#ifdef Py_GIL_DISABLED
+ _Py_qsbr_detach(((_PyThreadStateImpl *)tstate)->qsbr);
+#endif
tstate_deactivate(tstate);
tstate_set_detached(tstate);
current_fast_clear(&_PyRuntime);