about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--linuxthreads/ChangeLog8
-rw-r--r--linuxthreads/sysdeps/s390/Makefile6
-rw-r--r--linuxthreads/sysdeps/s390/tcb-offsets.sym4
-rw-r--r--linuxthreads/sysdeps/s390/tls.h63
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h106
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h96
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/socket.S41
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/sigsuspend.c15
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/socket.S31
10 files changed, 375 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index dbf029854a..c04ba452df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,18 @@
+2003-01-05  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/s390/s390-32/socket.S: Add support for
+	cancellation handling.
+	* sysdeps/unix/sysv/linux/s390/s390-64/socket.S: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sigsuspend.c: Likewise.
+
+2003-01-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/system.c (cancel_handler): Correct
+	order of parameters passed to kill.
+
 2003-01-04  Andreas Schwab  <schwab@suse.de>
 
-	* sysdeps/unix/sysv/linux/m68k/bits/stat.h: Add nanosecond
-	fields.
+	* sysdeps/unix/sysv/linux/m68k/bits/stat.h: Add nanosecond fields.
 
 2002-01-03  Paul Eggert  <eggert@twinsun.com>
 
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index c9da1c6356..f7440a59e2 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,11 @@
+2003-01-05  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: New file.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: New file.
+	* sysdeps/s390/Makefile: New file.
+	* sysdeps/s390/tcb-offsets.sym: New file.
+	* sysdeps/s390/tls.h: New file.
+
 2003-01-03  Richard Henderson  <rth@redhat.com>
 
 	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: New file.
diff --git a/linuxthreads/sysdeps/s390/Makefile b/linuxthreads/sysdeps/s390/Makefile
new file mode 100644
index 0000000000..2885c968b3
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/Makefile
@@ -0,0 +1,6 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
+ifeq ($(subdir),linuxthreads)
+libpthread-routines += ptw-sysdep
+endif
diff --git a/linuxthreads/sysdeps/s390/tcb-offsets.sym b/linuxthreads/sysdeps/s390/tcb-offsets.sym
new file mode 100644
index 0000000000..aee6be2570
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/tcb-offsets.sym
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
diff --git a/linuxthreads/sysdeps/s390/tls.h b/linuxthreads/sysdeps/s390/tls.h
new file mode 100644
index 0000000000..d872bb7553
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/tls.h
@@ -0,0 +1,63 @@
+/* Definitions for thread-local data handling.  linuxthreads/s390 version.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;		/* Pointer to the TCB.  Not necessary the
+			   thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;		/* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+#undef USE_TLS
+
+#if USE_TLS
+
+#else
+
+#define NONTLS_INIT_TP \
+  do { 								\
+    static const tcbhead_t nontls_init_tp			\
+      = { .multiple_threads = 0 };				\
+    INIT_THREAD_SELF (&nontls_init_tp, 0);			\
+  } while (0)
+
+#endif /* USE_TLS */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
new file mode 100644
index 0000000000..753fdd93f5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
@@ -0,0 +1,106 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+	.text;								      \
+ENTRY(name)								      \
+	SINGLE_THREAD_P(%r1)						      \
+	jne	L(pseudo_cancel);					      \
+	DO_CALL(syscall_name, args);					      \
+	lhi	%r4,-4095;						      \
+	clr	%r2,%r4;						      \
+	jnl	SYSCALL_ERROR_LABEL;					      \
+	br	%r14;							      \
+L(pseudo_cancel):							      \
+	STM_##args							      \
+	stm	%r13,%r15,52(%r15);					      \
+	ahi	%r15,-96;						      \
+	basr    %r13,0;							      \
+200301:	l	%r1,200302f-200301b(%r13);				      \
+	bas	%r14,0(%r13,%r1);					      \
+	lr	%r0,%r2;						      \
+	LM_##args							      \
+	DO_CALL(syscall_name, args);					      \
+	l	%r3,200303f-200301b(%r13);				      \
+	lr	%r4,%r13;						      \
+	lr	%r13,%r2;						      \
+	lr	%r2,%r0;						      \
+	bas	%r14,0(%r4,%r3);					      \
+	lr	%r2,%r13;						      \
+	lm	%r13,%r15,52+96(%r15);					      \
+	lhi	%r4,-4095;						      \
+	clr	%r2,%r4;						      \
+	jnl	SYSCALL_ERROR_LABEL;					      \
+L(pseudo_end):
+
+#undef PSEUDO_END
+#define PSEUDO_END(name)						      \
+  SYSCALL_ERROR_HANDLER;						      \
+200302:	.long	CENABLE-200301b;					      \
+200303:	.long	CDISABLE-200301b;					      \
+    END (name)
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	__pthread_enable_asynccancel
+#  define CDISABLE	__pthread_disable_asynccancel
+# else
+#  define CENABLE	__libc_enable_asynccancel
+#  define CDISABLE	__libc_disable_asynccancel
+# endif
+
+#define STM_0		/* Nothing */
+#define STM_1		st %r2,8(%r15);
+#define STM_2		stm %r2,%r3,8(%r15);
+#define STM_3		stm %r2,%r4,8(%r15);
+#define STM_4		stm %r2,%r5,8(%r15);
+#define STM_5		stm %r2,%r5,8(%r15);
+
+#define LM_0		/* Nothing */
+#define LM_1		l %r2,8+96(%r15);
+#define LM_2		lm %r2,%r3,8+96(%r15);
+#define LM_3		lm %r2,%r4,8+96(%r15);
+#define LM_4		lm %r2,%r5,8+96(%r15);
+#define LM_5		lm %r2,%r5,8+96(%r15);
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P(reg) \
+	ear	reg,%a0;						      \
+	l	reg,MULTIPLE_THREADS_OFFSET(reg);			      \
+	ltr	reg,reg;
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
new file mode 100644
index 0000000000..0e3daa5d31
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
@@ -0,0 +1,96 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+	.text;								      \
+ENTRY(name)								      \
+	SINGLE_THREAD_P							      \
+	jne	L(pseudo_cancel);					      \
+	DO_CALL(syscall_name, args);					      \
+	lghi	%r4,-4095;						      \
+	clgr	%r2,%r4;						      \
+	jnl	SYSCALL_ERROR_LABEL;					      \
+	br	%r14;							      \
+L(pseudo_cancel):							      \
+	STM_##args							      \
+	stmg	%r13,%r15,104(%r15);					      \
+	aghi	%r15,-192;						      \
+	brasl	%r14,CENABLE;						      \
+	lr	%r0,%r2;						      \
+	LM_##args							      \
+	DO_CALL(syscall_name, args);					      \
+	lgr	%r13,%r2;						      \
+	lr	%r2,%r0;						      \
+	brasl	%r14,CDISABLE;						      \
+	lgr	%r2,%r13;						      \
+	lmg	%r13,%r15,104+192(%r15);				      \
+	lghi	%r4,-4095;						      \
+	clgr	%r2,%r4;						      \
+	jnl	SYSCALL_ERROR_LABEL;					      \
+L(pseudo_end):
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	__pthread_enable_asynccancel
+#  define CDISABLE	__pthread_disable_asynccancel
+#  define __local_multiple_threads	__pthread_multiple_threads
+# else
+#  define CENABLE	__libc_enable_asynccancel
+#  define CDISABLE	__libc_disable_asynccancel
+#  define __local_multiple_threads	__libc_multiple_threads
+# endif
+
+#define STM_0		/* Nothing */
+#define STM_1		stg %r2,16(%r15);
+#define STM_2		stmg %r2,%r3,16(%r15);
+#define STM_3		stmg %r2,%r4,16(%r15);
+#define STM_4		stmg %r2,%r5,16(%r15);
+#define STM_5		stmg %r2,%r5,16(%r15);
+
+#define LM_0		/* Nothing */
+#define LM_1		lg %r2,16+192(%r15);
+#define LM_2		lmg %r2,%r3,16+192(%r15);
+#define LM_3		lmg %r2,%r4,16+192(%r15);
+#define LM_4		lmg %r2,%r5,16+192(%r15);
+#define LM_5		lmg %r2,%r5,16+192(%r15);
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P \
+  __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  define SINGLE_THREAD_P \
+	larl	%r1,__local_multiple_threads;				      \
+	icm	%r0,15,0(%r1);
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/socket.S b/sysdeps/unix/sysv/linux/s390/s390-32/socket.S
index 366b655e56..c4eb2cab0b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/socket.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/socket.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
    This file is part of the GNU C Library.
 
@@ -17,7 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <sysdep.h>
+#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 /* &%/$&!! preprocessor */
@@ -73,6 +73,12 @@ ENTRY(__socket)
 	st      %r3,0x64(0,%r15)        /* store into parameter list */
 	st      %r2,0x60(0,%r15)
 #endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+	SINGLE_THREAD_P (%r4)
+	jne	L(socket_cancel)
+#endif
+
 	/* load subcode for socket syscall */
 	lhi     %r2,P(SOCKOP_,socket)
 	la      %r3,0x60(0,%r15)        /* load address of parameter list */
