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]

Re: New pthreads library


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