Jump to content

Maybe a bug , I'm not pretty sure ...


GlowingHack

Recommended Posts

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.

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

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