Often when looking in the internet for implementations of some patterns in C++ we come across the well-known Meyers singleton, which is basically the next code:
class Singleton{
Singleton(){
// Thread-unsafe code
}
static Singleton* getInstance(){
static Singleton instance;
return &instance;
}
};
This essentially reserves static memory for the size of the instance and executes the class constructor during the first call to getInstance(), this of course occurs only if we are dealing with a non-POD object.
The problem here is that we might run in problems if we get inside getInstance with 2 threads at the same time for the first time. Obviously the constructor is not thread-safe per se.
However, GCCs g++ gives us a help here and protects every local static variable construction with thread-safe guards, __cxa_guard_acquire and __cxa_guard_release do the job here protecting the constructor. Note that this only happens with local statics as global static construction occurs before any function of the translation unit gets executed.
Differences are obvious if we take a look at the generated code, PODs are just data so no construction is needed, non-PODs are properly protected
POD type, function body highlighted:
class pod_class { public:
static pod_class* instance(){
static pod_class once;
return &once;
}};
int main(){ return (int)pod_class::instance; }
080483fd <_ZN9pod_class8instanceEv>:
80483fd: 55 push %ebp
80483fe: 89 e5 mov %esp,%ebp
8048400: b8 f8 95 04 08 mov $0x80495f8,%eax
8048405: 5d pop %ebp
8048406: c3 ret
Non-POD type, class constructor and function body higlighted:
Read the rest of this entry »