GlowingHack
-
Posts
1 -
Joined
-
Last visited
Never -
Donations
0.00 GBP
We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use
Maybe a bug , I'm not pretty sure ...
in OldBug reports
Posted
Sorry for my poor English , I am not the native English speaker.
I start using Mangos for only one day , and I also try to read some of the source files. I do not know my source code version is the newest,
my version is mangos-0.9.0 , if this bug has been fixed in the later version , just skip this topic .
I just read the file SingletonImp.h , and I found the coder using the double-lock routine for implementing the lazy instance.
However , this mechanism does not work on the SMAP cpu , which means on many multi-core , there exist potential hazard
while on the initialization .
The reason can be obtained by google the key word : Memory Barrier .
Here I just give the revision version , which I does not prove it is right , just tips.
// a memory barrier wraper
// this memory barrier indeed will lock the bus and notify all the core to flush their own cache
// in order to get the same and accurate value
// calling this function will make all the store-and-load operation before such calling strictly be finished.
static void MemoryBarrier() {
#if defined (__MSV_VER)
::MemoryBarrier();
#elif defined (__GNUG__)
__volatile __asm (""::: " memory " );
#endif
}
template
<
typename T,
class ThreadingModel,
class CreatePolicy,
class LifeTimePolicy
>
T&
MaNGOS::Singleton<T, ThreadingModel, CreatePolicy, LifeTimePolicy >::Instance()
{
//add
T& value = si_instance;
MemoryBarrier();
// here the value has been notified
if( !value )
{
// double-checked Locking pattern
Guard();
// since reach here , there exist no other thread gonna get in
// so it is safe to use the si_instance itself
if( !si_instance )
{
if( si_destroyed )
{
LifeTimePolicy::OnDeadReference();
si_destroyed = false;
}
si_instance = CreatePolicy::Create();
// we should make sure the value (address) has indeed been written into that pointer (si_instance)
// so flush this value
MemoryBarrier();
LifeTimePolicy::ScheduleCall(&DestroySingleton);
}
}
return *si_instance;
}
Since I havn't read the code about the time schedual of every singleton instance , maybe using the atexit function ,
so the si_destroy variable I do not revise it. Anyway , if there do need the revision , it is pretty easy .
Another thing is : using the key word "volatile" before the variable si_instance and si_destroy , since those two variables can
be accessed by two different threads or more , therefore it is safe to do this (however, this does not mean it is absolutely safe ) and this will
force compiler to generate better thread safe machine code.