Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #4376

Re: Please disprove this Double-Checked Locking "fix"

From Pete Becker <pete@versatilecoding.com>
Organization Roundhouse Consulting, Ltd.
Newsgroups comp.lang.c++
Date 2011-04-26 13:50 -0400
Message-ID <2011042613500411162-pete@versatilecodingcom> (permalink)
References <78f3178b-efdc-4af5-8f84-7ff6fa995af7@e25g2000prf.googlegroups.com>
Subject Re: Please disprove this Double-Checked Locking "fix"

Show all headers | View raw


On 2011-04-26 12:58:34 -0400, jl_post@hotmail.com said:

> Hi,
> 
>    Recently I've been reading up on "Double-Checked Locking" in C++
> and how it's often implemented imperfectly.  The Article "C++ and the
> Perils of Double-Checked Locking" by Scott Meyers and Andrei
> Alexandrescu ( http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
> ) provides a good overview of how it's usually done and why it's often
> inadequate.
> 
>    I won't go into details here, but the article states how this code:
> 
> Singleton* Singleton::instance() {
>   if (pInstance == 0) {
>     Lock lock;
>     if (pInstance == 0) {
>       pInstance = new Singleton;
>     }
>   }
>   return pInstance;
> }
> 
> and its variants aren't completely thread safe.
> 

As Leigh said, the issue is not so much compiler optimizations (as 
detailed in the snipped portion of this message) as memory visibility. 
There are systems where writes that occur in one order in the compiled 
code can become visible to other threads in a different order. (read 
the previous sentence several times; it's counterintiutive, but true) 
So even if you can persuade the compiler to generate exactly the code 
that you want, a different thread may see a non-zero value of pinstance 
before it sees the changes made to the thing that the new value of 
pinstance points to. The C++0x solution is:

#include <atomic>
std::atomic<Singleton*> pinstance;

if (pinstance == 0) {
	Lock lock;
	if (pinstance == 0)
		pinstance = new Singleton;
}
return pinstance;

Making pinstance an atomic variable ensures that all writes that 
"happen before" the assignment to pinstance in one thread are seen 
before the result of that assignment is seen in any other thread. In 
essence, it provides a portable wrapper around the memory barrier 
operations in Leigh's suggested solution. (Yes, if you care, his 
solution uses acquire/release semantics, and the solution I've given 
enforces sequential consistency, which is a stronger guarantee; if you 
need to, you can make the atomic variable use acquire/release)

-- 
  Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The 
Standard C++ Library Extensions: a Tutorial and Reference 
(www.petebecker.com/tr1book)

Back to comp.lang.c++ | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Please disprove this Double-Checked Locking "fix" jl_post@hotmail.com - 2011-04-26 09:58 -0700
  Re: Please disprove this Double-Checked Locking "fix" Leigh Johnston <leigh@i42.co.uk> - 2011-04-26 18:17 +0100
  Re: Please disprove this Double-Checked Locking "fix" Pete Becker <pete@versatilecoding.com> - 2011-04-26 13:50 -0400
    Re: Please disprove this Double-Checked Locking "fix" Scott Meyers <NeverRead@aristeia.com> - 2011-05-01 17:14 -0700
      Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-02 15:59 -0700
        Re: Please disprove this Double-Checked Locking "fix" Pete Becker <pete@versatilecoding.com> - 2011-05-03 08:39 -0400
  Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-04-26 11:16 -0700
    Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-04-26 11:19 -0700
    Re: Please disprove this Double-Checked Locking "fix" Pete Becker <pete@versatilecoding.com> - 2011-04-26 14:30 -0400
      Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-04-26 11:50 -0700
    Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-11 19:55 -0700
      Re: Please disprove this Double-Checked Locking "fix" Gerhard Fiedler <gelists@gmail.com> - 2011-05-13 19:56 -0300
        Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-13 16:59 -0700
          Re: Please disprove this Double-Checked Locking "fix" Gerhard Fiedler <gelists@gmail.com> - 2011-05-18 18:12 -0300
            Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-18 14:53 -0700
              Re: Please disprove this Double-Checked Locking "fix" Gerhard Fiedler <gelists@gmail.com> - 2011-05-19 13:46 -0300
                Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-19 15:30 -0700
                Re: Please disprove this Double-Checked Locking "fix" Gerhard Fiedler <gelists@gmail.com> - 2011-05-21 11:55 -0300
                Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-22 01:08 -0700
  Re: Please disprove this Double-Checked Locking "fix" James Kanze <james.kanze@gmail.com> - 2011-04-30 15:54 -0700
    Re: Please disprove this Double-Checked Locking "fix" Leigh Johnston <leigh@i42.co.uk> - 2011-05-01 21:49 +0100
      Re: Please disprove this Double-Checked Locking "fix" Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2011-05-01 17:26 -0400
        Re: Please disprove this Double-Checked Locking "fix" Leigh Johnston <leigh@i42.co.uk> - 2011-05-01 22:44 +0100
          Re: Please disprove this Double-Checked Locking "fix" Leigh Johnston <leigh@i42.co.uk> - 2011-05-02 01:01 +0100
            Re: Please disprove this Double-Checked Locking "fix" Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2011-05-01 22:04 -0400
            Re: Please disprove this Double-Checked Locking "fix" "Chris M. Thomasson" <cristom@charter.net> - 2011-05-04 11:49 -0700
              Re: Please disprove this Double-Checked Locking "fix" Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2011-05-06 00:16 -0400
          Re: Please disprove this Double-Checked Locking "fix" Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-02 15:43 -0700
        Re: Please disprove this Double-Checked Locking "fix" James Kanze <james.kanze@gmail.com> - 2011-05-01 14:53 -0700
          Re: Please disprove this Double-Checked Locking "fix" Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2011-05-01 19:23 -0400
            Re: Please disprove this Double-Checked Locking "fix" James Kanze <james.kanze@gmail.com> - 2011-05-02 09:02 -0700
              Re: Please disprove this Double-Checked Locking "fix" Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2011-05-05 23:46 -0400
      Re: Please disprove this Double-Checked Locking "fix" James Kanze <james.kanze@gmail.com> - 2011-05-01 14:47 -0700

csiph-web