@@ -80,6 +86,7 @@ ENTRY(__socket)
 	/* Do the system call trap.  */
 	svc     SYS_ify(socketcall)
 
+4:
 	l       %r15,0(0,%r15)          /* load back chain */
 	lm      %r6,15,24(%r15)         /* load registers */
 
@@ -91,7 +98,35 @@ ENTRY(__socket)
 	/* Successful; return the syscall's value.  */
 	br      %r14
 
-PSEUDO_END (__socket)
+#if defined NEED_CANCELLATION && defined CENABLE
+L(socket_cancel):
+	basr	%r13,0
+1:	l	%r1,2f-1b(%r13)
+	/* call CENABLE.  */
+	bas	%r14,0(%r13,%r1)
+	lr	%r0,%r2
+
+	/* load subcode for socket syscall */
+	lhi     %r2,P(SOCKOP_,socket)
+	la      %r3,0x60(0,%r15)        /* load address of parameter list */
+
+	/* Do the system call trap.  */
+	svc     SYS_ify(socketcall)
+
+	l	%r3,3f-1b(%r13)
+	lr	%r12,%r2
+	lr	%r2,%r0
+	/* call CDISABLE.  */
+	bas     %r14,0(%r13,%r3)
+	lr	%r2,%r12
+	j	4b
+
+2:	.long	CENABLE-1b
+3:	.long	CDISABLE-1b
+#endif
+
+	SYSCALL_ERROR_HANDLER
+END (__socket)
 
 #ifndef NO_WEAK_ALIAS
 weak_alias (__socket, socket)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigsuspend.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigsuspend.c
index 4fa30ec3c8..f5e8de3160 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/sigsuspend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,7 @@
 #include <signal.h>
 #include <unistd.h>
 
-#include <sysdep.h>
+#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 
 extern int __syscall_rt_sigsuspend (const sigset_t *, size_t);
@@ -34,7 +34,16 @@ __sigsuspend (set)
 {
   /* XXX The size argument hopefully will have to be changed to the
      real size of the user-level sigset_t.  */
-  return INLINE_SYSCALL (rt_sigsuspend, 2, set, _NSIG / 8);
+  if (SINGLE_THREAD_P)
+    return INLINE_SYSCALL (rt_sigsuspend, 2, set, _NSIG / 8);
+
+  int oldtype = LIBC_CANCEL_ASYNC ();
+
+  int result = INLINE_SYSCALL (rt_sigsuspend, 2, set, _NSIG / 8);
+
+  LIBC_CANCEL_RESET (oldtype);
+
+  return result;
 }
 libc_hidden_def (__sigsuspend)
 weak_alias (__sigsuspend, sigsuspend)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/socket.S b/sysdeps/unix/sysv/linux/s390/s390-64/socket.S
index 405802f61f..c9bd02baee 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/socket.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/socket.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
    This file is part of the GNU C Library.
 
@@ -17,7 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <sysdep.h>
+#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 /* &%/$&!! preprocessor */
@@ -73,6 +73,12 @@ ENTRY(__socket)
         stg     %r3,168(%r15)           /* Store into parameter list.  */
 	stg     %r2,160(%r15)
 #endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+	SINGLE_THREAD_P
+	jne	L(socket_cancel)
+#endif
+
         /* Load subcode for socket syscall.  */
         lghi    %r2,P(SOCKOP_,socket)
 	la      %r3,160(%r15)           /* Load address of parameter list.  */
@@ -80,6 +86,7 @@ ENTRY(__socket)
         /* Do the system call trap.  */
         svc     SYS_ify(socketcall)
 
+4:
         lg      %r15,0(%r15)            /* Load back chain.  */
         lmg     %r6,15,48(%r15)         /* Load registers.  */
 
@@ -91,6 +98,26 @@ ENTRY(__socket)
 	/* Successful; return the syscall's value.  */
 	br      %r14
 
+#if defined NEED_CANCELLATION && defined CENABLE
+L(socket_cancel):
+	brasl	%r14,CENABLE
+	lr	%r0,%r2
+
+	/* Load subcode for socket syscall.  */
+	lghi	%r2,P(SOCKOP_,socket)
+	la	%r3,160(%r15)		/* Load address of parameter list.  */
+
+	/* Do the system call trap.  */
+	svc	SYS_ify(socketcall)
+
+	lgr	%r12,%r2
+	lr	%r2,%r0
+	brasl	%r14,CDISABLE
+
+	lgr	%r2,%r12
+	j	4b
+#endif
+
 PSEUDO_END (__socket)
 
 #ifndef NO_WEAK_ALIAS