* sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Add support
authorRichard Henderson <rth@redhat.com>
Fri, 17 Dec 2004 10:11:44 +0000 (10:11 +0000)
committerRichard Henderson <rth@redhat.com>
Fri, 17 Dec 2004 10:11:44 +0000 (10:11 +0000)
        for NPTL where the PID is stored at userlevel and needs to be
        reset when CLONE_THREAD is not used.
nptl/
        * sysdeps/unix/sysv/linux/alpha/clone.S: New file.
        * sysdeps/alpha/tcb-offsets.sym (TID_OFFSET): New.

sysdeps/alpha/nptl/tcb-offsets.sym
sysdeps/unix/sysv/linux/alpha/clone.S
sysdeps/unix/sysv/linux/alpha/nptl/clone.S [new file with mode: 0644]

index ebd84f3..c21a791 100644 (file)
@@ -11,3 +11,4 @@
 
 MULTIPLE_THREADS_OFFSET                thread_offsetof (header.multiple_threads)
 PID_OFFSET                     thread_offsetof (pid)
+TID_OFFSET                     thread_offsetof (tid)
index b4766ec..1c450d1 100644 (file)
@@ -24,6 +24,9 @@
 #define _ERRNO_H       1
 #include <bits/errno.h>
 
+#define CLONE_VM       0x00000100
+#define CLONE_THREAD   0x00010000
+
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags,
             void *arg, pid_t *ptid, void *tls, pid_t *ctid);
 
@@ -51,9 +54,12 @@ ENTRY(__clone)
        beq     a1,$error               /* no NULL stack pointers */
 
        /* Save the fn ptr and arg on the new stack.  */
-       subq    a1,16,a1
+       subq    a1,32,a1
        stq     a0,0(a1)
        stq     a3,8(a1)
+#ifdef RESET_PID
+       stq     a2,16(a1)
+#endif
 
        /* The syscall is of the form clone(flags, usp, ptid, ctid, tls).
           Shift the flags, ptid, ctid, tls arguments into place; the
@@ -93,10 +99,19 @@ thread_start:
        mov     0, fp
        .prologue 0
 
+#ifdef RESET_PID
+       /* Check and see if we need to reset the PID.  */
+       ldq     t0,16(sp)
+       lda     t1,CLONE_THREAD
+       and     t0,t1,t2
+       beq     t2,2f
+1:
+#endif
+
        /* Load up the arguments.  */
        ldq     pv,0(sp)
        ldq     a0,8(sp)
-       addq    sp,16,sp
+       addq    sp,32,sp
 
        /* Call the user's function.  */
        jsr     ra,(pv)
@@ -113,6 +128,22 @@ thread_start:
        /* Die horribly.  */
        halt
 
+#ifdef RESET_PID
+2:
+       rduniq
+       lda     t1, CLONE_VM
+       mov     v0, s0
+       lda     v0, -1
+       and     t0, t1, t2
+       bne     t2, 3f
+       lda     v0, __NR_getxpid
+       callsys
+3:
+       stl     v0, PID_OFFSET(s0)
+       stl     v0, TID_OFFSET(s0)
+       br      1b
+#endif
+
        .end thread_start
 
 weak_alias(__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/alpha/nptl/clone.S b/sysdeps/unix/sysv/linux/alpha/nptl/clone.S
new file mode 100644 (file)
index 0000000..eea1cbe
--- /dev/null
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <sysdeps/unix/sysv/linux/alpha/clone.S>