[jmm-dev] bitwise RMW operators, specifically testAndSetBit/BTS

Doug Lea dl at cs.oswego.edu
Fri Jul 15 23:17:19 UTC 2016

On 07/15/2016 03:24 PM, John Rose wrote:

> How should these be aligned with compareAndExchange*?
> By that I mean the ordering of reads and writes should documented
> as no weaker than as if the thing had been implemented in terms of
> some corresponding CAS loop.  (Or is there a better way?)

Right. The specs for all getAndX operations should just amount to
"equivalent to CAS loop".

> This raises a question about omitting the store.
> Suppose the operation turns out to be a no-op.
> This can mean that contention is detected or an idempotent
> op has already raced to completion.
> In that case, should the op include the Release constraint or not?

As a lock implementation question: If you fail fast path,
then if options include spinning using Thread.onSpinWait,
which has fence-like effects anyway.
And if the alternative is no-op and it is expected to be common,
then users should guard the atomic with a read to filter out
most cases. And if it is a queued lock, then you generally need
a full volatile fence anyway to operate on queue.

So, across these and other options, release overhead is not
not often measurable. Which seems to argue against complicating
effects specification by allowing the early exit in:

> Put another way, can a reference implementation include
> the marked optimization or not:
> int getAndBitwiseOr(Object x, int mask) {
>    for (;;) {
>      int val0 = get(x); // getPlain
>      int val1 = val0 & mask;
>      if (val1 == val0)  return val0;  // ALLOW THIS OPTIMIZATION?
>      int witness = compareAndExchangeRelease(x, val0, val1);
>      if (witness == val0)  return val0;
>    }
> }


More information about the jmm-dev mailing list