Thread overview
Re: Double Checked Locking
Dec 17, 2011
Andrew Wiley
Dec 17, 2011
Jonathan M Davis
Dec 18, 2011
Jonathan M Davis
Dec 17, 2011
Sean Kelly
Dec 17, 2011
Sean Kelly
Jan 05, 2012
Martin Nowak
December 17, 2011
On Sat, Dec 17, 2011 at 1:47 AM, Andrew Wiley <wiley.andrew.j@gmail.com> wrote:
> I was looking through Jonathan Davis's pull request to remove static
> constructors from std.datetime, and I realized that I don't know
> whether Double Checked Locking is legal under D's memory model, and
> what the requirements for it to work would be.
> (if you're not familiar with the term, check out
> http://en.wikipedia.org/wiki/Double-checked_locking - it's a useful
> but problematic programming pattern that can cause subtle concurrency
> bugs)
> It seems like it should be legal as long as the variable tested and
> initialized is flagged as shared so that the compiler enforces proper
> fences, but is this actually true?

This entry in the FAQ makes me suspicious:
```
What does shared have to do with memory barriers?

Reading/writing shared data emits memory barriers to ensure sequential
consistency (not implemented).
```

So DCL should be alright with data flagged as shared, but it's not implemented in the compiler?
December 17, 2011
No. The most efficient thing would be to use core.atomic atomicLoad!msync.acq() for the read and atomicStore!msync.rel() for the write. Use a temporary to construct the instance, etc. I think Andrei outlined the proper approach in a series of articles a while back.

Sent from my iPhone

On Dec 16, 2011, at 11:47 PM, Andrew Wiley <wiley.andrew.j@gmail.com> wrote:

> I was looking through Jonathan Davis's pull request to remove static
> constructors from std.datetime, and I realized that I don't know
> whether Double Checked Locking is legal under D's memory model, and
> what the requirements for it to work would be.
> (if you're not familiar with the term, check out
> http://en.wikipedia.org/wiki/Double-checked_locking - it's a useful
> but problematic programming pattern that can cause subtle concurrency
> bugs)
> It seems like it should be legal as long as the variable tested and
> initialized is flagged as shared so that the compiler enforces proper
> fences, but is this actually true?
December 17, 2011
On 12/17/11 1:56 AM, Andrew Wiley wrote:
> On Sat, Dec 17, 2011 at 1:47 AM, Andrew Wiley<wiley.andrew.j@gmail.com>  wrote:
>> I was looking through Jonathan Davis's pull request to remove static
>> constructors from std.datetime, and I realized that I don't know
>> whether Double Checked Locking is legal under D's memory model, and
>> what the requirements for it to work would be.
>> (if you're not familiar with the term, check out
>> http://en.wikipedia.org/wiki/Double-checked_locking - it's a useful
>> but problematic programming pattern that can cause subtle concurrency
>> bugs)
>> It seems like it should be legal as long as the variable tested and
>> initialized is flagged as shared so that the compiler enforces proper
>> fences, but is this actually true?
>
> This entry in the FAQ makes me suspicious:
> ```
> What does shared have to do with memory barriers?
>
> Reading/writing shared data emits memory barriers to ensure sequential
> consistency (not implemented).
> ```
>
> So DCL should be alright with data flagged as shared, but it's not
> implemented in the compiler?

That is correct.

Andrei
December 17, 2011
On Saturday, December 17, 2011 09:50:26 Andrei Alexandrescu wrote:
> On 12/17/11 1:56 AM, Andrew Wiley wrote:
> > On Sat, Dec 17, 2011 at 1:47 AM, Andrew Wiley<wiley.andrew.j@gmail.com>
wrote:
> >> I was looking through Jonathan Davis's pull request to remove static
> >> constructors from std.datetime, and I realized that I don't know
> >> whether Double Checked Locking is legal under D's memory model, and
> >> what the requirements for it to work would be.
> >> (if you're not familiar with the term, check out
> >> http://en.wikipedia.org/wiki/Double-checked_locking - it's a useful
> >> but problematic programming pattern that can cause subtle concurrency
> >> bugs)
> >> It seems like it should be legal as long as the variable tested and
> >> initialized is flagged as shared so that the compiler enforces proper
> >> fences, but is this actually true?
> > 
> > This entry in the FAQ makes me suspicious:
> > ```
> > What does shared have to do with memory barriers?
> > 
> > Reading/writing shared data emits memory barriers to ensure sequential
> > consistency (not implemented).
> > ```
> > 
> > So DCL should be alright with data flagged as shared, but it's not implemented in the compiler?
> 
> That is correct.

Well, you learn something new every day I guess. I'd never even heard of double-checked locking before this. I came up with it on my own in an attempt to reduce how much the mutex was used. Is the problem with it that the write isn't actually atomic? Wikipedia makes it sound like the problem might be that the object might be partially initialized but not fully initialized, which I wouldn't have thought possible, since I would have thought that the object would be fully initialized and _then_ the reference would be assigned to it. And it's my understanding that a pointer assignment like that would be atomic. Or is there more going on than that, making it so that the assignment itself really isn't atomic?

