8000 gh-111924: Use PyMutex for runtime global locks. by colesbury · Pull Request #112207 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-111924: Use PyMutex for runtime global locks. #112207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Changes from review
  • Loading branch information
colesbury committed Dec 7, 2023
commit e2227da44cbdfc4c0898dc17b8bd2f00d6c81237
7 changes: 7 additions & 0 deletions Include/internal/pycore_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ PyMutex_IsLocked(PyMutex *m)
return (_Py_atomic_load_uint8(&m->v) & _Py_LOCKED) != 0;
}

// Re-initializes the mutex after a fork to the unlocked state.
static inline void
_PyMutex_at_fork_reinit(PyMutex *m)
{
*m = (PyMutex){0};
}

typedef enum _PyLockFlags {
// Do not detach/release the GIL when waiting on the lock.
_Py_LOCK_DONT_DETACH = 0,
Expand Down
1 change: 1 addition & 0 deletions Python/crossinterp.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ _xidregistry_lock(struct _xidregistry *registry)
if (registry->global) {
PyMutex_Lock(&registry->mutex);
}
// else: Within an interpreter we rely on the GIL instead of a separate lock.
}

static void
Expand Down
24 changes: 16 additions & 8 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,18 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime);
_Py_COMP_DIAG_POP

#define LOCKS_INIT(runtime) \
{ \
&(runtime)->interpreters.mutex, \
&(runtime)->xi.registry.mutex, \
&(runtime)->unicode_state.ids.mutex, \
&(runtime)->imports.extensions.mutex, \
&(runtime)->ceval.pending_mainthread.mutex, \
&(runtime)->atexit.mutex, \
&(runtime)->audit_hooks.mutex, \
&(runtime)->allocators.mutex, \
}

static void
init_runtime(_PyRuntimeState *runtime,
void *open_code_hook, void *open_code_userdata,
Expand Down Expand Up @@ -476,14 +488,10 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
_PyParkingLot_AfterFork();

// Re-initialize global locks
runtime->interpreters.mutex = (PyMutex){0};
runtime->xi.registry.mutex = (PyMutex){0};
runtime->unicode_state.ids.mutex = (PyMutex){0};
runtime->imports.extensions.mutex = (PyMutex){0};
runtime->ceval.pending_mainthread.mutex = (PyMutex){0};
runtime->atexit.mutex = (PyMutex){0};
runtime->audit_hooks.mutex = (PyMutex){0};
runtime->allocators.mutex = (PyMutex){0};
PyMutex *locks[] = LOCKS_INIT(runtime);
for (size_t i = 0; i < Py_ARRAY_LENGTH(locks); i++) {
_PyMutex_at_fork_reinit(locks[i]);
}

/* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
* not force the default allocator. */
Expand Down
0