[dmd-concurrency] What is protected by synchronization?

Kevin Bealer kevinbealer at gmail.com
Sun Jan 31 13:33:12 PST 2010


On Sun, Jan 31, 2010 at 4:09 PM, Robert Jacques <sandford at jhu.edu> wrote:

> On Sun, 31 Jan 2010 13:52:59 -0500, Kevin Bealer <kevinbealer at gmail.com>
> wrote:
>
>> On Sun, Jan 31, 2010 at 7:51 AM, Michel Fortin <michel.fortin at michelf.com
>> >wrote:
>> ...
>>
>>
>>> Something 'unique' is accessible through only one reference in the whole
>>> program, it is guarantied to have no aliasing. With 'lent' you can lend a
>>> unique reference to a function: you know once it returns your reference
>>> is
>>> still unique. As long as this 'unique' property holds, you can safely
>>> *move*
>>> the reference between threads. As long as the unique reference is kept
>>> thread-local you can access it without atomic operations or locks.
>>> 'unique'
>>> can be seen as a temporary state as you can safely move it to immutable,
>>> mutable, shared, etc.
>>>
>>> Andrei wants to implement unique as a template, but it'll be very limited
>>> without 'lent'. If I remember well, there's no general Unique template,
>>> just
>>> a UniqueArray for arrays of primitive types. Arrays of structs would
>>> allow
>>> taking the address of struct members and create aliasing.
>>>
>>>
>> I want to point out that this is only true if there is a memory barrier at
>> the point of lending.  If object X belongs uniquely to thread 1, and it
>> gets
>> lent to thread 2, a memory barrier should happen at this point.  There are
>> several cases where you can get hurt if this is not done:
>>
>> 1. The object might have been owned by thread 2, then given to thread 1,
>> which modified it, then returned to thread 2.  In this case, the second
>> transfer is problematic because there might be a cached copy of the
>> original
>> in thread 2's L1 or L2 cache.
>>
>> 2. The object might have been in the same cache line with another object
>> that was modified, causing unintentional caching, and thus snapshotting a
>> previous version of the object's state.
>>
>> 3. Some other code might have fiddled with the object even though it is
>> 'unique' -- for example, the global garbage collector might have been run
>> by
>> thread 2, causing thread 2 to "see" a bunch of things that thread 1 thinks
>> it uniquely owns.  This is going to be garbage collector design dependent,
>> e.g. the GC might always do a memory barrier just before returning control
>> to the user, in which case, no problem.
>>
>> The unique concept is a good thing but care must be taken -- I think
>> Andrei's template version of the unique concept should be perfectly safe
>> due
>> to the fact that it does a copy.  It would be more efficient if a memory
>> barrier could be used but that doesn't help with the analytical problem
>> (making sure the old thread doesn't have a pointer stuck somewhere.)
>>
>> I just wanted to knock down what I think is a dangerous idea that some
>> people might have inferred from the discussion on 'unique' -- that thread
>> X
>> cannot have cached something if it was never 'seen' by thread X before.
>>  For
>> that matter, I'm not sure but without hard thread affinity, the CPU might
>> have a cached version of something even if it the 'thread' never saw it
>> because the last thread to run there saw it.  (Or does thread switching
>> always incur a memory barrier -- I don't know much about how that is
>> usually
>> done.)
>>
>> Kevin
>>
>
> This is a good point, but this has already been discussed and resolved in
> previous discussions. In essence, the all the ways for a unique object to
> move between threads involve memory barriers of their own which in turn
> protects the publication safety of both unique and immutable objects. As for
> the cache line issues, these are generally know as false sharing, and while
> they can be a major performance issue, they do not effect program
> correctness. Also, the problem with Andrei's library type is that it's
> shallow and not transitive. Lastly, lent doesn't refer to passing things
> between threads. It is like const, a super-type which allows a function to
> take a shared, local, owned or unique object in an agnostic manner, by
> providing the guarantee that it won't squirrel away (escape) it somewhere.
>
>
Okay, I guess I missed or skimmed those discussions.  Thanks for the
details.

Kevin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/dmd-concurrency/attachments/20100131/65cae520/attachment.htm>


More information about the dmd-concurrency mailing list