-
-
Notifications
You must be signed in to change notification settings - Fork 32k
Some operations on managed dict are not safe from memory_order POV #133980
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
Comments
I think these are fine: 1: GC traverse is called during stop the world (no other threads are running) so it doesn't need atomics _PyObject_InitInlineValues: object initialization doesn't need atomics (no other threads have access to those fields) The _PyObject_SetManagedDict: this is code in an |
Thanks for explanation! About Lines 1933 to 1935 in 9ad0c7b
|
Yes, it should use atomic store with release memory order, created #133988 to fix it. Reproducer: from threading import Thread
e = Exception()
def writer():
for i in range(10000):
e.__dict__ = {1:2}
def reader():
for i in range(10000):
e.__dict__
t1 = Thread(target=writer)
t2 = Thread(target=reader)
t1.start()
t2.start()
t1.join()
t2.join() |
@kumaraditya303 Thanks! |
…nGH-133988) (cherry picked from commit ec39fd2) Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Uh oh!
There was an error while loading. Please reload this page.
Bug report
Bug description:
First of all, I'm not a threading expert and my understanding of the memory-ordering model may be wrong. So, if I'm wrong I will be happy to fix my knowledge lacoons.
I saw some inconsistency (from my sight) of loading and writing of managed dict pointer.
Non-atomic loads:
PyObject_VisitManagedDict
cpython/Objects/dictobject.c
Line 7202 in 9ad0c7b
PyObject_ClearManagedDict
cpython/Objects/dictobject.c
Line 7462 in 9ad0c7b
_PyObject_GetDictPtr
cpython/Objects/object.c
Line 1541 in 9ad0c7b
Non-atomic stores:
_PyObject_InitInlineValues
cpython/Objects/dictobject.c
Lines 6787 to 6791 in 9ad0c7b
IIUC mixing of non-atomic loads/stores with atomic ones may lead to data races.
memory_order_acquire
loads:_PyObject_GetManagedDict
cpython/Include/internal/pycore_object.h
Lines 932 to 936 in 9ad0c7b
memory_order_release
stores:_PyObject_MaterializeManagedDict_LockHeld
cpython/Objects/dictobject.c
Lines 6827 to 6829 in 9ad0c7b
store_instance_attr_lock_held
cpython/Objects/dictobject.c
Lines 6925 to 6927 in 9ad0c7b
ensure_managed_dict
cpython/Objects/dictobject.c
Lines 7494 to 7495 in 9ad0c7b
memory_order_seq_cst
stores:set_dict_inline_values
cpython/Objects/dictobject.c
Line 7225 in 9ad0c7b
try_set_dict_inline_only_or_other_dict
cpython/Objects/dictobject.c
Lines 7252 to 7253 in 9ad0c7b
replace_dict_probably_inline_materialized
cpython/Objects/dictobject.c
Lines 7287 to 7289 in 9ad0c7b
IIUC mixing acquire/release with seq_cst may break total order of seq_cst operations.
Mixing with
memory_order_seq_cst
stores_PyObject_SetManagedDict
cpython/Objects/dictobject.c
Lines 7356 to 7365 in 9ad0c7b
_PyObject_SetManagedDict
uses non-atomic load but stores withseq_cst
mode so it is OK (IIUC), but following store without fence may lead to data race.Are my findings valid or am I completely wrong?
cc @colesbury @kumaraditya303
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Linked PRs
PyObject_GenericSetDict
#133988PyObject_GenericSetDict
(GH-133988) #134354The text was updated successfully, but these errors were encountered: