[Bug c/26461] New: liveness of thread local references across function calls

2006-02-24 Thread yichen dot xie at gmail dot com
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

2006-02-24 Thread yichen dot xie at gmail dot com


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

2006-02-24 Thread yichen dot xie at gmail dot com


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

2006-02-24 Thread yichen dot xie at gmail dot com


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