|
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