public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* G++ and constructors
@ 2007-03-06  2:37 Sean MacLennan
  2007-03-06 12:46 ` John Love-Jensen
  0 siblings, 1 reply; 5+ messages in thread
From: Sean MacLennan @ 2007-03-06  2:37 UTC (permalink / raw)
  To: gcc-help

Hi,

I have been warned that the following can happen under another compiler. 
I don't think it can happen with g++, and frankly I don't think it can 
happen, but I was wondering if anybody could give a definitive answer.


We have a singleton and a method to get the singleton that creates it if 
necessary. Assume lock and unlock just work ;)

static myclass *instance = NULL;

static myclass *myclass::get_instance()
{
	if(instance == NULL) {
		lock();
		if(instance == NULL)
			instance = new myclass();
		unlock();
	}

	return instance;
}

What was argued was that the new can be split it two parts. It can 
allocate the memory, assign this memory to instance, *then* call the 
constructor. So you have a race condition in a multi-threaded system 
where instance is non-null, but has not yet been initialized.

I always thought that the new would not return until *after* the 
constructor had been called. Therefore, no race condition.

I don't need work-arounds, I just need to know if the code ever could be 
split.

Cheers,
    Sean MacLennan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: G++ and constructors
  2007-03-06  2:37 G++ and constructors Sean MacLennan
@ 2007-03-06 12:46 ` John Love-Jensen
  2007-03-06 14:58   ` John Love-Jensen
  2007-03-07 16:40   ` Daniel Lohmann
  0 siblings, 2 replies; 5+ messages in thread
From: John Love-Jensen @ 2007-03-06 12:46 UTC (permalink / raw)
  To: Sean MacLennan, MSX to GCC

Hi Sean,

> I don't need work-arounds, I just need to know if the code ever could be
> split.

Yes.  The code can be split (assuming that "lock()" and "unlock()" are not
performing some thread "critical protection" locking for you).

Although you didn't ask for work-arounds, here's a work-around that works
for GCC, but may not work in C++ in general*.

GCC uses threading protection for static objects.

So this variant of your routine, in GCC, should be thread safe:

----------------------------------------------------------------------
myclass* myclass::init_instance() // private: static
{
  return new myclass();
}

myclass* myclass::get_instance() // public: static
{
  static myclass* instance = InitInstance();
  return instance;
}
----------------------------------------------------------------------

HTH,
--Eljay

* since ISO 14882 C++ punted on the whole threading issue**.

** ... and on a standard C++ ABI, on modules, on... well, lots of stuff for
various reasons***.

*** some good reasons, some bad reasons -- depending on one's point of view.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: G++ and constructors
  2007-03-06 12:46 ` John Love-Jensen
@ 2007-03-06 14:58   ` John Love-Jensen
  2007-03-07 16:40   ` Daniel Lohmann
  1 sibling, 0 replies; 5+ messages in thread
From: John Love-Jensen @ 2007-03-06 14:58 UTC (permalink / raw)
  To: Sean MacLennan, MSX to GCC

Note:

I put in the init_instance() presuming you wanted to do some extra work in
there -- such as whatever lock() and unlock() are doing.

If you don't need to do any extra work, then you can collapse it to the
simpler:

----------------------------------------------------------------------
myclass* myclass::get_instance() // public: static
{
  static myclass* instance = new myclass;
  return instance;
}
----------------------------------------------------------------------

Sorry if I previous more complicated example caused confusion.

--Eljay

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: G++ and constructors
  2007-03-06 12:46 ` John Love-Jensen
  2007-03-06 14:58   ` John Love-Jensen
@ 2007-03-07 16:40   ` Daniel Lohmann
  2007-03-08 17:16     ` Ian Lance Taylor
  1 sibling, 1 reply; 5+ messages in thread
From: Daniel Lohmann @ 2007-03-07 16:40 UTC (permalink / raw)
  To: John Love-Jensen; +Cc: MSX to GCC

John Love-Jensen schrieb:
> [...] 
> Although you didn't ask for work-arounds, here's a work-around that works
> for GCC, but may not work in C++ in general*.
> 
> GCC uses threading protection for static objects.
> 
> So this variant of your routine, in GCC, should be thread safe:
> 
> ----------------------------------------------------------------------
> myclass* myclass::init_instance() // private: static
> {
>   return new myclass();
> }
> 
> myclass* myclass::get_instance() // public: static
> {
>   static myclass* instance = InitInstance();
>   return instance;
> }
> ----------------------------------------------------------------------

*GCC* does the threading protection?

I really wonder how!

How can GCC achieve this on every platform (especially embedded targets 
such as AVR, H8, ARM) without help from the runtime? (I haven't seen any 
dependencies to RTL functions in such case.)

Is this implemented using interruption-transparent algorithms / atomic 
operations or does the above simply hold only for some specific platform?


Daniel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: G++ and constructors
  2007-03-07 16:40   ` Daniel Lohmann
@ 2007-03-08 17:16     ` Ian Lance Taylor
  0 siblings, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2007-03-08 17:16 UTC (permalink / raw)
  To: Daniel Lohmann; +Cc: John Love-Jensen, MSX to GCC

Daniel Lohmann <daniel.lohmann@informatik.uni-erlangen.de> writes:

> John Love-Jensen schrieb:
> > [...] Although you didn't ask for work-arounds, here's a work-around
> > that works
> > for GCC, but may not work in C++ in general*.
> > GCC uses threading protection for static objects.
> > So this variant of your routine, in GCC, should be thread safe:
> > ----------------------------------------------------------------------
> > myclass* myclass::init_instance() // private: static
> > {
> >   return new myclass();
> > }
> > myclass* myclass::get_instance() // public: static
> > {
> >   static myclass* instance = InitInstance();
> >   return instance;
> > }
> > ----------------------------------------------------------------------
> 
> *GCC* does the threading protection?
> 
> I really wonder how!
> 
> How can GCC achieve this on every platform (especially embedded
> targets such as AVR, H8, ARM) without help from the runtime? (I
> haven't seen any dependencies to RTL functions in such case.)
> 
> Is this implemented using interruption-transparent algorithms / atomic
> operations or does the above simply hold only for some specific
> platform?

Processor specific details can be found in libstdc++-v3/config/cpu.
That code is used by the guard code in libstdc++-v3/libsupc++.

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-03-08 17:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-06  2:37 G++ and constructors Sean MacLennan
2007-03-06 12:46 ` John Love-Jensen
2007-03-06 14:58   ` John Love-Jensen
2007-03-07 16:40   ` Daniel Lohmann
2007-03-08 17:16     ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).