[concurrency-interest] AtomicReferenceFieldUpdater vs Unsafe

Vitaly Davidovich vitalyd at gmail.com
Mon Nov 28 22:08:00 EST 2011


Ok I see - you're going by purely what JMM dictates.  In practice though I
can't imagine a lock() impl that won't issue a fence at some point
internally before the write.  Therefore I don't see how assignment to x can
move past it; the expanded lock would look something like:
- volatile load/acquire
...
- volatile write/cas/etc (assume lock succeeds, as in this example)
- x = 17

So I still don't understand how, in practice, x = 17 can move above the
lock.
 On Nov 28, 2011 9:57 PM, "David Holmes" <davidcholmes at aapt.net.au> wrote:

> **
> The HB edge only arises between an unlock and subsequent lock. Here there
> is no unlock  in T1 and hence no subsequent lock in T2 and so no HB. (Which
> is not to say that the necessary memory barriers have not been issued as a
> side-effect of other things - but there is no HB edge as per the JMM).
>
> lock() has acquire semantics as does volatile read, hence regular
> load/stores can move past them. So here:
>
> x = 17;
> l.lock();
>
> can become
>
> l.lock();
> x = 17;
>
> which in this case just makes it more likely that T2 would in practice see
> 17.
>
> David
>
> -----Original Message-----
> *From:* Vitaly Davidovich [mailto:vitalyd at gmail.com]
> *Sent:* Tuesday, 29 November 2011 12:49 PM
> *To:* dholmes at ieee.org
> *Cc:* Boehm, Hans; concurrency-interest at cs.oswego.edu; Doug Lea
> *Subject:* RE: [concurrency-interest] AtomicReferenceFieldUpdater vs
> Unsafe
>
> Yes I realized that I misread the snippet right after I sent the email -
> thanks though :).
>
> However doing a tryLock will entail reading a volatile that was set during
> lock, so shouldn't that provide the HB? Granted I'm talking about a
> specific impl in the JDK.
>
> I don't see how roach motel applies here since the lock() writes a
> volatile and prior stores can't reorder with it (subsequent ones can move
> in though).
> On Nov 28, 2011 9:39 PM, "David Holmes" <davidcholmes at aapt.net.au> wrote:
>
>> **
>> Vitaly,
>>
>> Thread 2 only reads x if the lock is not available, which means thread 1
>> must have locked it, which occurs after setting x=17.
>>
>> However in terms of happens-before, there is no HB edge here so no
>> guarantee of x being 17 AFAICS. Thread 2 has to acquire the lock after
>> thread 1 to get a HB edge that guarantees x == 17. Further, roach-motel
>> tells us that x=17 could be reordered with the lock() anyway.
>>
>> David
>>
>> -----Original Message-----
>> *From:* concurrency-interest-bounces at cs.oswego.edu [mailto:
>> concurrency-interest-bounces at cs.oswego.edu]*On Behalf Of *Vitaly
>> Davidovich
>> *Sent:* Tuesday, 29 November 2011 12:30 PM
>> *To:* Boehm, Hans
>> *Cc:* Doug Lea; concurrency-interest at cs.oswego.edu
>> *Subject:* Re: [concurrency-interest] AtomicReferenceFieldUpdater vs
>> Unsafe
>>
>> Hi Hans,
>>
>> In your example why do you say that x should be 17 (or rather, why would
>> someone assume that)? If thread one writes to x but gets descheduled before
>> locking, then clearly thread 2 is not guaranteed to read 17; how is this
>> different from if instead of using a lock, a volatile y was used?
>>
>> If thread 1 did lock before tryLock in thread 2 then the store to a
>> volatile inside lock and a read of that volatile in tryLock should be
>> sufficient to create the happens-before edge.
>>
>> I must be missing your point though.
>>
>> Thanks
>> On Nov 28, 2011 8:23 PM, "Boehm, Hans" <hans.boehm at hp.com> wrote:
>>
>>> > From: Doug Lea
>>> >
>>> > On 11/28/11 14:23, Boehm, Hans wrote:
>>> > > There's another problem with tryLock()-like methods, which I pointed
>>> > out in a
>>> > > 2007 PPoPP paper.  I think the current j.u.c.tryLock() is not
>>> > correctly
>>> > > specified.  The problem is illustrated by the following badly
>>> > designed code:
>>> > >
>>> > > Thread 1: x = 17; l.lock();
>>> > >
>>> > > Thread 2: while (l.tryLock()) l.unlock(); ... x ...  // x should be
>>> > 17 here!
>>> > >
>>> > >
>>> > > A solution, more or less adopted by C++11, is to specify tryLock() as
>>> > > allowing spurious failures,
>>> >
>>> > I think we are OK on this. The Lock spec defines tryLock in terms
>>> > of the lock being "available", which means different things
>>> > across different Lock implementations, and doesn't rule out
>>> > spurious false returns.
>>> That interpretation sounds good to me.  It does mean that a lock that
>>> was constructed before the tryLock call and has never been accessed by
>>> anything else might not be "available".
>>>
>>> Hans
>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.edu
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111128/00bdd353/attachment-0001.html>


More information about the Concurrency-interest mailing list