This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/26461] liveness of thread local references across function calls
- From: "gpderetta at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 19 Mar 2009 12:14:35 -0000
- Subject: [Bug middle-end/26461] liveness of thread local references across function calls
- References: <bug-26461-12263@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #7 from gpderetta at gmail dot com 2009-03-19 12:14 -------
Hi, I'm the author of Boost.Coroutine (not yet part of boost, but one day...).
I have the exact same problem: gcc caches the address of TLS variables across
function calls which breaks when coroutines move from one thread to another.
Note that in my case I'm definitely *not* reinventing threads in user space.
Coroutines are for different use cases than threads (i.e. when you do not need
preemption but simply a way to organize event driven code). One use of
boost.coroutine is on top of boost.asio.
Posix has both threads and swapcontext and nowhere it says that swapcontext
can't be used in threaded applications. In fact is simply states that the saved
context is restored after a call to setcontext, and IMHO any posix compatible
compiler should support this.
FWIW The microsoft c++ compiler has the /GT (fiber safe TLS) flag to prevent
exactly this kind of optimizations. Probably GCC should support something like
that too.
See:
http://www.crystalclearsoftware.com/soc/coroutine/coroutinecoroutine_thread.html
for details.
Finally I see the problem even with plain pointers and references, not only
arrays, at least with gcc4.3:
#include <ucontext.h>
void bar(int&);
__thread int x = 0;
void foo(ucontext_t&oucp, ucontext_t& ucp) {
bar(x);
swapcontext(&oucp, &ucp);
bar(x);
}
Compiles down to this (with -O3, on x86_64):
:_Z3fooR8ucontextS0_:
movq %fs:0, %rax
movq %rbp, -16(%rsp)
movq %rbx, -24(%rsp)
movq %r12, -8(%rsp)
movq %rsi, %rbx
subq $24, %rsp
movq %rdi, %r12
leaq x@TPOFF(%rax), %rbp
movq %rbp, %rdi
call _Z3barRi
movq %r12, %rdi
movq %rbx, %rsi
call swapcontext
movq %rbp, %rdi
movq (%rsp), %rbx
movq 8(%rsp), %rbp
movq 16(%rsp), %r12
addq $24, %rsp
jmp _Z3barRi
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461