<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 16, 2012, at 2:29 PM, James Gregurich <<a href="mailto:bayoubengal@me.com">bayoubengal@me.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">ok. I'll test it and see.<br><br><br>On Oct 16, 2012, at 2:26 PM, Tim Northover <<a href="mailto:t.p.northover@gmail.com">t.p.northover@gmail.com</a>> wrote:<br><br><blockquote type="cite"><blockquote type="cite">What is the lifetime on a __thread variable? It gets destructed at the time<br>the thread exits?<br></blockquote><br>Pretty much. From C++11 (3.7.2):<br><br>"All variables declared with the thread_local keyword have thread<br>storage duration. The storage for these<br>entities shall last for the duration of the thread in which they are<br>created. There is a distinct object or<br>reference per thread, and use of the declared name refers to the<br>entity associated with the current thread."<br><br>"A variable with thread storage duration shall be initialized before<br>its first odr-use (3.2) and, if constructed,<br>shall be destroyed on thread exit."<br><br>I wouldn't swear to LLVM implementing these semantics yet though. The<br>initial TLS specification forbade non-trivial constructors and had no<br>mention of destructors. In fact, from a quick test it looks like LLVM<br>destroys the object at program exit, and only in one thread (unless<br>__cxa_atexit and to a lesser extent .init_array are more magical than<br>I knew).<br><br>Tim.<br></blockquote><br>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev<br></blockquote></div><br><div><br></div><div><br></div><div>ok. I ran the test with '__thread'. I did not get the expected results.</div><div><br></div><div>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().</div><div><br></div><div>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.</div><div><br></div><div>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'. </div><div><br></div><div><br></div><div>Is my expectation wrong? Is this feature not fully implemented or is there some option that needs to be enabled?</div><div><br></div><div><br></div><div><div>I tested building against the 10.7 & 10.8 SDKs. Xcode 4.5.1 with clang & libc++ in c++11 mode.</div><div><br></div><div><br></div></div><div><br></div><div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); ">#include <span style="color: #d12f1b"><thread></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); ">#include <span style="color: #d12f1b"><mutex></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); ">#include <span style="color: #d12f1b"><memory></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); ">#include <span style="color: #d12f1b"><sstream></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="color: #78492a">#include </span><iostream></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); ">#include <span style="color: #d12f1b"><vector></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="color: #78492a">#include </span><Foundation/Foundation.h></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="color: #78492a">#include </span><dispatch/dispatch.h></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(187, 44, 162); ">class<span style="color: #000000"> a</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">{</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(187, 44, 162); ">public<span style="color: #000000">:</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> a(<span style="color: #703daa">size_t</span> theLoopId) : <span style="color: #4f8187">mLoopId</span>(theLoopId)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">std</span>::<span style="color: #703daa">thread</span>::<span style="color: #bb2ca2">id</span> tmpCurrentThreadId = <span style="color: #703daa">std</span>::<span style="color: #703daa">this_thread</span>::<span style="color: #3d1d81">get_id</span>();</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">std</span>::<span style="color: #703daa">hash</span><<span style="color: #703daa">std</span>::<span style="color: #703daa">thread</span>::<span style="color: #bb2ca2">id</span>> tmpThreadHasher;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #4f8187">mThreadId</span> = tmpThreadHasher(<span style="color: #3d1d81">tmpCurrentThreadId</span>);</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="color: #000000"> </span><span style="color: #3d1d81">NSLog</span><span style="color: #000000">(</span>@"construct. thread=%zX, loop=%zX"<span style="color: #000000">, </span><span style="color: #4f8187">mThreadId</span><span style="color: #000000">, </span><span style="color: #4f8187">mLoopId</span><span style="color: #000000">);</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> }</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> ~a()</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="color: #000000"> </span><span style="color: #3d1d81">NSLog</span><span style="color: #000000">(</span>@"destruct. thread=%zX, loop=%zX"<span style="color: #000000">, </span><span style="color: #4f8187">mThreadId</span><span style="color: #000000">, </span><span style="color: #4f8187">mLoopId</span><span style="color: #000000">);</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> }</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">size_t</span> mThreadId;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">size_t</span> mLoopId;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">size_t</span> counter;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">};</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(187, 44, 162); ">template<span style="color: #000000"> <</span>typename<span style="color: #000000"> tpType></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: #bb2ca2">struct</span> drop_pointer</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">{</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">};</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(187, 44, 162); ">template<span style="color: #000000"> <</span>typename<span style="color: #000000"> tpType></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: #bb2ca2">struct</span> drop_pointer<tpType*></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">{</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">typedef</span> tpType type;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">};</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: #bb2ca2">struct</span> deleteDispatchgroup</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">{</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">void</span> <span style="color: #bb2ca2">operator</span>()(<span style="color: #703daa">dispatch_group_t</span> thePtr)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0); "><span style="color: #000000"> </span>//not needed if ARC is enabled on 10.8+</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); "> #if __MAC_OS_X_VERSION_MAX_ALLOWED < <span style="color: #272ad8">1080</span> || !__has_feature(objc_arc)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #3d1d81">dispatch_release</span>(thePtr);</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); "> #endif</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> };</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">};</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0); ">//__thread a x(-1);</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: #bb2ca2">int</span> main(<span style="color: #bb2ca2">int</span> argc, <span style="color: #bb2ca2">const</span> <span style="color: #bb2ca2">char</span> * argv[])</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">{</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(120, 73, 42); "><span style="color: #000000"> </span><span style="color: #703daa">dispatch_queue_t</span><span style="color: #000000"> tmpDispatchQueue = </span><span style="color: #3d1d81">dispatch_get_global_queue</span><span style="color: #000000">(</span>DISPATCH_QUEUE_PRIORITY_DEFAULT<span style="color: #000000">, </span><span style="color: #272ad8">0</span><span style="color: #000000">);</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">std</span>::<span style="color: #703daa">unique_ptr</span>< <span style="color: #4f8187">drop_pointer</span><<span style="color: #703daa">dispatch_group_t</span>>::<span style="color: #4f8187">type</span>, <span style="color: #4f8187">deleteDispatchgroup</span> > tmpDipatchGroupSPtr( <span style="color: #3d1d81">dispatch_group_create</span>() );</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #703daa">size_t</span> tmpCounter = <span style="color: #272ad8">0</span>;</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">for</span>(<span style="color: #703daa">size_t</span> i = <span style="color: #272ad8">1</span>; i <= <span style="color: #272ad8">50</span>; ++i)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">auto</span> tmpHandler = [&tmpCounter, i](<span style="color: #bb2ca2">void</span>) <span style="color: #008400">// (size_t theId)</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">static</span> <span style="color: #bb2ca2">__thread</span> <span style="color: #4f8187">a</span> x(i);</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">for</span>(<span style="color: #703daa">size_t</span> j= <span style="color: #272ad8">0</span>; j < <span style="color: #272ad8">10000000</span>; ++j)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> tmpCounter += j * i;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> x.<span style="color: #4f8187">counter</span> += j * i;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> }</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> };</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #3d1d81">dispatch_group_async</span>(tmpDipatchGroupSPtr.<span style="color: #3d1d81">get</span>(), tmpDispatchQueue, <span style="color: #31595d">tmpHandler</span>);</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> }</div><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><p style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #3d1d81">dispatch_group_wait</span>(tmpDipatchGroupSPtr.<span style="color: #3d1d81">get</span>(), <span style="color: #78492a">DISPATCH_TIME_FOREVER</span>);</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0); "><span style="color: #000000"> </span>// insert code here...</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(209, 47, 27); "><span style="color: #000000"> </span><span style="color: #703daa">std</span><span style="color: #000000">::</span><span style="color: #703daa">cout</span><span style="color: #000000"> << </span>"Hello, World!\n"<span style="color: #000000">;</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #bb2ca2">return</span> tmpCounter;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">}</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div></div></body></html>