diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index 442d64b7c8..0612cda347 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -29,7 +29,6 @@ extern "C" { #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids struct _getargs_runtime_state { - PyThread_type_lock mutex; struct _PyArg_Parser *static_parsers; }; @@ -96,7 +95,7 @@ typedef struct pyruntimestate { struct _signals_runtime_state signals; struct pyinterpreters { - PyThread_type_lock mutex; + _PyRawMutex mutex; /* The linked list of interpreters, newest first. */ PyInterpreterState *head; /* The runtime's initial interpreter, which has a special role @@ -115,7 +114,7 @@ typedef struct pyruntimestate { } interpreters; // XXX Remove this field once we have a tp_* slot. struct _xidregistry { - PyThread_type_lock mutex; + _PyRawMutex mutex; struct _xidregitem *head; } xidregistry; @@ -180,6 +179,10 @@ typedef struct pyruntimestate { PyInterpreterState _main_interpreter; } _PyRuntimeState; +#define HEAD_LOCK(runtime) \ + _PyRawMutex_lock(&(runtime)->interpreters.mutex) +#define HEAD_UNLOCK(runtime) \ + _PyRawMutex_unlock(&(runtime)->interpreters.mutex) /* other API */ diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 19faceebf1..f44d9a8ef1 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -26,7 +26,7 @@ extern PyTypeObject _PyUnicodeASCIIIter_Type; /* other API */ struct _Py_unicode_runtime_ids { - PyThread_type_lock lock; + _PyMutex mutex; // next_index value must be preserved when Py_Initialize()/Py_Finalize() // is called multiple times: see _PyUnicode_FromId() implementation. Py_ssize_t next_index; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f0c7aa7707..af06db6237 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1858,7 +1858,7 @@ _PyUnicode_FromId(_Py_Identifier *id) if (index < 0) { struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; - PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); + _PyMutex_lock(&rt_ids->mutex); // Check again to detect concurrent access. Another thread can have // initialized the index while this thread waited for the lock. index = _Py_atomic_size_get(&id->index); @@ -1868,7 +1868,7 @@ _PyUnicode_FromId(_Py_Identifier *id) rt_ids->next_index++; _Py_atomic_size_set(&id->index, index); } - PyThread_release_lock(rt_ids->lock); + _PyMutex_unlock(&rt_ids->mutex); } assert(index >= 0); diff --git a/Python/ceval.c b/Python/ceval.c index 7deee76cc5..ecbe2f9d51 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -97,11 +97,6 @@ #define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) #endif -#define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) -#define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) - /* Forward declarations */ static PyObject *trace_call_function( PyThreadState *tstate, PyObject *callable, PyObject **stack, diff --git a/Python/pystate.c b/Python/pystate.c index 008f1a3041..eef8d96ca3 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -63,59 +63,11 @@ _Py_COMP_DIAG_POP Py_DECL_THREAD PyThreadState *_Py_current_tstate; -static int -alloc_for_runtime(PyThread_type_lock *plock1, PyThread_type_lock *plock2, - PyThread_type_lock *plock3, PyThread_type_lock *plock4) -{ - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyThread_type_lock lock1 = PyThread_allocate_lock(); - if (lock1 == NULL) { - return -1; - } - - PyThread_type_lock lock2 = PyThread_allocate_lock(); - if (lock2 == NULL) { - PyThread_free_lock(lock1); - return -1; - } - - PyThread_type_lock lock3 = PyThread_allocate_lock(); - if (lock3 == NULL) { - PyThread_free_lock(lock1); - PyThread_free_lock(lock2); - return -1; - } - - PyThread_type_lock lock4 = PyThread_allocate_lock(); - if (lock4 == NULL) { - PyThread_free_lock(lock1); - PyThread_free_lock(lock2); - PyThread_free_lock(lock3); - return -1; - } - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - *plock1 = lock1; - *plock2 = lock2; - *plock3 = lock3; - *plock4 = lock4; - return 0; -} - static void init_runtime(_PyRuntimeState *runtime, void *open_code_hook, void *open_code_userdata, _Py_AuditHookEntry *audit_hook_head, - Py_ssize_t unicode_next_index, - PyThread_type_lock unicode_ids_mutex, - PyThread_type_lock interpreters_mutex, - PyThread_type_lock xidregistry_mutex, - PyThread_type_lock getargs_mutex) + Py_ssize_t unicode_next_index) { if (runtime->_initialized) { Py_FatalError("runtime already initialized"); @@ -133,17 +85,10 @@ init_runtime(_PyRuntimeState *runtime, PyPreConfig_InitPythonConfig(&runtime->preconfig); - runtime->interpreters.mutex = interpreters_mutex; - - runtime->xidregistry.mutex = xidregistry_mutex; - - runtime->getargs.mutex = getargs_mutex; - // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); runtime->unicode_state.ids.next_index = unicode_next_index; - runtime->unicode_state.ids.lock = unicode_ids_mutex; runtime->_initialized = 1; } @@ -161,18 +106,13 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) // is called multiple times. Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index; - PyThread_type_lock lock1, lock2, lock3, lock4; - if (alloc_for_runtime(&lock1, &lock2, &lock3, &lock4) != 0) { - return _PyStatus_NO_MEMORY(); - } - if (runtime->_initialized) { // Py_Initialize() must be running again. // Reset to _PyRuntimeState_INIT. memcpy(runtime, &initial, sizeof(*runtime)); } init_runtime(runtime, open_code_hook, open_code_userdata, audit_hook_head, - unicode_next_index, lock1, lock2, lock3, lock4); + unicode_next_index); return _PyStatus_OK(); } @@ -180,22 +120,6 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) void _PyRuntimeState_Fini(_PyRuntimeState *runtime) { - /* Force the allocator used by _PyRuntimeState_Init(). */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -#define FREE_LOCK(LOCK) \ - if (LOCK != NULL) { \ - PyThread_free_lock(LOCK); \ - LOCK = NULL; \ - } - - FREE_LOCK(runtime->interpreters.mutex); - FREE_LOCK(runtime->xidregistry.mutex); - FREE_LOCK(runtime->unicode_state.ids.lock); - FREE_LOCK(runtime->getargs.mutex); - -#undef FREE_LOCK - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } #ifdef HAVE_FORK @@ -207,27 +131,14 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) // This was initially set in _PyRuntimeState_Init(). runtime->main_thread = PyThread_get_thread_ident(); - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); - int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); - int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_state.ids.lock); - int reinit_getargs = _PyThread_at_fork_reinit(&runtime->getargs.mutex); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + memset(&runtime->interpreters.mutex, 0, sizeof(runtime->interpreters.mutex)); + memset(&runtime->xidregistry.mutex, 0, sizeof(runtime->xidregistry.mutex)); /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does * not force the default allocator. */ int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); - if (reinit_interp < 0 - || reinit_main_id < 0 - || reinit_xidregistry < 0 - || reinit_unicode_ids < 0 - || reinit_getargs < 0) + if (reinit_main_id < 0) { return _PyStatus_ERR("Failed to reinitialize runtime locks"); @@ -236,11 +147,6 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) } #endif -#define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) -#define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) - /* Forward declaration */ static void _PyGILState_NoteThreadState( struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); @@ -284,24 +190,6 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) { struct pyinterpreters *interpreters = &runtime->interpreters; interpreters->next_id = 0; - - /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. - Create a new mutex if needed. */ - if (interpreters->mutex == NULL) { - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - interpreters->mutex = PyThread_allocate_lock(); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (interpreters->mutex == NULL) { - return _PyStatus_ERR("Can't initialize threads for interpreter"); - } - } - return _PyStatus_OK(); } @@ -2168,12 +2056,12 @@ _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, } struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + _PyRawMutex_lock(&xidregistry->mutex); if (xidregistry->head == NULL) { _register_builtins_for_crossinterpreter_data(xidregistry); } int res = _xidregistry_add_type(xidregistry, cls, getdata); - PyThread_release_lock(xidregistry->mutex); + _PyRawMutex_unlock(&xidregistry->mutex); return res; } @@ -2182,13 +2070,13 @@ _PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) { int res = 0; struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + _PyRawMutex_lock(&xidregistry->mutex); struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); if (matched != NULL) { (void)_xidregistry_remove_entry(xidregistry, matched); res = 1; } - PyThread_release_lock(xidregistry->mutex); + _PyRawMutex_unlock(&xidregistry->mutex); return res; } @@ -2202,14 +2090,14 @@ _PyCrossInterpreterData_Lookup(PyObject *obj) { struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; PyObject *cls = PyObject_Type(obj); - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + _PyRawMutex_lock(&xidregistry->mutex); if (xidregistry->head == NULL) { _register_builtins_for_crossinterpreter_data(xidregistry); } struct _xidregitem *matched = _xidregistry_find_type(xidregistry, (PyTypeObject *)cls); Py_DECREF(cls); - PyThread_release_lock(xidregistry->mutex); + _PyRawMutex_unlock(&xidregistry->mutex); return matched != NULL ? matched->getdata : NULL; }