Boost logo

Boost :

From: Anthony Williams (anthony_w.geo_at_[hidden])
Date: 2008-04-11 11:34:07


Amit <contact.lipik_at_[hidden]> writes:

> I have a couple of question though. They probably belong on the user list, but
> since we are discussing the library anyway...
>
> a) Is it safe to instantiate thread_specific_ptr as a function level static
> (i.e. are there likely to be race issues just instantiating the object, in case
> the first calls of hte function happens to be concurrent?)?
> I did look through the code this time, it appears to be safe since the call to
> TlsAlloc is wrapped inside call_once - and it seems to work okay. But given the
> nature of these things, and my lack of intimate knowledge of SMP, don't know if
> this is unsound.

thread_specific_ptr is not an aggregate, so use as a function-level static
depends on whether or not the compiler supports thread-safe function-level
statics. gcc has a switch for this. I don't know about ICL. If this is not
safe, the compiler will call the constructor multiple times if multiple
threads call the function simultaneously.

I recommend having thread_specific_ptr instances at namespace scope, or
wrapping them up in a mutex or call_once:

void init_my_tss_ptr(boost::thread_specific_ptr<my_class>** p)
{
    static thread_specific_ptr<my_class> tss;
    *p=&tss;
}

void foo()
{
    static boost::thread_specific_ptr<my_class>* tss;
    static boost::once_flag flag=BOOST_ONCE_INIT;
    boost::call_once(flag,init_my_tss_ptr,&tss);

    // do stuff with the thread_specific_ptr:
    // e.g.
    if(tss->get()) do_stuff();
    // or
    tss->reset(new my_class);
}

> b) Do you think it is worth providing a wrapper around Interlocked* functions?
> e.g., I have created the function below for my use, but if POSIX also provides
> something like the Interlocked* win32 calls, it could be made platform
> independent if boost.thread provided a CompareExchange wrapper.

POSIX doesn't provide atomic ops. However, C++0x will, and I intend to write
an implementation of them for boost using platform- or compiler-specific APIs
(such as InterlockedXXX on Windows, or gcc atomic built-in functions).

> d) And finally, what is the deal with yield? My understanding is that it is not
> required on pre-emptive multitasking systems (i.e. all modern ones?)? If so,
> perhaps the documentation is misleading, since it says:
> "Gives up the remainder of the current thread's time slice, to allow other
> threads to run."

yield() is never /required/, since the OS can pre-empt your thread any time it
chooses. However, you can put a call to yield() in what would otherwise be a
busy-wait loop in order to allow other threads to proceed rather than
consuming CPU time for the current thread looping when there is no progress to
be made.

Anthony

-- 
Anthony Williams            | Just Software Solutions Ltd
Custom Software Development | http://www.justsoftwaresolutions.co.uk
Registered in England, Company Number 5478976.
Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk