Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,11 @@ final Object xfer(Object e, long ns) {
q = p.next;
if (p.isData != haveData && haveData != (m != null)) {
if (p.cmpExItem(m, e) == m) {
// Full fence (StoreLoad) for Dekker with await() which
// writes waiter then reads item. On ARM64, CAS
// (ldaxr/stlxr) + plain load to a different field does
// NOT provide StoreLoad ordering.
VarHandle.fullFence();
Thread w = p.waiter; // matched complementary node
if (p != h && h == cmpExHead(h, (q == null) ? p : q))
h.next = h; // advance head; self-link old
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ final Object xferLifo(Object e, long ns) {
else if (p.cmpExItem(m, e) != m)
p = head; // missed; restart
else { // matched complementary node
// Full fence (StoreLoad) for Dekker with await() which
// writes waiter then reads item. On ARM64, CAS
// (ldaxr/stlxr) + plain load to a different field does
// NOT provide StoreLoad ordering.
// GHA Run 04
VarHandle.fullFence();
Thread w = p.waiter;
cmpExHead(p, p.next);
LockSupport.unpark(w);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,13 @@ final int acquire(Node node, int arg, boolean shared,
Thread.onSpinWait();
} else if (node.status == 0) {
node.status = WAITING; // enable signal and recheck
// Full fence (StoreLoad) to ensure WAITING status is visible
// before re-reading state in tryAcquire/tryAcquireShared
// (Dekker pattern with releaseShared/release which writes
// state then reads node.status in signalNext).
// On ARM64, volatile write (stlr) + volatile read (ldar) to
// different addresses does NOT provide StoreLoad ordering.
U.fullFence();
} else {
spins = postSpins = (byte)((postSpins << 1) | 1);
try {
Expand Down Expand Up @@ -1097,6 +1104,13 @@ public final boolean tryAcquireNanos(int arg, long nanosTimeout)
*/
public final boolean release(int arg) {
if (tryRelease(arg)) {
// Full fence (StoreLoad) to ensure the state update from
// tryRelease is visible before reading node.status in signalNext
// (Dekker pattern: release writes state then reads status,
// acquire writes status then reads state).
// On ARM64, CAS (stlxr/release) + ldar to different addresses
// does NOT provide StoreLoad ordering.
U.fullFence();
signalNext(head);
return true;
}
Expand Down Expand Up @@ -1184,6 +1198,8 @@ public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
*/
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
// Full fence (StoreLoad) — see comment in release()
U.fullFence();
signalNext(head);
return true;
}
Expand Down
Loading