On Wed, 22 Apr 2009 02:45 -0400, "Dan E" <trg_i...@mailhaven.com> wrote:
> I dug deeper into this and it appears that the __clone function in
> libc/sysdeps/linux/mips/clone.S is missing a few parameters.  The first
> one that's missing is where the kernel should write the thread id.  See
> the comment about CLONE_PARENT_SETTID in
> libpthread/nptl/sysdeps/pthread/createthread.c.
> 
> I'm checking glibc's implementation and it looks like it handles all 7
> parameters.

OK, I fixed that up too based on the current glibc and the nptl tests
jumped from 52% to 94% passing.  169 out of 180 pass, with only 11
failing:

./tst-cancel16  FAIL
./tst-cancel7   FAIL
./tst-clock2    FAIL
./tst-cond20    FAIL
./tst-cond21    FAIL
./tst-flock1    FAIL
./tst-flock2    FAIL
./tst-mqueue1   FAIL
./tst-mqueue2   FAIL
./tst-mqueue4   FAIL
./tst-mqueue7   FAIL

It looks like NPTL on MIPS is getting a little closer to reality. 
libc/sysdeps/linux/mips/clone.S is definitely in the MIPS common code,
though, so perhaps you'd like to consider the following patch to see if
it breaks anything for the non-NPTL flavors of uClibc.

This patch modifies the MIPS userspace "clone()" function to accept the
three additional parameters that are now part of glibc.  Required for
NPTL pthread_create() to successfully obtain the thread id (tid) from
the kernel.


-- 
http://www.fastmail.fm - A no graphics, no pop-ups email service

diff -aur uClibc-nptl/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S
--- a/libc/sysdeps/linux/mips/clone.S	2008-07-09 19:36:41.000000000 -0400
+++ b/libc/sysdeps/linux/mips/clone.S	2009-04-22 04:01:54.000000000 -0400
@@ -26,15 +26,29 @@
 #define _ERRNO_H	1
 #include <bits/errno.h>
 #include <sys/asm.h>
+#ifdef RESET_PID
+#include <tls.h>
+#endif
+
+#define CLONE_VM	0x00000100
+#define CLONE_THREAD	0x00010000
 
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+		void *parent_tidptr, void *tls, void *child_tidptr) */
 
 	.text
+#if _MIPS_SIM == _ABIO32
+# define EXTRA_LOCALS 1
+#else
+# define EXTRA_LOCALS 0
+#endif
+LOCALSZ= 4
+FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
 .globl   clone ;
 	.align       2;
 	.type         clone,@function;
 	.ent        clone, 0;
-	
+
 clone:
 	.frame	    sp, 4*SZREG, sp
 #ifdef __PIC__
@@ -42,17 +56,16 @@
 	.set		noreorder
 	.cpload		$25
 	.set		reorder
-	subu		sp,32
+	subu		sp,FRAMESZ
 	.cprestore	16
 #else	/* N32 */
-	PTR_SUBU	sp,32	/* fn, arg, gp, pad */
+	PTR_SUBU	sp,FRAMESZ	/* fn, arg, gp, pad */
 	.cpsetup	$25, 16, clone
 #endif	/* N32 */
 #else
-	subu		sp,32
+	subu		sp,FRAMESZ
 #endif
 
-
 	/* Sanity check arguments.  */
 	li		v0,EINVAL
 	beqz		a0,error	/* No NULL function pointers.  */
@@ -64,11 +77,27 @@
 	PTR_SUBU	a1,32		/* Reserve argument save space.  */
 	PTR_S		a0,0(a1)	/* Save function pointer.  */
 	PTR_S		a3,PTRSIZE(a1)	/* Save argument pointer.  */
+#ifdef RESET_PID
+	LONG_S		a2,(PTRSIZE*2)(a1)	/* Save clone flags. */
+#endif
+
+	move		a0,a2
 
+	/* Shuffle in the last three arguments - arguments 5, 6, and 7 to
+           this function, but arguments 3, 4, and 5 to the syscall. */
+#if _MIPS_SIM == _ABIO32
+	PTR_L		a2,(FRAMESZ+PTRSIZE+PTRSIZE+16)(sp)
+	PTR_S		a2,16(sp)
+	PTR_L		a2,(FRAMESZ+16)(sp)
+	PTR_L		a3,(FRAMESZ+PTRSIZE+16)(sp)
+#else
+	move		a2,a4
+	move		a3,a5
+	move		a4,a6
+#endif
 
 	/* Do the system call */
-	move		a0,a2
-	li		v0,__NR_clone
+	li			v0,__NR_clone
 	syscall
 
 	bnez		a3,error
@@ -78,7 +107,7 @@
 #if _MIPS_SIM != _MIPS_SIM_ABI32
 	.cpreturn
 #endif
-	PTR_ADDU	sp,32
+	PTR_ADDU	sp,FRAMESZ
 	j $31  ; nop
 
 	/* Something bad happened -- no child created */
@@ -86,7 +115,7 @@
 #if _MIPS_SIM != _MIPS_SIM_ABI32
 	.cpreturn
 #endif
-	PTR_ADDU	sp,32
+	PTR_ADDU	sp,FRAMESZ
 
 	/* uClibc change -- start */
 	move		a0,v0		/* Pass return val to C function. */
@@ -94,9 +123,9 @@
 
 #ifdef __PIC__
 	PTR_LA		t9,__syscall_error
-	jr		t9
+	jr			t9
 #else
-	j		__syscall_error
+	j			__syscall_error
 #endif
 	.end  clone
 
@@ -114,16 +143,46 @@
 	.cprestore	16
 #endif
 	/* The stackframe has been created on entry of clone().  */
+
+#ifdef RESET_PID
+	/* Check and see if we need to reset the PID. */
+	LONG_L		a0,(PTRSIZE*2)(sp)
+	and			a1,a0,CLONE_THREAD
+	beqz		a1,L(restore_pid)
+L(donepid):
+#endif
+
 	/* Restore the arg for user's function.  */
-	PTR_L		t9,0(sp)	/* Function pointer.  */
+	PTR_L		t9,0(sp)		/* Function pointer.  */
 	PTR_L		a0,PTRSIZE(sp)	/* Argument pointer.  */
 
 	/* Call the user's function.  */
-	jal		t9
+	jal			t9
 
 	/* Call _exit rather than doing it inline for breakpoint purposes.  */
 	move		a0,v0
-	jal		HIDDEN_JUMPTARGET(_exit)
+#ifdef __PIC__
+	PTR_LA		t9,HIDDEN_JUMPTARGET(_exit)
+	jalr		t9
+#else
+	jal			HIDDEN_JUMPTARGET(_exit)
+#endif
+
+#ifdef RESET_PID
+L(restore_pid):
+	and			a1,a0,CLONE_VM
+	li			v0,-1
+	bnez		a1,L(gotpid)
+	li			v0,__NR_getpid
+	syscall
+L(gotpid):
+	READ_THREAD_POINTER(v1)
+	INT_S		v0,PID_OFFSET(v1)
+	INT_S		v0,TID_OFFSET(v1)
+	b			L(donepid)
+#endif
+
 	.end  __thread_start
+
 weak_alias(clone, __clone)
 
_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to