This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
> This is what the specification says for some of the functions
> (pthread_join). We can of course choose to ignore it but it's a bit
> more problematic. Just assume this code:
>
> pthread_create (&t, ...);
> pthread_join (t, ...);
>
> There is no guarantee that the newly created thread already terminated
> when the join operation starts. It might even be that there is a new
> thread with this thread handle and so the join is for a different
> thread.
That is an entirely different case (which I already mentioned). An
undetached thread ID clearly remains valid after it terminates, so that
pthread_join can work. That is why I went to all the trouble of clearing
stating the complete set of cases, I wish you would address the points I
raised if you have something to say.
> > For the x86 segment register trick, you can do a very similar thing just
> > with another special declaration. Either:
> >
> > extern struct thread_internal *_self asm("%gs:0");
> > inline struct thread_internal *thread_self() { return _self; }
> >
> > or:
> >
> > extern struct thread_internal _self asm("%gs:0");
> > inline struct thread_internal *thread_self() { return &_self; }
>
> The second case does not work (try it, you get a wrong use of %gs) and
> overall this is not the same. In your case the compiler has to waste
> a register for the thread data pointer.
Have you tried it? I have, and I have used this very technique in another
implementation in the past. Here is an example:
struct foo {
int x, y;
};
extern struct foo seg __asm__("%gs:0");
static inline struct foo *
the_foo(void) { return &seg; }
int foobar(int x)
{
struct foo *me = the_foo();
return x + me->y;
}
This compiles to:
foobar:
pushl %ebp
movl %esp,%ebp
movl %gs:0+4,%eax
addl 8(%ebp),%eax
leave
ret
(That's from egcs 1.1b, but I have used this technique in the past with gcc
2.7.2.1 as well.) It is only a convenient happenstance of the assembly
syntax that this kludge turns out to work, but, hell, it's the x86.
> This makes a big difference for this stupid architecture. If you can
> find a way to modify your code appropriate it's certainly better. But
> I haven't found a possibility.
I have only the working example of exactly the syntax I used in my first
message to refer you to. What else can I say?
> Well, yes, of course this part is also dependend. But there is
> already functionality to do this in the libc API (swapcontext etc).
Yes, but we need to implement it!
> > But it can easily be a decision made at source level via sysdeps
> > typedefs/macros whether to include a "kernel thread" data structure
> > directly in the pthread data structure or to use a pointer to a
> > separately allocated structure.
>
> Makes sense. But we should forsee this right from the beginning.
Of course (and here we are foreseeing it right now in the beginning!).
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |