[Bug c/26461] New: liveness of thread local references across function calls
I ran into this problem with stock gcc-4.0.2 on Fedora Core 2. The problem shows when the following code is compiled with -O2: the address of "array" seems to be cached and reused across calls to function "h". This becomes a problem when function h saves its execution context in one thread and resumes in another thread (thus the address of array changes before and after the call). Is this a feature or a bug? How could I instruct gcc not to reuse thread local addresses acrosses function calls? Thanks. __thread int array[1]; int *f() { for (;;) h(array); return array; } -- Summary: liveness of thread local references across function calls Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: yichen dot xie at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461
[Bug middle-end/26461] liveness of thread local references across function calls
--- Comment #2 from yichen dot xie at gmail dot com 2006-02-24 22:12 --- (In reply to comment #1) > It seems like you are trying to > deal with your own threading system instead of allowing the OS do its work. > This is indeed what I am trying to do, and C seems to be the perfect language for doing this. I agree it's not common to be switching thread contexts across function calls, but I don't think it should be prohibited by GCC. In my case, "h" simply saves its context, put it on the ready queue, and waits for another thread to pick it up and resume execution with the new thread local copy of "array". So the question is there a way to force recompuation of "&array[0]" after h? Is it reasonable to request for a mechanism to force recomputation of "&array[0]"? BTW, the solution IMO is simple: either make sure all thread local values and addresses (the problem seems to exist only with arrays, the compiler is more conservative dealing with pointers, etc) are dead after a function call, or add a mechanism (__attribute__((thread_switch))?) to force it. -- yichen dot xie at gmail dot com changed: What|Removed |Added ---------------- CC||yichen dot xie at gmail dot ||com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461
[Bug middle-end/26461] liveness of thread local references across function calls
--- Comment #4 from yichen dot xie at gmail dot com 2006-02-24 23:06 --- > Why not let the OS do its job? I still don't understand that idea. It's a thread library that builds on top of pthreads, so yes, OS is doing its job, and we're doing more on top of that. C is a natural choice for us. Does it help if we rename "h" to "reschedule"? __thread array[1]; for (;;) { // do something with array reschedule(); } > Actually no it is not responable in general since GCC assumes the address is > invariant which is correct except for your little weird case. What function Well, it may be a bit weird for any other language, but not C (IMO). It's definitely not weird if you compare it to the kernel, which is largely written in C. Thread local objects are invariant within a thread, not across threads. I think it could be dangerous for gcc to assume that function calls preserve thread context, esp. when the function is written in assembly. At least there should be a way to tell the compiler not to assume that, given C is a low-level language where everything should be possible. > are you using to save/restore the context? There are no standard C function Very simple assembly code that stores/restores a few registers, including %esp. C is a low level language, and it should interoperate well not only with standard C functions, but also with assembly or any other "weird" functions. That's what C is good for, isn't it? > which allows for that. Even get/setcontext are POSIX but I doubt they support > across threads correctly anyways. I know setjmp/longjmp don't for sure. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461
[Bug middle-end/26461] liveness of thread local references across function calls
--- Comment #6 from yichen dot xie at gmail dot com 2006-02-25 01:55 --- (In reply to comment #5) > ISO C is not your normal low level language any more. It actually tries to be > a high level language. > > So this is not a bug. > I still don't think it's a good idea to treat thread local array addresses as invariant. If you look at the implementation of getcontext/swapcontext, they intentionally left gs segment register out in the context, leaving open the possibility that a context saved by one thread be resumed by another. What will gcc do in this case? If you don't mind, could you point me to the section of ISO C where it specifies that function calls must preserve thread contexts? If not, by all means it's a bug in the optimizer. Does any one else have an opinion? -- yichen dot xie at gmail dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461