One more question about block-scoped static objects:
>From compiled assembly I have learned that GCC uses a 64-bit integer guard to
>ensure once-initialization of static objects with block scopes.
Code in gcc/libstdc++-v3/libsupc++/guard.cc uses a global mutex to protect
multiple threads from racing, which, as described in that file, could
potentially cause a deadlock that can be avoided if a condition variable is
used.
This, however, is unnecessary with mcfgthread. The mcfgthread library uses the
once_flag itself as both the mutex and condition variable, eliminating the need
of a global mutex and condition variable.
Code using mcfgthread might look like this:
[code]
class foo { ... };
static ::_MCFCRT_OnceFlag flag;
static alignas(foo) char obj[sizeof(foo)];
foo *get_obj(){
const auto construct_obj = []{ ::new(static_cast<void *>(obj)) foo(); };
const auto destruct_obj = []{ reinterpret_cast<foo *>(obj)->~foo(); };
// Lock the once flag as if it were a mutex.
const auto result = ::_MCFCRT_WaitForOnceFlagForever(&flag);
// This never times out, so result can be either _MCFCRT_kOnceResultInitial
or _MCFCRT_kOnceResultFinished.
if(result == ::_MCFCRT_kOnceResultInitial){
try {
// Construct the object in-place.
construct_obj();
if(std::atexit(&destruct_obj) != 0){
// Assume we have run out of memory.
destruct_obj();
throw std::bad_alloc();
}
} catch(...){
// Unlock the once flag, allowing other threads to retry the
initialization.
// This works like pthread_cond_signal().
::_MCFCRT_SignalOnceFlagAsAborted(&flag);
throw;
}
// We are done here. Unlock the once flag and other threads will not be
blocked any more.
// This works like pthread_cond_broadcast().
_MCFCRT_SignalOnceFlagAsFinished(&flag);
}
return reinterpret_cast<foo *>(obj);
}
[/code]
Now here is my question:
That '__cxxabiv1::__guard' thing seems built-in of GCC. Does it have anything
to do with code generation? And where is it involved?
------------------
Best regards,
lh_mouse
2016-04-20