-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-114940: Use fine-grained mutex protection for PyInterpreterState.threads
#125561
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
Conversation
rruuaanng
commented
Oct 16, 2024
•
edited by bedevere-app
bot
Loading
edited by bedevere-app
bot
- Issue: Add a Per-Interpreter "HEAD" Lock #114940
mutex
member to PyInterpreterState.threads
mutex
member to PyInterpreterState.threads
This shouldn't have a NEWS entry--it's not a user-facing change. (The interpreter state structure is not public.) While we're here, it might be good to replace the uses of |
I chose to remove NEWS, and HEAD_LOCK will not be completely replaced. It depends on @ericsnowcurrently plans (if it wants to make the interpreter thread use |
…e-114940.Sev-r-.rst
Yeah, I know. We just need to replace it in the |
Currently I have replaced gc_free_threading.c, ceval.c, ceval_gil.c, instrumentation.c. |
Hmm, that doesn't seem right. I would expect most of the changes to be in |
I'm actually not sure since this only seems to be related to |
Sorry to ping you directly @ericsnowcurrently, a lot of the stuff in gc_free_threading seems to be about cleaning up the current interpreter state, I changed them to lock the current interpreter, Is this correct? |
Cleaning up an interpreter state (assuming you mean |
Sorry, I seem to have described it wrong. They are all traversing the current state, not cleaning. Please forgive my wrong words. |
42fbb68
to
29c4ccb
Compare
Link this issue to this PR: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This requires more careful auditing of code that loops over interpreters and threads. There's still functions that acquire the wrong lock or are now missing a lock, because the code assumed that an outer HEAD_LOCK()
was sufficient.
PyOS_BeforeFork/PyOS_AfterFork_Parent
also need to acquire the interpreter lockget_reftotal
loops over threads ifPy_GIL_DISABLED
get_mimalloc_allocated_blocks
loops over threads
@@ -791,18 +790,16 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) | |||
} | |||
|
|||
// Clear the current/main thread state last. | |||
HEAD_LOCK(runtime); | |||
INTERP_HEAD_LOCK(interp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @ericsnowcurrently pointed this out in a different comment, but we should not change where the lock/unlocks happen in this PR.
The existing code has a race condition, but holding the lock across the PyThreadState_Clear()
call risks deadlock (see the code comment below).
In fact, my current plan is to add mutex locks to all operations related to thread members. In fact, this is the meaning of its existence. But I'm thinking, as you said, maybe we should protect other functions worth adding locks. |
A few notes here.
|
Yes, for this PR, I will be very focused and listen to all the advice. Because this change is very important, in fact, I have been evaluating the status of multithreading and interpreter recently. I hope this PR can be audited by more people. Thank you for your good advice. |
Link this issue to this PR: And, CI warnings can be ignored, they come from (runtime not used)
|
I replaced the lock of |
In the interest of understanding what actually needs to be switched to the new lock, I ended up implementing this change separately: gh-127037. I'd be fine if we updated this PR to merge in my changes, since they're very similar and I'd be glad for you (@rruuaanng) to get credit. 😄 |
@ericsnowcurrently Oh, at a glance, I seem to think they are the same, but they are not consistent. This is very helpful to me. If we wait until the merger, maybe this PR can be merged with it. Edit They seem to be the same :( |
I think just adding |
If it's okay for me to be a co-signed, I think it's good 😀 |
I ended up splitting up the changes into gh-127077 and gh-127115, and credited @rruuaanng on the latter one. Let's close this PR. |