[cfe-dev] __thread keyword (was Re: status of 'thread_local')
James Gregurich
bayoubengal at me.com
Thu Oct 18 16:09:46 PDT 2012
On Oct 16, 2012, at 2:29 PM, James Gregurich <bayoubengal at me.com> wrote:
> ok. I'll test it and see.
>
>
> On Oct 16, 2012, at 2:26 PM, Tim Northover <t.p.northover at gmail.com> wrote:
>
>>> What is the lifetime on a __thread variable? It gets destructed at the time
>>> the thread exits?
>>
>> Pretty much. From C++11 (3.7.2):
>>
>> "All variables declared with the thread_local keyword have thread
>> storage duration. The storage for these
>> entities shall last for the duration of the thread in which they are
>> created. There is a distinct object or
>> reference per thread, and use of the declared name refers to the
>> entity associated with the current thread."
>>
>> "A variable with thread storage duration shall be initialized before
>> its first odr-use (3.2) and, if constructed,
>> shall be destroyed on thread exit."
>>
>> I wouldn't swear to LLVM implementing these semantics yet though. The
>> initial TLS specification forbade non-trivial constructors and had no
>> mention of destructors. In fact, from a quick test it looks like LLVM
>> destroys the object at program exit, and only in one thread (unless
>> __cxa_atexit and to a lesser extent .init_array are more magical than
>> I knew).
>>
>> Tim.
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
ok. I ran the test with '__thread'. I did not get the expected results.
When I ran the code below, I got one instance of 'a' created on thread 2 which was later released on the main thread by cxa_exit().
If I moved 'x' to be a global variable (file scope), I still got one instance constructed by cxx_global_var_init() before main was invoked.
I verified that I am getting multiple worker threads during the running of this app. So, I would expect each worker thread to get a copy of 'x'.
Is my expectation wrong? Is this feature not fully implemented or is there some option that needs to be enabled?
I tested building against the 10.7 & 10.8 SDKs. Xcode 4.5.1 with clang & libc++ in c++11 mode.
#include <thread>
#include <mutex>
#include <memory>
#include <sstream>
#include <iostream>
#include <vector>
#include <Foundation/Foundation.h>
#include <dispatch/dispatch.h>
class a
{
public:
a(size_t theLoopId) : mLoopId(theLoopId)
{
std::thread::id tmpCurrentThreadId = std::this_thread::get_id();
std::hash<std::thread::id> tmpThreadHasher;
mThreadId = tmpThreadHasher(tmpCurrentThreadId);
NSLog(@"construct. thread=%zX, loop=%zX", mThreadId, mLoopId);
}
~a()
{
NSLog(@"destruct. thread=%zX, loop=%zX", mThreadId, mLoopId);
}
size_t mThreadId;
size_t mLoopId;
size_t counter;
};
template <typename tpType>
struct drop_pointer
{
};
template <typename tpType>
struct drop_pointer<tpType*>
{
typedef tpType type;
};
struct deleteDispatchgroup
{
void operator()(dispatch_group_t thePtr)
{
//not needed if ARC is enabled on 10.8+
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 1080 || !__has_feature(objc_arc)
dispatch_release(thePtr);
#endif
};
};
//__thread a x(-1);
int main(int argc, const char * argv[])
{
dispatch_queue_t tmpDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
std::unique_ptr< drop_pointer<dispatch_group_t>::type, deleteDispatchgroup > tmpDipatchGroupSPtr( dispatch_group_create() );
size_t tmpCounter = 0;
for(size_t i = 1; i <= 50; ++i)
{
auto tmpHandler = [&tmpCounter, i](void) // (size_t theId)
{
static __thread a x(i);
for(size_t j= 0; j < 10000000; ++j)
{
tmpCounter += j * i;
x.counter += j * i;
}
};
dispatch_group_async(tmpDipatchGroupSPtr.get(), tmpDispatchQueue, tmpHandler);
}
dispatch_group_wait(tmpDipatchGroupSPtr.get(), DISPATCH_TIME_FOREVER);
// insert code here...
std::cout << "Hello, World!\n";
return tmpCounter;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121018/c253f344/attachment.html>
More information about the cfe-dev
mailing list