Need second opions from some threading / object creation experts...

Folks, I'm looking at the code for singleton_pool, and I can't *quite* convince myself that it's completely thread safe and guaranteed to do what it says, the code in question is in boost/pool/detail/singleton.hpp which is a deceptively clever/simple singleton implementation. I haven't been able to break it in practice, but would a sufficiently clever compiler be able to optimize away the call create_object.do_nothing(); and therefore not instantiate the object prior to main()? Thanks in advance, John.

On 15/05/11 04:52, John Maddock wrote:
Folks,
I'm looking at the code for singleton_pool, and I can't *quite* convince myself that it's completely thread safe and guaranteed to do what it says, the code in question is in boost/pool/detail/singleton.hpp which is a deceptively clever/simple singleton implementation. I haven't been able to break it in practice, but would a sufficiently clever compiler be able to optimize away the call create_object.do_nothing(); and therefore not instantiate the object prior to main()?
No cause it's static and hence compiler wont remove it. I think it is suffisent, but I would worry of *other* static object in different TU calling singleton instance as the order of static initializer is random. Thread safe singleton are huge beasts to get right, see http://stackoverflow.com/questions/6915/thread-safe-lazy-contruction-of-a-si... I think our best bet is having some atomic compare&swap in the singleton construction to be sure it is done properly.

I'm looking at the code for singleton_pool, and I can't *quite* convince myself that it's completely thread safe and guaranteed to do what it says, the code in question is in boost/pool/detail/singleton.hpp which is a deceptively clever/simple singleton implementation. I haven't been able to break it in practice, but would a sufficiently clever compiler be able to optimize away the call create_object.do_nothing(); and therefore not instantiate the object prior to main()?
No cause it's static and hence compiler wont remove it. I think it is suffisent, but I would worry of *other* static object in different TU calling singleton instance as the order of static initializer is random.
Thread safe singleton are huge beasts to get right, see http://stackoverflow.com/questions/6915/thread-safe-lazy-contruction-of-a-si...
Sigh... yes that's why we *still* don't have a singleton in Boost.
I think our best bet is having some atomic compare&swap in the singleton construction to be sure it is done properly.
That was what I was hinting at - I had assumed that use of Boost.Thread's call_once was the only way to do this right, and then I saw the code and wasn't so sure. The thing I'm concerned about is this: * The code currently relies on a call to a function in a static object to force that object to be instantiated and initialize the singleton, but: * Once compiler optimizations are turned on, that function call will be optimized away to a no-op. * There's now no code that's using the global object. * A clever linker says "hey we don't need this anymore" and removes it from the program image, so: * The singleton no longer gets initialized before main starts (only when it's first called). Of course this optimization changes program behavior so it ought to be forbidden... but you know I'm paranoid ;-) Cheers, John.

Sigh... yes that's why we *still* don't have a singleton in Boost.
And somehow, I like we dont have any public singleton class. I know what happens when you give singleton to people: they use it everywhere ;)
That was what I was hinting at - I had assumed that use of Boost.Thread's call_once was the only way to do this right, and then I saw the code and wasn't so sure.
The thing I'm concerned about is this:
* The code currently relies on a call to a function in a static object to force that object to be instantiated and initialize the singleton, but: * Once compiler optimizations are turned on, that function call will be optimized away to a no-op. * There's now no code that's using the global object. * A clever linker says "hey we don't need this anymore" and removes it from the program image, so: * The singleton no longer gets initialized before main starts (only when it's first called).
Of course this optimization changes program behavior so it ought to be forbidden... but you know I'm paranoid ;-)
Being paranoid here is actually the sane thing. I think having a pointer based singleton with compare-and-swap initailisation is probably better. IIRC there is such a beast in Modern C++ design and Loki but I dunno how OK it is.

John Maddock wrote:
I'm looking at the code for singleton_pool, and I can't *quite* convince myself that it's completely thread safe and guaranteed to do what it says, the code in question is in boost/pool/detail/singleton.hpp which is a deceptively clever/simple singleton implementation. I haven't been able to break it in practice, but would a sufficiently clever compiler be able to optimize away the call create_object.do_nothing(); and therefore not instantiate the object prior to main()?
No cause it's static and hence compiler wont remove it. I think it is suffisent, but I would worry of *other* static object in different TU calling singleton instance as the order of static initializer is random. Thread safe singleton are huge beasts to get right, see http://stackoverflow.com/questions/6915/thread-safe-lazy-contruction-of-a-si...
Sigh... yes that's why we *still* don't have a singleton in Boost.
I think our best bet is having some atomic compare&swap in the singleton construction to be sure it is done properly.
That was what I was hinting at - I had assumed that use of Boost.Thread's call_once was the only way to do this right, and then I saw the code and wasn't so sure.
The thing I'm concerned about is this:
* The code currently relies on a call to a function in a static object to force that object to be instantiated and initialize the singleton, but: * Once compiler optimizations are turned on, that function call will be optimized away to a no-op. * There's now no code that's using the global object. * A clever linker says "hey we don't need this anymore" and removes it from the program image, so: * The singleton no longer gets initialized before main starts (only when it's first called).
Of course this optimization changes program behavior so it ought to be forbidden... but you know I'm paranoid ;-)
Cheers, John.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

John Maddock wrote:
The thing I'm concerned about is this:
* The code currently relies on a call to a function in a static object to force that object to be instantiated and initialize the singleton, but: * Once compiler optimizations are turned on, that function call will be optimized away to a no-op. * There's now no code that's using the global object. * A clever linker says "hey we don't need this anymore" and removes it from the program image, so: * The singleton no longer gets initialized before main starts (only when it's first called).
There MIGHT be a way to fix this by snookering the linker into not stripping code that is explicitly called. I've dealt with this on a regular basis in the serialization library by forcing the export of certain functions/instances so that the linker presumes that the might be called from outside the executable. I get regular complaints that "my executable is exporting entry points" but I haven't found any other way to deal with it.
Of course this optimization changes program behavior so it ought to be forbidden... but you know I'm paranoid ;-)
Well, just because you're paranoid doesn't mean that there isn't anyone out to get you. Robert Ramey
participants (3)
-
Joel falcou
-
John Maddock
-
Robert Ramey