[cfe-dev] __thread keyword (was Re: status of 'thread_local')
James Gregurich
bayoubengal at me.com
Thu Oct 18 18:33:23 PDT 2012
Tim,
sorry. I just re-read your message and realized that I confirmed what you already said. I didn't correctly understand what you were telling me on the first pass.
So, I suppose the answer to my original question is that this feature is a work-in-progress and I should stick with boost::thread_specific_ptr for now.
-James
On Oct 18, 2012, at 4:09 PM, James Gregurich <bayoubengal at me.com> wrote:
>
> 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;
> }
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121018/80733d2a/attachment.html>
More information about the cfe-dev
mailing list