This problem may looks strange. I want to do that because we have some code need to be built on several platforms, but some platform doesn't support thread_local, then use boost::thread_specific_ptr instead. however, it's unpleasing to build boost binary for every platform (x86/x64/arm, debug/release, os, too many).
I wonder if it's possible to imp thread_specific_ptr via thread_local so that we can keep client code more elegant(avoid #ifdef)
I want to have a header file like:
#if HAS_THREAD_LOCAL
class thread_specific_ptr
{
... // use thread_local to implement
};
#else
using boost::thread_specific_ptr
#endif
I can't find the way, maybe you can, thanks.
It is possible to implement thread_specific_ptr
using thread_local
. The important part one has to remember is that thread_local
is a storage specifier and thread_specific_ptr
is an object. As such it's technically possible to dynamically create and destroy thread_specific_ptr
objects while you cannot do that with thread_local
objects. For instance, you cannot put a thread_local
object as a member of your class.
However, thread_local
can be used internally by thread_specific_ptr
to select an internal structure based on the current thread. That structure can contain data for all thread_specific_ptr
s in the program, and allow dynamic creation and deletion of its elements. One could use a std::map
for this purpose, for example.
thread_local std::map< void*, std::shared_ptr< void > > thread_specific_ptr_data;
template< typename T >
class thread_specific_ptr
{
public:
T* get() const
{
auto it = thread_specific_ptr_data.find(this);
if (it != thread_specific_ptr_data.end())
return static_cast< T* >(it->second.get());
return nullptr;
}
};
That, of course, adds some overhead compared to the raw use of thread_local
, and it can actually be a bit slower than boost::thread_specific_ptr
on some platforms because boost::thread_specific_ptr
uses lower-level interfaces than thread_local
. You would also have to solve the problems boost::thread_specific_ptr
is facing, like what key to use to look for the value in the map. But this approach can be useful if your goal is to remove the dependency.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With