- Jonathan M Davis
December 17, 2011
On 12/17/11 5:03 PM, Jonathan M Davis wrote:
> Well, you learn something new every day I guess. I'd never even heard of
> double-checked locking before this. I came up with it on my own in an attempt
> to reduce how much the mutex was used. Is the problem with it that the write
> isn't actually atomic? Wikipedia makes it sound like the problem might be that
> the object might be partially initialized but not fully initialized, which I
> wouldn't have thought possible, since I would have thought that the object
> would be fully initialized and _then_ the reference would be assigned to it.
> And it's my understanding that a pointer assignment like that would be atomic.
> Or is there more going on than that, making it so that the assignment itself
> really isn't atomic?

There so much going on about double-checked locking, it's not even funny. Atomic assignments have the least to do with it. Check this out: http://goo.gl/f0VQG


Andrei
December 17, 2011
Both concurrent execution and a compiler that assumes a single threaded execution model can do really weird things in the name of optimization.

Sent from my iPhone

On Dec 17, 2011, at 3:03 PM, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Saturday, December 17, 2011 09:50:26 Andrei Alexandrescu wrote:
>> On 12/17/11 1:56 AM, Andrew Wiley wrote:
>>> On Sat, Dec 17, 2011 at 1:47 AM, Andrew Wiley<wiley.andrew.j@gmail.com>
> wrote:
>>>> I was looking through Jonathan Davis's pull request to remove static
>>>> constructors from std.datetime, and I realized that I don't know
>>>> whether Double Checked Locking is legal under D's memory model, and
>>>> what the requirements for it to work would be.
>>>> (if you're not familiar with the term, check out
>>>> http://en.wikipedia.org/wiki/Double-checked_locking - it's a useful
>>>> but problematic programming pattern that can cause subtle concurrency
>>>> bugs)
>>>> It seems like it should be legal as long as the variable tested and
>>>> initialized is flagged as shared so that the compiler enforces proper
>>>> fences, but is this actually true?
>>> 
>>> This entry in the FAQ makes me suspicious:
>>> ```
>>> What does shared have to do with memory barriers?
>>> 
>>> Reading/writing shared data emits memory barriers to ensure sequential
>>> consistency (not implemented).
>>> ```
>>> 
>>> So DCL should be alright with data flagged as shared, but it's not implemented in the compiler?
>> 
>> That is correct.
> 
> Well, you learn something new every day I guess. I'd never even heard of double-checked locking before this. I came up with it on my own in an attempt to reduce how much the mutex was used. Is the problem with it that the write isn't actually atomic? Wikipedia makes it sound like the problem might be that the object might be partially initialized but not fully initialized, which I wouldn't have thought possible, since I would have thought that the object would be fully initialized and _then_ the reference would be assigned to it. And it's my understanding that a pointer assignment like that would be atomic. Or is there more going on than that, making it so that the assignment itself really isn't atomic?
> 
> - Jonathan M Davis
December 18, 2011
On Saturday, December 17, 2011 17:10:19 Andrei Alexandrescu wrote:
> On 12/17/11 5:03 PM, Jonathan M Davis wrote:
> > Well, you learn something new every day I guess. I'd never even heard of double-checked locking before this. I came up with it on my own in an attempt to reduce how much the mutex was used. Is the problem with it that the write isn't actually atomic? Wikipedia makes it sound like the problem might be that the object might be partially initialized but not fully initialized, which I wouldn't have thought possible, since I would have thought that the object would be fully initialized and _then_ the reference would be assigned to it. And it's my understanding that a pointer assignment like that would be atomic. Or is there more going on than that, making it so that the assignment itself really isn't atomic?
> 
> There so much going on about double-checked locking, it's not even funny. Atomic assignments have the least to do with it. Check this out: http://goo.gl/f0VQG

Looks interesting. I'll have to give it a read. I really like te subtitle though: "Multithreading is just one damn thing after, before, or simultaneous with another."

In any case, I obviously need to learn more about some of the issues with multi-threading.

- Jonathan M Davis
January 05, 2012
On Sat, 17 Dec 2011 08:47:43 +0100, Andrew Wiley <wiley.andrew.j@gmail.com> wrote:

> I was looking through Jonathan Davis's pull request to remove static
> constructors from std.datetime, and I realized that I don't know
> whether Double Checked Locking is legal under D's memory model, and
> what the requirements for it to work would be.
> (if you're not familiar with the term, check out
> http://en.wikipedia.org/wiki/Double-checked_locking - it's a useful
> but problematic programming pattern that can cause subtle concurrency
> bugs)
> It seems like it should be legal as long as the variable tested and
> initialized is flagged as shared so that the compiler enforces proper
> fences, but is this actually true?

I've written down some idioms I use for this.
https://gist.github.com/1562943

If we could generalize and probably verify them,
they'd make a great addition to the standard library.

martin