[dmd-concurrency] What is protected by synchronization?
Robert Jacques
sandford at jhu.edu
Sun Jan 31 13:09:02 PST 2010
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.
More information about the dmd-concurrency
mailing list