B[X]
is not atomic. But if it even would be atomic, it wouldn't help much.
The problem is that you have expression of multiple atomic operations. Although operations are atomic, the whole expression is not atomic.
Or: an expression containing of multiple atomic operations does not need to be atomic.
The class invariant here should be that cur
points to the current object in buf
.
But this invariant is broken between 2 atomic operations fetch_add
and store
.
If B[X]
would be atomic (which is not), one would have following sequence of atomic operations for push:
X = cur.fetch_add(1); // atomic
// 1. dT
ref = B[X]; // let's assume atomic
// 2. dT
ref.store(i); // atomic
For example in the time interval 2.dT imagine second thread popping 2 items and third thread pushing 1 item, all executing before ref.store(i)
. In this time the value under ref
reference would change.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…