
Amit <contact.lipik@gmail.com> 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