Skip to content
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

gh-112075: Make instance attributes stored in inline "dict" thread safe #114742

Merged
merged 8 commits into from Apr 22, 2024

Conversation

DinoV
Copy link
Contributor

@DinoV DinoV commented Jan 30, 2024

Adds some locking around when we de-materialize a dictionary.

Also adds a comment where we'll need qsbr support for materialization.

Objects/dictobject.c Outdated Show resolved Hide resolved
@DinoV DinoV marked this pull request as draft February 3, 2024 01:04
@DinoV DinoV force-pushed the nogil_dict_pydictvalues branch 4 times, most recently from 57327a2 to 0b7b010 Compare February 6, 2024 07:09
@markshannon
Copy link
Member

This looks inefficient, we really don't want locks in the fast path for attribute lookup.

Rather than putting locks around things, maybe we can revisit the way we handle objects with managed dictionaries to consider free-threading?

@DinoV
Copy link
Contributor Author

DinoV commented Feb 6, 2024

This looks inefficient, we really don't want locks in the fast path for attribute lookup.

Rather than putting locks around things, maybe we can revisit the way we handle objects with managed dictionaries to consider free-threading?

I assume you're referring to the latest unfinished version (as previous one only added a lock for dematerialization which as @colesbury pointed out isn't correct)? If so there aren't actually any locking for lookups in the fast path... There is an read w/ acquire semantics, but on strongly-ordered systems like x64 that's no different than a normal read anyway. It does introduce an incref/decref when reading from the dictionary. Also FWIW I think I don't need the spinning in _PyDictOrValues_TryGetDict and _PyDictOrValues_TryGetValues or the usage of _PYDICTORVALUES_UPDATING as I have in the current version.

I think we could get rid of the incref though if we disabled dematerialization in free-threading, but there's still going to be some ref count checks to see if the object is local, and if not to mark it as shared so that we'll free the values via QSBR. I'm not sure that can be avoided.

@DinoV
Copy link
Contributor Author

DinoV commented Feb 6, 2024

I've run into an existing complication with the existing solution I've been trying. The limitation in the byte code generator " Until the last DEOPT_IF, no objects may be allocated, INCREFed, or DECREFed." makes this leak the dict on de-opt. We could of course follow the error pattern of if (cond) { Py_DECREF(dict); DEOPT_IF(true); } but maybe that's a non-starter...

It also occurred to me that we're not just racing with de-materialization of the dict, but we're also racing with someone assigning to __dict__ and freeing the existing dict.

So an alternate plan might be:

  1. Don't incref the dicts for read
  2. Don't de-materialize shared dicts (but still de-materialize thread-local dicts)
  3. On assignment to __dict__ if the existing dict is shared then scheduled it to be freed via QSBR, otherwise free it immediately.

@markshannon
Copy link
Member

faster-cpython/ideas#651

@DinoV DinoV force-pushed the nogil_dict_pydictvalues branch 3 times, most recently from eadcc3e to 3c3537e Compare February 16, 2024 21:53
@DinoV DinoV marked this pull request as ready for review February 16, 2024 22:55
Objects/dictobject.c Outdated Show resolved Hide resolved
Include/internal/pycore_object.h Outdated Show resolved Hide resolved
Include/internal/pycore_object.h Outdated Show resolved Hide resolved
@DinoV DinoV force-pushed the nogil_dict_pydictvalues branch 4 times, most recently from f896695 to b5a3231 Compare February 21, 2024 21:09
@colesbury colesbury added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @colesbury for commit fc7d1a4 🤖

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@DinoV DinoV added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @DinoV for commit 4b85255 🤖

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@DinoV DinoV added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @DinoV for commit fac83b7 🤖

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@DinoV DinoV added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @DinoV for commit fac83b7 🤖

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@DinoV DinoV added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @DinoV for commit ac503e8 🤖

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Apr 19, 2024
@DinoV DinoV merged commit 8b541c0 into python:main Apr 22, 2024
179 of 196 checks passed
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.

None yet

5 participants