Use atomic RMW for {mutex, rwlock, cond, srwlock}_get_or_create_id functions#2114
Use atomic RMW for {mutex, rwlock, cond, srwlock}_get_or_create_id functions#2114bors merged 4 commits intorust-lang:masterfrom
{mutex, rwlock, cond, srwlock}_get_or_create_id functions#2114Conversation
ecx.read_scalar_at_offset_atomic(mutex_op, 4, ecx.machine.layouts.u32, AtomicReadOp::Acquire)
@RalfJung I agree, changed them back to |
I agree, except that this here is Abstract Machine code that runs "on the meta level" so I am somewhat surprised it needs to play by the same rules. Using interpreter memory to store the state of these things seemed like a clever idea, but maybe it wasn't... |
|
Thanks. :-) |
|
📌 Commit 9e38dc4 has been approved by |
|
☀️ Test successful - checks-actions |
This is required for #1963
{mutex, rwlock, cond, srwlock}_get_or_create_id()currently checks whether an ID field is 0 using an atomic read, allocate one and get a new ID if it is, then write it in a separate atomic write. This is fine without weak memory. For instance, inpthread_mutex_lockwhich may be called by two threads concurrently, only one thread can read 0, create and then write a new ID, the later-run thread will always see the newly created ID and never 0.However, with weak memory behaviour, both threads may read 0: the first thread has to see 0 because nothing else was written to it, and the second thread is not guaranteed to observe the latest value, causing a duplicate mutex to be created and both threads "successfully" acquiring the lock at the same time.
This is a pretty typical pattern requiring the use of atomic RMWs. RMW always reads the latest value in a location, so only one thread can create the new mutex and ID, all others scheduled later will see the new ID.