------- 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