home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,393 of 33,346   
   Leigh Johnston to darkknight.21@gmail.com   
   Re: re-ordering across a mutex   
   24 Aug 11 16:39:36   
   
   From: leigh@i42.co.uk   
      
   On 18/08/2011 10:32, darkknight.21@gmail.com wrote:   
   > I have a follow-up question to my question on the double checked   
   > locking problem   
   >   
   > If I use a mutex of some kind like this   
   > 	acquire-mutex   
   > 	execute code/ modify shared variables   
   > 	release-mutex   
   >   
   > For this to work, the compiler is not allowed to move code across the   
   > acquire/release statements.  Does the documentation for a mutex   
   > usually say this?   
   >   
   > Anyway, assuming the above is true, is not a simple solution to the   
   > singleton problem something like this   
   >          if (ptr == 0)  // line1  - inexpensive   
   >          {   
   >              acquire-mutex1   
   >              if (ptr == 0)   
   >              {   
   >                 ptr1 =&singleton;  // whatever   
   >                 acquire_mutex2;   
   >                 ptr = ptr1;   
   >                 release_mutex2;   
   >              }   
   >              release-mutex1   
   >          }   
   >   
   > At line1, if ptr is non-zero, we know for sure that the singleton   
   > object has been fully constructed.  No volatile anywhere.  The mutexes   
   > would also provide the needed memory barriers.   
   >   
   > Would this work?   
      
   No, not on all systems.  CPU read reordering could make non-null ptr   
   visible before the all of the singleton object is visible so you need a   
   barrier with acquire semantics after reading ptr.  My singleton class   
   does the following:   
      
   	template    
   	class singleton   
   	{   
   	public:   
   		static T& instance()   
   		{   
   			T* ret = sInstancePtr;   
   			memory_barrier_acquire_dependant();   
   			if (ret == 0)   
   			{   
   				lock theLock(sLock);   
   				static T sInstance;   
   				memory_barrier_release();   
   				sInstancePtr = &sInstance;   
   				ret = sInstancePtr;   
   			}   
   			return *ret;   
   		}   
   	private:   
   		static lockable sLock;   
   		static T* sInstancePtr;   
   	};   
      
   	template    
   	lockable singleton::sLock;   
   	template    
   	T* singleton::sInstancePtr;   
      
   HTH.   
      
   /Leigh   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca