FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-112075: Make PyDictKeysObject thread-safe by DinoV · Pull Request #114741 · python/cpython · GitHub

/ cpython Public

gh-112075: Make PyDictKeysObject thread-safe - #114741

Merged
DinoV merged 6 commits into
python:mainfrom
DinoV:nogil_dict_pydictkeys
Feb 21, 2024
Merged

gh-112075: Make PyDictKeysObject thread-safe#114741
DinoV merged 6 commits into
python:mainfrom
DinoV:nogil_dict_pydictkeys

Conversation

DinoV commented Jan 30, 2024
edited by bedevere-app Bot
Loading

Copy link
Copy Markdown
Contributor

Comment thread Objects/dictobject.c Outdated
_Py_DecRefTotal(_PyInterpreterState_GET());
#endif
if (--dk->dk_refcnt == 0) {
if (_Py_atomic_add_ssize(&dk->dk_refcnt, -1) == 1) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

How about adding a macro for the free-threading version and the default version?

corona10 Jan 30, 2024
edited
Loading

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I did similar approach at listobject: 393cbef

See: _Py_SET_ITEMREF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@corona10 is there a significant difference in performance between the two builds? I'm not sure if it is worth it to add these preprocessor guards everywhere if there is no measurable effect :) Is there a different motivation than performance?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Regardless of whether we do the macro approach everywhere, I think it's a good idea in this specific case (specifically for performance).

DinoV force-pushed the nogil_dict_pydictkeys branch from 137eebe to 0891529 Compare January 30, 2024 17:31
DinoV marked this pull request as ready for review January 30, 2024 18:05
Comment thread Objects/dictobject.c Outdated
DinoV force-pushed the nogil_dict_pydictkeys branch from 0891529 to 398cb23 Compare January 31, 2024 17:04
colesbury self-requested a review January 31, 2024 20:15

colesbury left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This mostly looks good to me.

I don't think we want to be locking around shared_keys_usable_size(). It's both not sufficient for thread-safety at most of the call sites and not what we want to be doing for performance reasons.

Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment on lines +170 to +171
_Py_atomic_store_ssize(&keys->dk_nentries, keys->dk_nentries + 1);
_Py_atomic_store_ssize(&keys->dk_usable, keys->dk_usable - 1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We can use a weaker ordering here that will be faster, especially on x86 where "release" doesn't require any memory barrier:

    _Py_atomic_store_ssize_relaxed(&keys->dk_nentries, keys->dk_nentries + 1);
    _Py_atomic_store_ssize_release(&keys->dk_usable, keys->dk_usable - 1);

(I don't think we have _Py_atomic_store_ssize_release yet, though)

I find the memory orderings hard to reason correctly about, so I like to model them with CDSChecker. Here's the model I used for this:
https://github.com/colesbury/c11-model-checker/blob/cpython-models/test/gh-112075.c

Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c
Comment thread Include/cpython/pyatomic_msc.h Outdated
Comment thread Include/cpython/pyatomic_msc.h Outdated
Comment thread Objects/dictobject.c Outdated
Comment thread Objects/dictobject.c Outdated

colesbury left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

One minor formatting comment, but otherwise LGTM

Comment thread Objects/dictobject.c Outdated
if (_PyDict_HasSplitTable(mp)) {
LOCK_KEYS(keys);
dictkeys_incref(keys);
} else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
} else {
}
else {

DinoV force-pushed the nogil_dict_pydictkeys branch from 808dd89 to 4914ba8 Compare February 20, 2024 20:01
DinoV force-pushed the nogil_dict_pydictkeys branch 2 times, most recently from 90bea6a to 88ab576 Compare February 20, 2024 23:25
DinoV force-pushed the nogil_dict_pydictkeys branch from 88ab576 to a9d3666 Compare February 21, 2024 00:12
DinoV merged commit 176df09 into python:main Feb 21, 2024
woodruffw pushed a commit to woodruffw-forks/cpython that referenced this pull request Mar 4, 2024
Adds locking for shared PyDictKeysObject's for dictionaries
diegorusso pushed a commit to diegorusso/cpython that referenced this pull request Apr 17, 2024
Adds locking for shared PyDictKeysObject's for dictionaries
DinoV deleted the nogil_dict_pydictkeys branch May 31, 2024 18:23
LukasWoodtli pushed a commit to LukasWoodtli/cpython that referenced this pull request Jan 22, 2025
Adds locking for shared PyDictKeysObject's for dictionaries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants


Back | FazBrowse Home | New Git URL