From patchwork Fri May 9 20:00:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roland McGrath X-Patchwork-Id: 866 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx23.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id DEF92360073 for ; Fri, 9 May 2014 13:00:08 -0700 (PDT) Received: by homiemail-mx23.g.dreamhost.com (Postfix, from userid 14307373) id 76AED635FF6A0; Fri, 9 May 2014 13:00:08 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx23.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx23.g.dreamhost.com (Postfix) with ESMTPS id 4BC5A635CB737 for ; Fri, 9 May 2014 13:00:08 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:content-type :content-transfer-encoding:from:to:subject:message-id:date; q= dns; s=default; b=lHMdqbTIkLlXdBzq4hrkKQVYXzHr9r45Y5mD9YWZhKEhq5 bcutF7JssIw2cGb1CP8L88UeHMxaXWvxlm5zihuqdTfLdiY/jH2ewdcc73ztMvJ8 lEM5QRxrIQVQNejM0fTZzAnfrqQcx0h3NTgg73I7wb6G1JjfuLfv2z/RkQ4z4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:content-type :content-transfer-encoding:from:to:subject:message-id:date; s= default; bh=2JwdDaJMO7ABRJo6JMIxa2AA4c4=; b=vxOyv0Ofx02LnR2jrawC sAo0lJHIZO6k3a5CtYekXX/aOseDHCuFcQvp/TmG1ALsMWRzRJkuQ6zXHST9XxZf D/IZO/3oybwt+RJMFJvwvBoCR4mSeQ/ONlATUibGdkm7RicU6uU2++woTm7B+FzU DE2HCm7zpFMBINwLQ/wmDrk= Received: (qmail 31721 invoked by alias); 9 May 2014 20:00:05 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 31709 invoked by uid 89); 9 May 2014 20:00:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: topped-with-meat.com MIME-Version: 1.0 From: Roland McGrath To: "GNU C. Library" Subject: [PATCH roland/exit-thread] Clean up __exit_thread. Message-Id: <20140509200000.3050D2C39F8@topped-with-meat.com> Date: Fri, 9 May 2014 13:00:00 -0700 (PDT) X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=J405smXS c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=yPYmHpsGH-wA:10 a=Z6MIti7PxpgA:10 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=mDV3o1hIAAAA:8 a=6dbbA89-Le5OidUn6hQA:9 a=jN8X1nmLIh00sb6O:21 a=BHyBkxNhozkEPDHj:21 a=CjuIK1q_8ugA:10 X-DH-Original-To: glibc@patchwork.siddhesh.in This cleans things up in a few ways: * It removes a Linuxism from the pthreaddef.h files. * It removes duplication across all the pthreaddef.h files except i386 and x86_64. * It avoids the useless errno setting code on non-x86. * It removes the undocumented and unsupported __exit_thread entry point from libc.a. I verified on i386 and x86_64 builds that the code generated for start_thread in pthread_create.c is at least about as good as before. On x86_64, it perturbed the code generation substantially because the compiler knowing that the syscall sequence can never return changes how it organizes the blocks; probably the new code is better. On i386, the old code used 'int $0x80' and now it uses the vDSO entry point like regular syscall stubs do. This should perform marginally better. It also means that in a situation where wild memory clobberation has corrupted the TCB, an exitting thread might do more unpredictable things and possibly never actually exit, whereas before it was more likely to do the syscall. I don't think that's worth caring about. But if it is, we can easily add an i386-specific exit-thread.h to do what the old code did. I didn't test any other machines, but it's hard to see how they could go wrong. I'd appreciate people testing the branch on other machines. If nobody objects, I'll probably commit this on Monday. Thanks, Roland 2014-05-09 Roland McGrath * sysdeps/generic/exit-thread.h: New file. * sysdeps/unix/sysv/linux/exit-thread.h: New file. * include/unistd.h (__exit_thread): Remove declaration. * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Drop exit-thread. * sysdeps/unix/sysv/linux/exit-thread.S: File removed. * csu/libc-start.c: Include . (LIBC_START_MAIN): Pass no argument to __exit_thread. * nptl/pthread_create.c: Include . (start_thread): Call __exit_thread in place of __exit_thread_inline. * nptl/sysdeps/i386/pthreaddef.h (__exit_thread_inline): Macro removed. * nptl/sysdeps/powerpc/pthreaddef.h: Likewise. * nptl/sysdeps/s390/pthreaddef.h: Likewise. * nptl/sysdeps/sh/pthreaddef.h: Likewise. * nptl/sysdeps/sparc/sparc32/pthreaddef.h: Likewise. * nptl/sysdeps/sparc/sparc64/pthreaddef.h: Likewise. * nptl/sysdeps/x86_64/pthreaddef.h: Likewise. * sysdeps/aarch64/nptl/pthreaddef.h: Likewise. * sysdeps/alpha/nptl/pthreaddef.h: Likewise. * sysdeps/arm/nptl/pthreaddef.h: Likewise. * sysdeps/hppa/nptl/pthreaddef.h: Likewise. * sysdeps/ia64/nptl/pthreaddef.h: Likewise. * sysdeps/m68k/nptl/pthreaddef.h: Likewise. * sysdeps/microblaze/nptl/pthreaddef.h: Likewise. * sysdeps/mips/nptl/pthreaddef.h: Likewise. * sysdeps/tile/nptl/pthreaddef.h: Likewise. --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -20,6 +20,7 @@ #include #include #include +#include extern void __libc_init_first (int argc, char **argv, char **envp); #ifndef SHARED @@ -312,7 +313,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), if (! atomic_decrement_and_test (ptr)) /* Not much left to do but to exit the thread, not the process. */ - __exit_thread (0); + __exit_thread (); } #else /* Nothing fancy, just call the function. */ --- a/include/unistd.h +++ b/include/unistd.h @@ -161,9 +161,6 @@ extern int __libc_enable_secure_internal attribute_relro attribute_hidden; extern void __libc_check_standard_fds (void); -/* Special exit function which only terminates the current thread. */ -extern void __exit_thread (int val) __attribute__ ((noreturn)); - /* Internal name for fork function. */ extern __pid_t __libc_fork (void); --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -432,7 +433,7 @@ start_thread (void *arg) The exit code is zero since in case all threads exit by calling 'pthread_exit' the exit status must be 0 (zero). */ - __exit_thread_inline (0); + __exit_thread (); /* NOTREACHED */ return 0; --- a/nptl/sysdeps/i386/pthreaddef.h +++ b/nptl/sysdeps/i386/pthreaddef.h @@ -38,16 +38,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - while (1) { \ - if (__builtin_constant_p (val) && (val) == 0) \ - asm volatile ("xorl %%ebx, %%ebx; int $0x80" :: "a" (__NR_exit)); \ - else \ - asm volatile ("movl %1, %%ebx; int $0x80" \ - :: "a" (__NR_exit), "r" (val)); \ - } --- a/nptl/sysdeps/powerpc/pthreaddef.h +++ b/nptl/sysdeps/powerpc/pthreaddef.h @@ -31,10 +31,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/nptl/sysdeps/s390/pthreaddef.h +++ b/nptl/sysdeps/s390/pthreaddef.h @@ -31,10 +31,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/nptl/sysdeps/sh/pthreaddef.h +++ b/nptl/sysdeps/sh/pthreaddef.h @@ -32,17 +32,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - while (1) { \ - if (__builtin_constant_p (val) && (val) == 0) \ - asm volatile ("mov #0,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD \ - :: "i" (__NR_exit)); \ - else \ - asm volatile ("mov %1,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD \ - :: "i" (__NR_exit), "r" (val)); \ - } --- a/nptl/sysdeps/sparc/sparc32/pthreaddef.h +++ b/nptl/sysdeps/sparc/sparc32/pthreaddef.h @@ -31,9 +31,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME (stack_pointer + (2 * 64)) register char *stack_pointer __asm__("%sp"); - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/nptl/sysdeps/sparc/sparc64/pthreaddef.h +++ b/nptl/sysdeps/sparc/sparc64/pthreaddef.h @@ -31,9 +31,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME (stack_pointer + (2 * 128)) register char *stack_pointer __asm__("%sp"); - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/nptl/sysdeps/x86_64/pthreaddef.h +++ b/nptl/sysdeps/x86_64/pthreaddef.h @@ -42,10 +42,3 @@ /* Location of current stack frame. The frame pointer is not usable. */ #define CURRENT_STACK_FRAME \ ({ register char *frame __asm__("rsp"); frame; }) - - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - asm volatile ("syscall" :: "a" (__NR_exit), "D" (val)) --- a/sysdeps/aarch64/nptl/pthreaddef.h +++ b/sysdeps/aarch64/nptl/pthreaddef.h @@ -30,8 +30,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/alpha/nptl/pthreaddef.h +++ b/sysdeps/alpha/nptl/pthreaddef.h @@ -29,9 +29,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/arm/nptl/pthreaddef.h +++ b/sysdeps/arm/nptl/pthreaddef.h @@ -39,8 +39,3 @@ return the hard FP minus 12. Of course, this makes no sense without the obsolete APCS stack layout... */ #define CURRENT_STACK_FRAME (__builtin_frame_address (0) - 12) - - -/* XXX Until we have a better place keep the definitions here. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/unix/sysv/linux/exit-thread.S +++ b/sysdeps/generic/exit-thread.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-2014 Free Software Foundation, Inc. +/* Call to terminate the current thread. Stub version. + Copyright (C) 2014 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 @@ -15,8 +16,13 @@ License along with the GNU C Library; if not, see . */ -#include +/* This causes the current thread to exit, without affecting other + threads in the process if there are any. If there are no other + threads left, then this has the effect of _exit (0). */ -PSEUDO (__exit_thread, exit, 1) - /* Shouldn't get here. */ -PSEUDO_END(__exit_thread) +static inline void __attribute__ ((noreturn, always_inline, unused)) +__exit_thread (void) +{ + while (1) + asm ("write me!"); +} --- a/sysdeps/hppa/nptl/pthreaddef.h +++ b/sysdeps/hppa/nptl/pthreaddef.h @@ -31,9 +31,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME stack_pointer register char * stack_pointer __asm__ ("%r30"); - - -/* XXX Until we have a better place keep the definitions here. */ - -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/ia64/nptl/pthreaddef.h +++ b/sysdeps/ia64/nptl/pthreaddef.h @@ -34,9 +34,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __stack_pointer register char *__stack_pointer __asm__ ("sp"); - -/* XXX Until we have a better place keep the definitions here. */ - -/* While there is no such syscall. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/m68k/nptl/pthreaddef.h +++ b/sysdeps/m68k/nptl/pthreaddef.h @@ -31,8 +31,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/microblaze/nptl/pthreaddef.h +++ b/sysdeps/microblaze/nptl/pthreaddef.h @@ -33,8 +33,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - -/* XXX Until we have a better place keep the definitions here. */ - -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/mips/nptl/pthreaddef.h +++ b/sysdeps/mips/nptl/pthreaddef.h @@ -30,9 +30,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - - -/* XXX Until we have a better place keep the definitions here. */ - -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/tile/nptl/pthreaddef.h +++ b/sysdeps/tile/nptl/pthreaddef.h @@ -34,8 +34,3 @@ /* Location of current stack frame. */ #define CURRENT_STACK_FRAME __builtin_frame_address (0) - -/* XXX Until we have a better place keep the definitions here. */ - -#define __exit_thread_inline(val) \ - INLINE_SYSCALL (exit, 1, (val)) --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -141,7 +141,7 @@ endif ifeq ($(subdir),posix) sysdep_headers += bits/initspin.h -sysdep_routines += exit-thread sched_getcpu +sysdep_routines += sched_getcpu tests += tst-getcpu endif --- /dev/null +++ b/sysdeps/unix/sysv/linux/exit-thread.h @@ -0,0 +1,38 @@ +/* Call to terminate the current thread. Linux version. + Copyright (C) 2014 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, see + . */ + +#include + +/* This causes the current thread to exit, without affecting other + threads in the process if there are any. If there are no other + threads left, then this has the effect of _exit (0). */ + +static inline void __attribute__ ((noreturn, always_inline, unused)) +__exit_thread (void) +{ + /* Doing this in a loop is mostly just to satisfy the compiler that the + function really qualifies as noreturn. It also means that in some + pathological situation where the system call does not get made or does + not work, the thread will simply spin rather than running off the end + of the caller and doing unexpectedly strange things. */ + while (1) + { + INTERNAL_SYSCALL_DECL (err); + INTERNAL_SYSCALL (exit, err, 1, 0); + } +}