Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Static allocation in a static function & thread safety (http://www.velocityreviews.com/forums/t532066-static-allocation-in-a-static-function-and-thread-safety.html)

paolo.brandoli@gmail.com 08-23-2007 08:35 PM

Static allocation in a static function & thread safety
 
Hello all,

Suppose that I have the following class "a" that returns a pointer to
a single instance of itself.

class a
{
public:
static a* getSingleInstance()
{
static a;
return &a;
}
};

The code is not thread safe, because several thread could call
getSingleInstance at the same time and the construction of a is not
guaranteed to be thread safe.

But if I add the following class "b", which call
a::getSingleInstance() in its constructor:

class b
{
public:
b()
{
a::getSingleInstance();
}
}

....and I add a static instance of b in some cpp file, like this:
static b;

this would still create the class "a" in the desidered order in case
it is needed by other static objects, but it would also create it in
case no other code require it. This would create the class before
main() starts and has the possibility to spawn other threads.

a::getSingleInstance() should be thread-safe from the second time it
is called, because the flag that controls the creation of the single
instance "a" doesn't need to be modified. I'm I right?

Would this make a::getSingleInstance() thread safe (supposing that
other static objects don't create any thread during their
construction)?

Any idea that would improve this?

Thanks in advance,
Paolo


Gianni Mariani 08-23-2007 08:52 PM

Re: Static allocation in a static function & thread safety
 
paolo.brandoli@gmail.com wrote:
> Hello all,
>
> Suppose that I have the following class "a" that returns a pointer to
> a single instance of itself.
>
> class a
> {
> public:
> static a* getSingleInstance()
> {
> static a;
> return &a;
> }
> };
>
> The code is not thread safe, because several thread could call
> getSingleInstance at the same time and the construction of a is not
> guaranteed to be thread safe.


The current C++ standard says nothing about threads. However, threads
are very topical in the next revision of the standard so let's go with
that ...

Local static object creation is thread safe with GCC and in my opinion
is the only way to read the standard. (note that this GCC feature is
broken on solaris.) The standard requires that the "a" object above is
created exactly once, any compiler that says it supports threads must
enforce the standard and so must make static object creation thread safe.

>
> But if I add the following class "b", which call
> a::getSingleInstance() in its constructor:
>
> class b
> {
> public:
> b()
> {
> a::getSingleInstance();
> }
> }
>
> ...and I add a static instance of b in some cpp file, like this:
> static b;
>
> this would still create the class "a" in the desidered order in case
> it is needed by other static objects, but it would also create it in
> case no other code require it. This would create the class before
> main() starts and has the possibility to spawn other threads.


Starting multiple threads before main() is bad mojo precisely because
you can't be sure when all static objects are initialized.

>
> a::getSingleInstance() should be thread-safe from the second time it
> is called, because the flag that controls the creation of the single
> instance "a" doesn't need to be modified. I'm I right?
>
> Would this make a::getSingleInstance() thread safe (supposing that
> other static objects don't create any thread during their
> construction)?
>
> Any idea that would improve this?


Use GCC ? File bugs with your compiler supplier ?

Victor Bazarov 08-23-2007 08:53 PM

Re: Static allocation in a static function & thread safety
 
paolo.brandoli@gmail.com wrote:
> [.. attempt to solve the problem of static initialisation in

a multithreaded program ..]
> this would still create the class "a" in the desidered order in case
> it is needed by other static objects, but it would also create it in
> case no other code require it. This would create the class before
> main() starts and has the possibility to spawn other threads.


Why do you limit the possibility to "spawm other threads" to _after_
'main' has started?

> [..]


BTW, initialisation of local static objects has been discussed not
once already, perhaps you should begin by reading the archives about
it so you don't repeat others' mistakes?... Just a thought.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask



arun.darra@gmail.com 08-23-2007 09:04 PM

Re: Static allocation in a static function & thread safety
 
On Aug 24, 1:35 am, paolo.brand...@gmail.com wrote:
> Hello all,
>
> Suppose that I have the following class "a" that returns a pointer to
> a single instance of itself.
>
> class a
> {
> public:
> static a* getSingleInstance()
> {
> static a;
> return &a;
> }
>
> };
>
> The code is not thread safe, because several thread could call
> getSingleInstance at the same time and the construction of a is not
> guaranteed to be thread safe.
>
> But if I add the following class "b", which call
> a::getSingleInstance() in its constructor:
>
> class b
> {
> public:
> b()
> {
> a::getSingleInstance();
> }
>
> }
>
> ...and I add a static instance of b in some cpp file, like this:
> static b;
>
> this would still create the class "a" in the desidered order in case
> it is needed by other static objects, but it would also create it in
> case no other code require it. This would create the class before
> main() starts and has the possibility to spawn other threads.
>
> a::getSingleInstance() should be thread-safe from the second time it
> is called, because the flag that controls the creation of the single
> instance "a" doesn't need to be modified. I'm I right?
>
> Would this make a::getSingleInstance() thread safe (supposing that
> other static objects don't create any thread during their
> construction)?
>
> Any idea that would improve this?
>
> Thanks in advance,
> Paolo



If you want to add thread safty to a static getInstance method which
is responsible for creating a single instance of the class, you can
alter it as mentiong below and use the "double-checked locking"
mechanish.

class a
{
private:
static a *p;
public:
static a* getInstance()
{
if(p == NULL)
{
pthread_mutex_lock(&mutex);
if(p == NULL)
{
p = new a;
}
pthread_mutex_unlock(&mutex);
}
return p;
}
}
};

