The GitHub Actions job "Nightly Builds" on pekko.git/main has failed.
Run started by GitHub user He-Pin (triggered by He-Pin).

Head commit for run:
c1910b21367c3ad2ffc8b26685f972140318d953 / He-Pin(kerr) <[email protected]>
fix: restore volatile reads/writes downgraded by the VarHandle migration (#3008)

Motivation:
The migration from sun.misc.Unsafe to VarHandle (#1990, and #1894 for
Mailbox) replaced the producer writes correctly (compareAndSwapObject
-> compareAndSet, putOrderedObject -> setRelease) but silently
downgraded the corresponding reads and a couple of writes from
volatile to plain access: `Unsafe.getObjectVolatile`/`getIntVolatile`/
`getLongVolatile` became `VarHandle.get` (plain) and two
`putObjectVolatile`/`putIntVolatile` became `VarHandle.set` (plain).

`VarHandle.get`/`set` have plain memory semantics even when the field
is declared `volatile`, so these accesses lost their happens-before
guarantees with the concurrent compareAndSet/setRelease publications.
On weakly-ordered hardware (AArch64) a reader can observe a stale value,
and inside tight loops the plain read may be hoisted by the JIT. (On
x86-64 plain loads happen to have acquire semantics, which is why this
mostly went unnoticed.)

Modification — restore the original ordered semantics on every
downgraded access:
- Mailbox: `currentStatus`/`setStatus` and `systemQueueGet` (status and
  system-message queue head).
- ActorCell: `mailbox` (Dispatch), `childrenRefs`/`functionRefs` reads
  and the `setTerminated` write (Children).
- RepointableActorRef: `underlying`/`lookup` cell reads.
- CircuitBreaker: `currentState`/`currentResetTimeout` reads.
- PromiseActorRef (AskSupport): `state`/`watchedBy` reads and the
  `setState` write.
- MessageDispatcher: `inhabitants`/`shutdownSchedule` reads.
- Artery Association: `associationState` read.

CAS-published fields use `getVolatile`/`setVolatile` (restoring the
exact getObjectVolatile/putObjectVolatile semantics). For a load,
`getVolatile` compiles to the same instruction as a plain load on
x86-64 (MOV) and to LDAR on AArch64 — i.e. exactly what the original
Unsafe code emitted — so this restores the prior semantics at no extra
cost on the read side. The two writes restored to `setVolatile` carry a
StoreLoad fence as they did before the migration.

The node-queue spin reads (AbstractNodeQueue/AbstractBoundedNodeQueue)
are addressed separately, as they pair with release stores and use
getAcquire.

Result:
All concurrently-accessed fields that were volatile before the
Unsafe->VarHandle migration are volatile again, closing latent
visibility races (most importantly the mailbox status / system-message
queue and the actor cell/mailbox references). Method signatures are
unchanged, so there is no binary-compatibility impact.

References: https://github.com/apache/pekko/issues/2870

Report URL: https://github.com/apache/pekko/actions/runs/26635194243

With regards,
GitHub Actions via GitBox


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to