Double-Checked Locking pattern issue

G

George2

Hello gurus,


For the wellknown Double-Checked Locking pattern,

http://www.ddj.com/184405726?pgno=1

Step 1: Allocate memory to hold a Singleton object.
Step 2: Construct a Singleton object in the allocated memory.
Step 3: Make pInstance point to the allocated memory.

After reading for a couple of times, I still do not understand why
some compiler will exchange step 2 and step 3 code? If there are any
exception in step 2, the swap code will make pInstance point to an
invalid memory address. Any ideas why compiler do the swap?

Code:
Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock;
if (pInstance == 0) {
pInstance = // Step 3
operator new(sizeof(Singleton)); // Step 1
new (pInstance) Singleton; // Step 2
}
}
return pInstance;
}


thanks in advance,
George
 
J

Joe Seigh

George2 said:
Hello gurus,


For the wellknown Double-Checked Locking pattern,

http://www.ddj.com/184405726?pgno=1

Step 1: Allocate memory to hold a Singleton object.
Step 2: Construct a Singleton object in the allocated memory.
Step 3: Make pInstance point to the allocated memory.

After reading for a couple of times, I still do not understand why
some compiler will exchange step 2 and step 3 code? If there are any
exception in step 2, the swap code will make pInstance point to an
invalid memory address. Any ideas why compiler do the swap?
[...]

The compiler is allowed reorder code as long as it's not detectable in
a single threaded program. The behavior of the code in a multi-threaded
program is undefined.
 
J

James Kanze

For the wellknown Double-Checked Locking pattern,

Step 1: Allocate memory to hold a Singleton object.
Step 2: Construct a Singleton object in the allocated memory.
Step 3: Make pInstance point to the allocated memory.
After reading for a couple of times, I still do not understand why
some compiler will exchange step 2 and step 3 code? If there are any
exception in step 2, the swap code will make pInstance point to an
invalid memory address. Any ideas why compiler do the swap?

Optimization. And it's not just compilers; the hardware may
change the order of writes (and reads!) as well, unless special
hardware instructions are inserted to tell it not to do so.

Thus, for example, some of the writes in the constructor may not
propagate out to be visible to other threads before the write to
the pointer has propagated out. Or another thread might in fact
read the non-zero value in the pointer, but then use a stale
copy of the memory of the actual object, which doesn't reflect
the values of the writes in the constructor.

It's possible to write an implementation of double checked
locking which works, provided the compiler provides the
possibility of inline assembler (to allow you to insert the
necessary additional instructions), and that it won't move code
accross the inline assembler. Of course, once you use inline
assembler, all portability goes out the window.

FWIW: even when portability isn't a concern, I've yet to find a
case where double checked locking would be an appropriate
solution anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top