This will help u create a thread safe static getInstance method,
this technique is generally used for making the singleton pattern
thread safe.


Chris Thomasson 08-23-2007 09:36 PM

Re: Static allocation in a static function & thread safety
 
<arun.darra@gmail.com> wrote in message
news:1187903092.787590.149840@q3g2000prf.googlegro ups.com...
> On Aug 24, 1:35 am, paolo.brand...@gmail.com wrote:
>> Hello all,
>>
>> Suppose that I have the following class "a" that returns a pointer to
>> a single instance of itself.

[...]
>> Would this make a::getSingleInstance() thread safe (supposing that
>> other static objects don't create any thread during their
>> construction)?
>>
>> Any idea that would improve this?

[...]
> If you want to add thread safty to a static getInstance method which
> is responsible for creating a single instance of the class, you can
> alter it as mentiong below and use the "double-checked locking"
> mechanish.

[...]
> This will help u create a thread safe static getInstance method,
> this technique is generally used for making the singleton pattern
> thread safe.


Your example is simply infested with race-conditions! You have absolutely no
method in your code that addresses compiler and hardware reordering. For the
hardware reordering, you need a data-dependant load memory barrier after the
initial load, and a release memory barrier before the final store. For the
compiler reordering you need to read your documentation. I would advise that
you use assembly language to accomplish this task. Here is some more
detailed notes:

http://groups.google.com/group/comp....b69ac2f850f453



Chris Thomasson 08-23-2007 09:48 PM

Re: Static allocation in a static function & thread safety
 
Here is some basic dcl pseudo-code that MUST be executed in the precise
given order:


1: static T *g_ptr = 0; // set before thread creation


T* instance() {

2: T* l_ptr = atomic_loadptr(&g_ptr);
3: membar #LoadLoad; // needed for alpha cpu's
4: if (! l_ptr) {
5: lock();
6: l_ptr = g_ptr;
7: if (! l_ptr) {
8: l_ptr = new T;
9: membar #LoadStore | #StoreStore;
10: atomic_storeptr(&g_ptr, l_ptr);
}
11: unlock();
}
12: return l_ptr;

}


http://groups.google.com/group/comp....ea516c5581240e
(read the entire thread...)





All times are GMT. The time now is 01:11 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.