From patchwork Wed Feb 7 13:09:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 127178 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp456320ljc; Wed, 7 Feb 2018 05:10:15 -0800 (PST) X-Google-Smtp-Source: AH8x225LDlKcAxtnrGdWxs3jUN+ZOaDnCbozWHWiy8v/7fB/vY4QHcvZttdArlRjHbfAq2g1HwPa X-Received: by 10.98.7.214 with SMTP id 83mr5924420pfh.130.1518009015163; Wed, 07 Feb 2018 05:10:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518009015; cv=none; d=google.com; s=arc-20160816; b=jIFQXJLBvEsnWoVe6ImQJgUOfm00L/IcJGItwccfwyTHCXKyafOsJ9ASKj+uxGGbKk QpbRvg48kvBjqCRcJrUn2BjvXg7wXOkgaeLp9f/OhhHLObJr4RXN70zfaBOmJxd8A4bA /C+Qc5NhnhFuTqljXppRl4wsdKd3flL2tUBAXW95jcYmv7/tIim/BczAf3QvXCQIh7RU 7pWb1k0F+7XX+BZFAUChBSEIZeo30BOEqJ8bI+JZ27iVyptQJbbYFIx3t6H4UeHX6OrI +SgMdSUccbDTiffFY8genafHYhvJk/6JP1Ki/NAb06qSuYtHGN23N9gDn9geTq6QDITq aRDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from:delivered-to:sender:list-help :list-post:list-archive:list-subscribe:list-unsubscribe:list-id :precedence:mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=KNbxn4UixnFlg+vxknOdIqwQhzs9N39cbK3/yw0cZPQ=; b=Z2rjd465/i3VU3gO1HaQBQSxjPMhNOASzZEQUQBAhv8GzgYU8vwL98NmzwUrxYkcNs ZV5MBG3UHTsYJdjwEw7zAA+Hvii/ax+WizMc83oO1n9CoshDF5haIfnSvWwKEa4mnzfj wxQ3bEsugTRaO6az5H/VUlR6NV7bNfp7+uepi+HHQ6gbiVlbRLriY+zfsms5ZS6og/pK zTVaZjsVsl1yjVcXTB4YArhTriWAxJts54d5ef2MAsMeV/3ZkrfYqMDPfLpdx1GRX0Fl VYqnWHYShZMdpEWZtWd9hYXWqy2XRGKN51eCfX1f6BRslYJwfFfJAmf56zYDw+GJE5oI 3aFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=feWItxIy; spf=pass (google.com: domain of libc-alpha-return-90100-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90100-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id k8si926754pgc.482.2018.02.07.05.10.14 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Feb 2018 05:10:15 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90100-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=feWItxIy; spf=pass (google.com: domain of libc-alpha-return-90100-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90100-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=IlgjuBz53CNMLz+ZIyaQAxM+qCXKp0llNCVGXPwY1vxq9siclrnoE dUQzhQKnBOzO5K2VXM6bUYU3aGtIGRtAuGpkFFcf3rCe3OlSPfRg14iPV4Qqtnis LDCu1ZrBrhJOxlfNuZkvrHfE1nkfQL75yZOAPEr+0cgxujCMg2VbPI= 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:from:to:subject:date:message-id; s=default; bh=XiaZBqf08f5lfzGcHA/jMd2pWys=; b=feWItxIyi3ZoqokRkvxqKgJHrlPB 1etXkph9xbv7hCZnbs0oiCdZm73eUcZ8XRlXXju8TRQXbjVl3anjdnQi3i1p/AJs 4Gagz2cGxPn38AbaHdteX/d1AqhUUkXam6cMtK9YRO9WkMeF03jypqUejmTSin/Z dv3HaKSI5dHTUTA= Received: (qmail 12254 invoked by alias); 7 Feb 2018 13:09:50 -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 12105 invoked by uid 89); 7 Feb 2018 13:09:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS, URIBL_RED autolearn=ham version=3.3.2 spammy=20102018 X-HELO: mail-qk0-f196.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=KNbxn4UixnFlg+vxknOdIqwQhzs9N39cbK3/yw0cZPQ=; b=ppMJCxZB6addcwYRErbci/EdhGJBJQsXgC712MFxN14yo0MMeYxZUX1Q2VCn4Bghv4 o9Cj7fxDIDwzG3OzytdzBcM/xMWl/uw4PLdpS3cqOZo2NdS67el+CKgQG3HtPYqXLGSQ utyRpe6EsrUPmRa090wU3cC00wFA/5woHBjtiNy/ILcit1jypLJWxmYmVLSsgwBAEAtM x9eXf1Q4s9MYmVX0rGwL/d/ekJpBG9VRONIL00i4QdhelYjSZuY3q85Lga3naPhK1A0j UCYWtXVV8Ac5ttTLaWsVdYO6Y+++bnMQvZDL89jdomoH+gBT4F27PxEhCw7z3dPY0dGi Xmqw== X-Gm-Message-State: APf1xPCtB+FBU8iPluoqInQ3wTeqRuA+730FkZQ4xyQsoHb7pvsN43Kg 9fFzRDwGhPqU9FsfeOwd+J+rtmmafh4= X-Received: by 10.55.15.4 with SMTP id z4mr8529072qkg.138.1518008977808; Wed, 07 Feb 2018 05:09:37 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 1/3] Refactor Linux ARCH_FORK implementation Date: Wed, 7 Feb 2018 11:09:25 -0200 Message-Id: <1518008967-8310-1-git-send-email-adhemerval.zanella@linaro.org> This patch refactors the ARCH_FORK macro and the required architecture specific header to simplify the required architecture definitions to provide the fork syscall semantic and proper document current Linux clone ABI variant. Instead of require the reimplementation of arch-fork.h header, this patch changes the ARCH_FORK to an inline function with clone ABI defined by kernel-features.h define. The generic kernel ABI meant for newer ports is used as default and redefine if the architecture requires. Checked on x86_64-linux-gnu and i686-linux-gnu. Also with a build for all the afected ABIs. * sysdeps/nptl/fork.c (ARCH_FORK): Replace by auch_fork. * sysdeps/unix/sysv/linux/alpha/arch-fork.h: Remove file. * sysdeps/unix/sysv/linux/riscv/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/aarch64/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/arm/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/hppa/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/i386/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/ia64/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/m68k/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/microblaze/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/mips/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/nios2/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/s390/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/sh/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/sparc/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/tile/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/arch-fork.h: Likewise. * sysdeps/unix/sysv/linux/arch-fork.h (arch_fork): New function. * sysdeps/unix/sysv/linux/aarch64/kernel-features.h: New file. * sysdeps/unix/sysv/linux/riscv/kernel-features.h: Likewise. * sysdeps/unix/sysv/linux/arm/kernel-features.h (__ASSUME_CLONE_BACKWARDS): Define. * sysdeps/unix/sysv/linux/createthread.c (ARCH_CLONE): Define to __clone2 if __NR_clone2 is defined. * sysdeps/unix/sysv/linux/hppa/kernel-features.h (__ASSUME_CLONE_BACKWARDS): Likewise. * sysdeps/unix/sysv/linux/i386/kernel-features.h (__ASSUME_CLONE_BACKWARDS): Likewise. * sysdeps/unix/sysv/linux/ia64/kernel-features.h (__ASSUME_CLONE2): Likewise. * sysdeps/unix/sysv/linux/microblaze/kernel-features.h (__ASSUME_CLONE_BACKWARDS3): Likewise. * sysdeps/unix/sysv/linux/kernel-features.h: Document possible clone variants and the define architecture can use. (__ASSUME_CLONE_DEFAULT): Define as default. * sysdeps/unix/sysv/linux/mips/kernel-features.h (__ASSUME_CLONE_BACKWARDS): Likewise. * sysdeps/unix/sysv/linux/powerpc/kernel-features.h (__ASSUME_CLONE_BACKWARDS): Likewise. * sysdeps/unix/sysv/linux/s390/kernel-features.h (__ASSUME_CLONE_BACKWARDS2): Likewise. --- ChangeLog | 45 ++++++++++++++++++++++ sysdeps/nptl/fork.c | 8 +--- .../arch-fork.h => aarch64/kernel-features.h} | 15 +++----- sysdeps/unix/sysv/linux/alpha/arch-fork.h | 28 -------------- sysdeps/unix/sysv/linux/arch-fork.h | 44 ++++++++++++++++----- sysdeps/unix/sysv/linux/arm/arch-fork.h | 27 ------------- sysdeps/unix/sysv/linux/arm/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/createthread.c | 5 ++- sysdeps/unix/sysv/linux/hppa/arch-fork.h | 32 --------------- sysdeps/unix/sysv/linux/hppa/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/i386/arch-fork.h | 27 ------------- sysdeps/unix/sysv/linux/i386/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/ia64/arch-fork.h | 31 --------------- sysdeps/unix/sysv/linux/ia64/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/kernel-features.h | 35 +++++++++++++++++ sysdeps/unix/sysv/linux/m68k/arch-fork.h | 28 -------------- sysdeps/unix/sysv/linux/microblaze/arch-fork.h | 27 ------------- .../unix/sysv/linux/microblaze/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/mips/arch-fork.h | 1 - sysdeps/unix/sysv/linux/mips/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/nios2/arch-fork.h | 33 ---------------- sysdeps/unix/sysv/linux/powerpc/arch-fork.h | 1 - sysdeps/unix/sysv/linux/powerpc/kernel-features.h | 3 ++ .../arch-fork.h => riscv/kernel-features.h} | 17 +++----- sysdeps/unix/sysv/linux/s390/arch-fork.h | 29 -------------- sysdeps/unix/sysv/linux/s390/kernel-features.h | 3 ++ sysdeps/unix/sysv/linux/sh/arch-fork.h | 28 -------------- sysdeps/unix/sysv/linux/sparc/arch-fork.h | 27 ------------- sysdeps/unix/sysv/linux/tile/arch-fork.h | 29 -------------- sysdeps/unix/sysv/linux/x86_64/arch-fork.h | 27 ------------- 30 files changed, 155 insertions(+), 413 deletions(-) rename sysdeps/unix/sysv/linux/{riscv/arch-fork.h => aarch64/kernel-features.h} (67%) delete mode 100644 sysdeps/unix/sysv/linux/alpha/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/arm/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/hppa/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/i386/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/ia64/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/m68k/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/microblaze/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/mips/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/nios2/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/powerpc/arch-fork.h rename sysdeps/unix/sysv/linux/{aarch64/arch-fork.h => riscv/kernel-features.h} (66%) delete mode 100644 sysdeps/unix/sysv/linux/s390/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/sh/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/sparc/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/tile/arch-fork.h delete mode 100644 sysdeps/unix/sysv/linux/x86_64/arch-fork.h -- 2.7.4 diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c index 846fa49..0061ee0 100644 --- a/sysdeps/nptl/fork.c +++ b/sysdeps/nptl/fork.c @@ -131,13 +131,7 @@ __libc_fork (void) call_function_static_weak (__malloc_fork_lock_parent); } -#ifdef ARCH_FORK - pid = ARCH_FORK (); -#else -# error "ARCH_FORK must be defined so that the CLONE_SETTID flag is used" - pid = INLINE_SYSCALL (fork, 0); -#endif - + pid = arch_fork (&THREAD_SELF->tid); if (pid == 0) { diff --git a/sysdeps/unix/sysv/linux/riscv/arch-fork.h b/sysdeps/unix/sysv/linux/aarch64/kernel-features.h similarity index 67% rename from sysdeps/unix/sysv/linux/riscv/arch-fork.h rename to sysdeps/unix/sysv/linux/aarch64/kernel-features.h index f6f5d73..9cfa514 100644 --- a/sysdeps/unix/sysv/linux/riscv/arch-fork.h +++ b/sysdeps/unix/sysv/linux/aarch64/kernel-features.h @@ -1,5 +1,6 @@ -/* Internal definitions for thread-friendly fork implementation. Linux/RISC-V. - Copyright (C) 2002-2018 Free Software Foundation, Inc. +/* Set flags signalling availability of kernel features based on given + kernel version number. AArch64 version. + Copyright (C) 2018 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 @@ -16,11 +17,7 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include +#include_next -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ - NULL, NULL, &THREAD_SELF->tid) +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/alpha/arch-fork.h b/sysdeps/unix/sysv/linux/alpha/arch-fork.h deleted file mode 100644 index 41897dc..0000000 --- a/sysdeps/unix/sysv/linux/alpha/arch-fork.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. Alpha version. - Copyright (C) 2003-2018 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 -#include -#include -#include - - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, NULL, &THREAD_SELF->tid, NULL) diff --git a/sysdeps/unix/sysv/linux/arch-fork.h b/sysdeps/unix/sysv/linux/arch-fork.h index d5f5429..62bc23d 100644 --- a/sysdeps/unix/sysv/linux/arch-fork.h +++ b/sysdeps/unix/sysv/linux/arch-fork.h @@ -1,4 +1,4 @@ -/* ARCH_FORK definition for Linux fork implementation. Stub version. +/* arch_fork definition for Linux fork implementation. Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -16,12 +16,38 @@ License along with the GNU C Library; if not, see . */ -/* This file should define the function-like macro of no arguments - ARCH_FORK to an INLINE_SYSCALL invocation of the clone-like system - call, passing the CLONE_CHILD_SETTID and CLONE_CHILD_CLEARTID flags - and &THREAD_SELF->tid as the TID address. +#ifndef __ARCH_FORK_H +#define __ARCH_FORK_H - Machines that lack an arch-fork.h header file will hit an #error in - fork.c; this stub file doesn't contain an #error itself mainly for - the transition period of migrating old machine-specific fork.c files - to machine-specific arch-fork.h instead. */ +#include + +/* Call the clone syscall with fork semantic. The CTID address is used + to both store the child thread ID at its location and and erase it + in child memory when the child exits, and do a wakeup on the futex at + that address. + + The architecture with non-default kernel abi semantic should correctlly + override it with one of the supported calling convention (check generic + kernel-features.h for the clone abi variants). */ +static inline pid_t +arch_fork (void *ctid) +{ + const int flags = CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD; + long int ret; +#ifdef __ASSUME_CLONE_BACKWARDS + ret = INLINE_SYSCALL_CALL (clone, flags, 0, NULL, 0, ctid); +#elif defined(__ASSUME_CLONE_BACKWARDS2) + ret = INLINE_SYSCALL_CALL (clone, 0, flags, NULL, ctid, 0); +#elif defined(__ASSUME_CLONE_BACKWARDS3) + ret = INLINE_SYSCALL_CALL (clone, flags, 0, 0, NULL, ctid, 0); +#elif defined(__ASSUME_CLONE2) + ret = INLINE_SYSCALL_CALL (clone2, flags, 0, 0, NULL, ctid, 0); +#elif defined(__ASSUME_CLONE_DEFAULT) + ret = INLINE_SYSCALL_CALL (clone, flags, NULL, NULL, ctid, 0); +#else +# error "Undefined clone variant" +#endif + return ret; +} + +#endif /* __ARCH_FORK_H */ diff --git a/sysdeps/unix/sysv/linux/arm/arch-fork.h b/sysdeps/unix/sysv/linux/arm/arch-fork.h deleted file mode 100644 index ff3bc90..0000000 --- a/sysdeps/unix/sysv/linux/arm/arch-fork.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. ARM version. - Copyright (C) 2014-2018 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 -#include -#include - - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, NULL, NULL, &THREAD_SELF->tid) diff --git a/sysdeps/unix/sysv/linux/arm/kernel-features.h b/sysdeps/unix/sysv/linux/arm/kernel-features.h index f13632b..7831ab1 100644 --- a/sysdeps/unix/sysv/linux/arm/kernel-features.h +++ b/sysdeps/unix/sysv/linux/arm/kernel-features.h @@ -39,3 +39,6 @@ #define __ASSUME_RECV_SYSCALL 1 #define __ASSUME_SEND_SYSCALL 1 + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/createthread.c b/sysdeps/unix/sysv/linux/createthread.c index 5b5464a..5879e51 100644 --- a/sysdeps/unix/sysv/linux/createthread.c +++ b/sysdeps/unix/sysv/linux/createthread.c @@ -28,8 +28,9 @@ #include - -#ifndef ARCH_CLONE +#ifdef __NR_clone2 +# define ARCH_CLONE __clone2 +#else # define ARCH_CLONE __clone #endif diff --git a/sysdeps/unix/sysv/linux/hppa/arch-fork.h b/sysdeps/unix/sysv/linux/hppa/arch-fork.h deleted file mode 100644 index 7d52994..0000000 --- a/sysdeps/unix/sysv/linux/hppa/arch-fork.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. HPPA version. - Copyright (C) 2005-2018 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 -#include -#include -#include - -/* Argument 1 - Clone flags. - 2 - Child stack pointer. - 3 - Parent tid pointer. - 4 - New TLS area pointer. - 5 - Child tid pointer. */ -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, NULL, NULL, &THREAD_SELF->tid) diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h index 3f005a5..ef3c4dd 100644 --- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h +++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h @@ -32,3 +32,6 @@ #if __LINUX_KERNEL_VERSION < 0x040000 # undef __ASSUME_EXECVEAT #endif + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/i386/arch-fork.h b/sysdeps/unix/sysv/linux/i386/arch-fork.h deleted file mode 100644 index 0c43e2f..0000000 --- a/sysdeps/unix/sysv/linux/i386/arch-fork.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Internal definitions for thread-friendly fork implementation. Linux/i386. - Copyright (C) 2002-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2002. - - 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 -#include -#include - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ - NULL, NULL, &THREAD_SELF->tid) diff --git a/sysdeps/unix/sysv/linux/i386/kernel-features.h b/sysdeps/unix/sysv/linux/i386/kernel-features.h index 8708712..f3cfd48 100644 --- a/sysdeps/unix/sysv/linux/i386/kernel-features.h +++ b/sysdeps/unix/sysv/linux/i386/kernel-features.h @@ -48,3 +48,6 @@ /* i686 only supports ipc syscall. */ #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/ia64/arch-fork.h b/sysdeps/unix/sysv/linux/ia64/arch-fork.h deleted file mode 100644 index 522712e..0000000 --- a/sysdeps/unix/sysv/linux/ia64/arch-fork.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. IA64 version. - Copyright (C) 2003-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 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, see - . */ - -#include -#include -#include -#include - - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone2, 6, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, 0, NULL, &THREAD_SELF->tid, NULL) - -#define ARCH_CLONE __clone2 diff --git a/sysdeps/unix/sysv/linux/ia64/kernel-features.h b/sysdeps/unix/sysv/linux/ia64/kernel-features.h index cc3fe92..04cdf43 100644 --- a/sysdeps/unix/sysv/linux/ia64/kernel-features.h +++ b/sysdeps/unix/sysv/linux/ia64/kernel-features.h @@ -26,4 +26,7 @@ #define __ASSUME_SEND_SYSCALL 1 #define __ASSUME_ACCEPT4_SYSCALL 1 +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE2 + #endif /* _KERNEL_FEATURES_H */ diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 3aa2052..ca18f0b 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -115,3 +115,38 @@ #if __LINUX_KERNEL_VERSION >= 0x040500 # define __ASSUME_COPY_FILE_RANGE 1 #endif + +/* Support for clone call used on fork. The signature varies across the + architectures with current 4 different variants: + + 1. long int clone (unsigned long flags, unsigned long newsp, + int *parent_tidptr, unsigned long tls, + int *child_tidptr) + + 2. long int clone (unsigned long newsp, unsigned long clone_flags, + int *parent_tidptr, int * child_tidptr, + unsigned long tls) + + 3. long int clone (unsigned long flags, unsigned long newsp, + int stack_size, int *parent_tidptr, + int *child_tidptr, unsigned long tls) + + 4. long int clone (unsigned long flags, unsigned long newsp, + int *parent_tidptr, int *child_tidptr, + unsigned long tls) + + The fourth variant is intended to be used as the default for newer ports, + ALso IA64 uses the third variant but with __NR_clone2 instead of + __NR_clone. + + The macros names to define the variant used for the architecture is + similar to kernel: + + - __ASSUME_CLONE_BACKWARDS: for variant 1. + - __ASSUME_CLONE_BACKWARDS2: for variant 2 (s390). + - __ASSUME_CLONE_BACKWARDS3: for variant 3 (microblaze). + - __ASSUME_CLONE_DEFAULT: for variant 4. + - __ASSUME_CLONE2: for clone2 with variant 3 (ia64). + */ + +#define __ASSUME_CLONE_DEFAULT 1 diff --git a/sysdeps/unix/sysv/linux/m68k/arch-fork.h b/sysdeps/unix/sysv/linux/m68k/arch-fork.h deleted file mode 100644 index 20b6bab..0000000 --- a/sysdeps/unix/sysv/linux/m68k/arch-fork.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. m68k version. - Copyright (C) 2010-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Maxim Kuvyrkov , 2010. - - 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 -#include -#include -#include - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ - NULL, &THREAD_SELF->tid, NULL) diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-fork.h b/sysdeps/unix/sysv/linux/microblaze/arch-fork.h deleted file mode 100644 index 05ed4fa..0000000 --- a/sysdeps/unix/sysv/linux/microblaze/arch-fork.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. MicroBlaze version. - Copyright (C) 2014-2018 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 -#include -#include -#include - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ - NULL, NULL, &THREAD_SELF->tid) diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h index 745f899..b13b863 100644 --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h @@ -57,3 +57,6 @@ #if __LINUX_KERNEL_VERSION < 0x040A00 # undef __ASSUME_COPY_FILE_RANGE #endif + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS3 diff --git a/sysdeps/unix/sysv/linux/mips/arch-fork.h b/sysdeps/unix/sysv/linux/mips/arch-fork.h deleted file mode 100644 index 5f94537..0000000 --- a/sysdeps/unix/sysv/linux/mips/arch-fork.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/mips/kernel-features.h b/sysdeps/unix/sysv/linux/mips/kernel-features.h index 7756a34..a9009fb 100644 --- a/sysdeps/unix/sysv/linux/mips/kernel-features.h +++ b/sysdeps/unix/sysv/linux/mips/kernel-features.h @@ -47,3 +47,6 @@ #if _MIPS_SIM == _ABIN32 # define __ASSUME_WORDSIZE64_ILP32 1 #endif + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS diff --git a/sysdeps/unix/sysv/linux/nios2/arch-fork.h b/sysdeps/unix/sysv/linux/nios2/arch-fork.h deleted file mode 100644 index 6dacec2..0000000 --- a/sysdeps/unix/sysv/linux/nios2/arch-fork.h +++ /dev/null @@ -1,33 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. Nios II version. - Copyright (C) 2005-2018 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 -#include -#include -#include - -/* Argument 1 - Clone flags. - 2 - Child stack pointer. - 3 - Parent tid pointer. - 4 - Child tid pointer. - 5 - New TLS area pointer. */ - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, NULL, &THREAD_SELF->tid, NULL) diff --git a/sysdeps/unix/sysv/linux/powerpc/arch-fork.h b/sysdeps/unix/sysv/linux/powerpc/arch-fork.h deleted file mode 100644 index 5f94537..0000000 --- a/sysdeps/unix/sysv/linux/powerpc/arch-fork.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h index f3c02e6..503f562 100644 --- a/sysdeps/unix/sysv/linux/powerpc/kernel-features.h +++ b/sysdeps/unix/sysv/linux/powerpc/kernel-features.h @@ -49,3 +49,6 @@ /* powerpc only supports ipc syscall. */ #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-fork.h b/sysdeps/unix/sysv/linux/riscv/kernel-features.h similarity index 66% rename from sysdeps/unix/sysv/linux/aarch64/arch-fork.h rename to sysdeps/unix/sysv/linux/riscv/kernel-features.h index cab797e..37f4d99 100644 --- a/sysdeps/unix/sysv/linux/aarch64/arch-fork.h +++ b/sysdeps/unix/sysv/linux/riscv/kernel-features.h @@ -1,5 +1,6 @@ -/* ARCH_FORK definition for Linux fork implementation. AArch64 version. - Copyright (C) 2005-2018 Free Software Foundation, Inc. +/* Set flags signalling availability of kernel features based on given + kernel version number. RISC-V version. + Copyright (C) 2018 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 @@ -16,13 +17,7 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include +#include_next - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, NULL, NULL, &THREAD_SELF->tid) +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS 1 diff --git a/sysdeps/unix/sysv/linux/s390/arch-fork.h b/sysdeps/unix/sysv/linux/s390/arch-fork.h deleted file mode 100644 index 152b465..0000000 --- a/sysdeps/unix/sysv/linux/s390/arch-fork.h +++ /dev/null @@ -1,29 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. S390 version. - Copyright (C) 2003-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Martin Schwidefsky , 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, see - . */ - -#include -#include -#include -#include - - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - 0, CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - NULL, &THREAD_SELF->tid, NULL) diff --git a/sysdeps/unix/sysv/linux/s390/kernel-features.h b/sysdeps/unix/sysv/linux/s390/kernel-features.h index 3caca98..f718264 100644 --- a/sysdeps/unix/sysv/linux/s390/kernel-features.h +++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h @@ -50,3 +50,6 @@ /* s390 only supports ipc syscall. */ #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + +#undef __ASSUME_CLONE_DEFAULT +#define __ASSUME_CLONE_BACKWARDS2 diff --git a/sysdeps/unix/sysv/linux/sh/arch-fork.h b/sysdeps/unix/sysv/linux/sh/arch-fork.h deleted file mode 100644 index a29f61c..0000000 --- a/sysdeps/unix/sysv/linux/sh/arch-fork.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. SH version. - Copyright (C) 2003-2018 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 -#include -#include -#include - -/* TLS pointer argument is passed as the 5-th argument. */ -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 5, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ - NULL, &THREAD_SELF->tid, NULL) diff --git a/sysdeps/unix/sysv/linux/sparc/arch-fork.h b/sysdeps/unix/sysv/linux/sparc/arch-fork.h deleted file mode 100644 index 03ccc9a..0000000 --- a/sysdeps/unix/sysv/linux/sparc/arch-fork.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. SPARC version. - Copyright (C) 2003-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 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, see - . */ - -#include -#include -#include -#include - -#define ARCH_FORK() \ - INLINE_CLONE_SYSCALL (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - 0, NULL, NULL, &THREAD_SELF->tid) diff --git a/sysdeps/unix/sysv/linux/tile/arch-fork.h b/sysdeps/unix/sysv/linux/tile/arch-fork.h deleted file mode 100644 index d0526d8..0000000 --- a/sysdeps/unix/sysv/linux/tile/arch-fork.h +++ /dev/null @@ -1,29 +0,0 @@ -/* ARCH_FORK definition for Linux fork implementation. Tile* version. - Copyright (C) 2011-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Chris Metcalf , 2011. - Based on work contributed by Ulrich Drepper , 2002. - - 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 -#include -#include -#include - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 4, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ - 0, NULL, &THREAD_SELF->tid) diff --git a/sysdeps/unix/sysv/linux/x86_64/arch-fork.h b/sysdeps/unix/sysv/linux/x86_64/arch-fork.h deleted file mode 100644 index 4471970..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/arch-fork.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Internal definitions for thread-friendly fork implementation. Linux/x86_64. - Copyright (C) 2003-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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, see - . */ - -#include -#include -#include - -#define ARCH_FORK() \ - INLINE_SYSCALL (clone, 4, \ - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ - NULL, &THREAD_SELF->tid) From patchwork Wed Feb 7 13:09:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 127176 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp456146ljc; Wed, 7 Feb 2018 05:10:04 -0800 (PST) X-Google-Smtp-Source: AH8x225kjc5e8zacyqPZxAddbRPIHAtWzp8P/hVeWwbNyprVUXp608CUBwsyO63L5wRziboCPuZ7 X-Received: by 10.98.157.93 with SMTP id i90mr6074322pfd.58.1518009004789; Wed, 07 Feb 2018 05:10:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518009004; cv=none; d=google.com; s=arc-20160816; b=bKfXDELTWJvayCBKBDKLoYTzhHLy6A4j9vJ1AlEzoN4CFay/jT3yj+ljNzGCXA1TfN ASqhg/I/5puXCrogua7ZiTyNoZSvMBGksc6Fey1CPsZCVIMOKGp4vYwiJYhYOGlilnLF Z/OHtoFblDjHmclheZ8xkZpNecerhbUflWJ5NEOIeGretRYjwHWqmRGhb/oTbULTTMhA S1aziGl94BxsM4Roz1OLxRXMMxZbtyGIR5GKjDn1nKbjQKbfekmnCZe7Iu5dHMIuVcVK AI19qhKy5MnKU5GXJNx19t2X69jJKC9zOV7infneLabuUxrltGGl+NrevEMcv26NGR5d 9oOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=Gtgx6DdVXOT8P5YuWoMXUXW48rQ0DFCN+cRkZ/iYOhg=; b=lp67ybJMTJ25b74Ir69dF3KxSUdQPf9WXprtBVMshgtw+KMnXgVxxfEB48fE1l0NMm EL0r96wVsJX1oAH1GOncyOFx4B5qHmg+V09WX7JYWyAqramDWYMNYEYbWfsJtZDGcern 66pSAxUhSqwhOiVleCaMRQrnZlXl9BzaZL3E+cfvmOFp1pKE0d+SST6SZxeUcKKxbEaM SXWXTXZ4/77fIOGuV4FKeBsdH4dfcUnAVe/Xkh69NS6OPPCdrB0IEsfEESsByB/SjBX1 gyy4t8QxfqcQpPPwQP3EvoIZg3hXZNrPrNPYYZh471KtS2Eos+7RFiGZdoqtLeDJZnUN +HUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=q0Mw0RTS; spf=pass (google.com: domain of libc-alpha-return-90099-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90099-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id v8si918614pgc.724.2018.02.07.05.10.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Feb 2018 05:10:04 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90099-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=q0Mw0RTS; spf=pass (google.com: domain of libc-alpha-return-90099-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90099-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=lK6jl700S7WaPTgA6xmZgyMU1blIyFI +ruCBe5BW9hyhymPqEvMnzABuXZAX1SX9bWLOH/9iBohMSD63kJd7BTeCeAw8sVE pZyoZFV2TIev/ZgUpt9uAD7Q3o4YMyCJeDr1SVfIiVsmJwF/ME2tC25pA1Wf71VL yUiWBNF0Qpac= 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:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=kFXmskt7S9cAJhGoQgUpcIkwn74=; b=q0Mw0 RTSGu91eqPb451zDZAfu5l58holeUmtJ8SL0Xl8eipOBf7brXnDqxb3m75Wcuv3q j9XI47e43/6AynE4+hBzLamS4wsxB00nwCgaDlvCiil8I7Yno9A/DPEuvsaKILOh EAZL8nQ5ZdkE14Cbh2XgmzNwZkZlnQIqZwUcRk= Received: (qmail 11993 invoked by alias); 7 Feb 2018 13:09:49 -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 11844 invoked by uid 89); 7 Feb 2018 13:09:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qk0-f195.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Gtgx6DdVXOT8P5YuWoMXUXW48rQ0DFCN+cRkZ/iYOhg=; b=gobuhXQ0rrmxZ871z0X7Bz5I6avDAcPBq/5+dYGm2tcVh1KxBKabcc7atk8+/9X5mb qLLIjhE1JmVefJx+E52P8nI43bfw2yLy0rG0jM7NJqANqJ54jPxPX89Rg8L6ZtmBJO1D ec9fs3hWDk7s4DHwS/t0Bzd/PGoyjQ9KZHcnWB6lDT1EQ0yROJ63WJED12mhIaGY6UV6 Q4boJiXQJM1wq6V/zPlgb9r/l3vTblvR6MVUD8PLO+F/NAkk+pnKvV3qklDj5RyXrvwo DwCFn6XQMHyUyPG6cXgEWJbWhU/vhJY3DyXtj4eFqZUsopBDkNRNZNxddPx8FYJopg5k uTuw== X-Gm-Message-State: APf1xPDkym7sWLPpRljz9bJ8GPj/hW5vwZEWCN3jDgrDVDf3nRVEsVxp cEp3AqfkytXICoMdPSNYS1mjO/CYxmM= X-Received: by 10.55.20.232 with SMTP id 101mr5110171qku.264.1518008979146; Wed, 07 Feb 2018 05:09:39 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 2/3] dynarray: Implement remove function Date: Wed, 7 Feb 2018 11:09:26 -0200 Message-Id: <1518008967-8310-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1518008967-8310-1-git-send-email-adhemerval.zanella@linaro.org> References: <1518008967-8310-1-git-send-email-adhemerval.zanella@linaro.org> This patch implements the remove item function for dynarray array. It is a costly operation, since it requires a memory move operation possible as large as the array size less one element. Checked on x86_64-linux-gnu. * malloc/dynarray-skeleton.c: List remove as defined function. ((DYNARRAY_PREFIX##remove): New function. * malloc/tst-dynarray.c (test_int): Add tests for remove function. (check_int, check_int_array): New functions. --- ChangeLog | 5 ++++ malloc/dynarray-skeleton.c | 23 +++++++++++++++++ malloc/tst-dynarray.c | 64 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 81 insertions(+), 11 deletions(-) -- 2.7.4 diff --git a/malloc/dynarray-skeleton.c b/malloc/dynarray-skeleton.c index 5ab4a19..619a750 100644 --- a/malloc/dynarray-skeleton.c +++ b/malloc/dynarray-skeleton.c @@ -72,6 +72,7 @@ DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *); bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t); void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *); + void DYNARRAY_PREFIX##remove (struct DYNARRAY_STRUCT *, size_t); void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *); The following functions are provided are provided if the @@ -428,6 +429,28 @@ DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list) } } +/* Remove the element of index IDX of LIST if it is present. */ +__attribute__ ((unused, nonnull (1))) +static void +DYNARRAY_NAME (remove) (struct DYNARRAY_STRUCT *list, size_t idx) +{ + size_t last_pos = list->dynarray_header.used; + if (idx + 1 == last_pos) + { + DYNARRAY_NAME (remove_last) (list); + return; + } + DYNARRAY_ELEMENT *elem = DYNARRAY_NAME (at) (list, idx); + DYNARRAY_ELEMENT *last = &list->dynarray_header.array[last_pos]; + + ptrdiff_t size_to_move = (uintptr_t)last - (uintptr_t)elem; +#ifdef DYNARRAY_ELEMENT_FREE + DYNARRAY_ELEMENT_FREE (elem); +#endif + memmove (elem, elem + 1, size_to_move); + list->dynarray_header.used--; +} + /* Remove all elements from the list. The elements are freed, but the list itself is not. */ __attribute__ ((unused, nonnull (1))) diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c index 0a5716b..c31b73d 100644 --- a/malloc/tst-dynarray.c +++ b/malloc/tst-dynarray.c @@ -55,6 +55,40 @@ struct long_array enum { max_count = 20 }; +static void +check_int (int do_remove, struct dynarray_int *dyn, unsigned int base, + unsigned int final_count, unsigned int to_remove) +{ + if (do_remove == 1) + for (unsigned int i = 0; i < final_count; ++i) + TEST_VERIFY_EXIT (*dynarray_int_at (dyn, i) == base + i); + else if (do_remove == 2) + { + unsigned int i; + for (i = 0; i < to_remove; ++i) + TEST_VERIFY_EXIT (*dynarray_int_at (dyn, i) == base + i); + for (i = to_remove; i < final_count; ++i) + TEST_VERIFY_EXIT (*dynarray_int_at (dyn, i) == base + i + 1); + } +} + +static void +check_int_array (int do_remove, struct int_array *result, unsigned int base, + unsigned int final_count, unsigned int to_remove) +{ + if (do_remove == 1) + for (unsigned int i = 0; i < final_count; ++i) + TEST_VERIFY_EXIT (result->array[i] == base + i); + else if (do_remove == 2) + { + unsigned int i; + for (i = 0; i < to_remove; ++i) + TEST_VERIFY_EXIT (result->array[i] == base + i); + for (i = to_remove; i < final_count; ++i) + TEST_VERIFY_EXIT (result->array[i] == base + i + 1); + } +} + /* Test dynamic arrays with int elements (no automatic deallocation for elements). */ static void @@ -84,15 +118,15 @@ test_int (void) do_add: Switch between emplace (false) and add (true). do_finalize: Perform finalize call at the end. do_clear: Perform clear call at the end. - do_remove_last: Perform remove_last call after adding elements. + do_remove: Perform remove_last or remove call after adding elements. count: Number of elements added to the array. */ for (int do_add = 0; do_add < 2; ++do_add) - for (int do_finalize = 0; do_finalize < 2; ++do_finalize) + for (int do_finalize = 1; do_finalize < 2; ++do_finalize) for (int do_clear = 0; do_clear < 2; ++do_clear) - for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last) - for (unsigned int count = 0; count < max_count; ++count) + for (int do_remove = 1; do_remove < 3; ++do_remove) + for (unsigned int count = 2; count < max_count; ++count) { - if (do_remove_last && count == 0) + if (do_remove && count == 0) continue; unsigned int base = count * count; struct dynarray_int dyn; @@ -123,7 +157,8 @@ test_int (void) } unsigned final_count; bool heap_array = dyn.dynarray_header.array != dyn.scratch; - if (do_remove_last) + size_t to_remove = dynarray_int_size (&dyn) / 2; + if (do_remove == 1) { dynarray_int_remove_last (&dyn); if (count == 0) @@ -131,7 +166,15 @@ test_int (void) else final_count = count - 1; } - else + else if (do_remove == 2) + { + dynarray_int_remove (&dyn, to_remove); + if (count == 0) + final_count = 0; + else + final_count = count - 1; + } + else final_count = count; if (final_count > 0) { @@ -151,8 +194,7 @@ test_int (void) TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count); TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count); if (!do_clear) - for (unsigned int i = 0; i < final_count; ++i) - TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i); + check_int (do_remove, &dyn, base, final_count, to_remove); if (do_finalize) { struct int_array result = { (int *) (uintptr_t) -1, -1 }; @@ -168,8 +210,8 @@ test_int (void) TEST_VERIFY_EXIT (malloc_usable_size (result.array) >= final_count * sizeof (result.array[0])); - for (unsigned int i = 0; i < final_count; ++i) - TEST_VERIFY_EXIT (result.array[i] == base + i); + check_int_array (do_remove, &result, base, final_count, + to_remove); free (result.array); } } From patchwork Wed Feb 7 13:09:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 127175 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp456014ljc; Wed, 7 Feb 2018 05:09:56 -0800 (PST) X-Google-Smtp-Source: AH8x225UERRUz6tBFDA7/g8hFRSbumS7OWCu4rXipmm/hClU9U5Gi/l0Qu/Q5FhX5jqFKRVPQFEW X-Received: by 10.101.70.12 with SMTP id v12mr4914590pgq.327.1518008995818; Wed, 07 Feb 2018 05:09:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518008995; cv=none; d=google.com; s=arc-20160816; b=WUhhmemdaLPbYlko1ILbd1srjIBhKrnKW6pq93V6kfYLy3SHvhu1jGnNNAgU8kn5ae qYx9ma7+NEVUyCKFcsFSyl+uh/0RZlMk15ZGyhKauMbHCn369mDwavrUzmTTMygdWnt/ 1W9S2yAfRa+aAmjp3wutHUSA4e5UfC+W1gf4GCqmqYOb8wqnEjcMgTsoo8CigxgMP/Aw jaIctv2bMYdxwYt3aR2o1XasEZKnn2LumVaZCpw8pOD6BZkQ6j6qzv6VneA/1z+risDL k+WpvgvV48iCJHMo0Mzcmq0xiGRGcroNkwMAOmuBdqFV4GuBa6GUryH5rCl5tvzBNqOc lK5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=9edXBXbg2bScVzHX7jIdfZ17LpPELNfZlpR5GQYg/wA=; b=rsIE630uLtb9U2CUYm62a8ru+cpuVM6dbV+tHGUO/MPBPUaRwkGlUA7PwJFsjZF92R VKquMeClrUKU1gJc2UWRjn+VGsaW9XYnuigRgwTOxKkOrJkP57s3ZMxgMAobY+4V2va1 t3kKRYsarAWIX3WK7OWA37oRV7NZK1KSdivoDmHHhsmHZ7KsYAPJMuPvsLYh6HCKZQxX 9cuNrnzk5tzlrUmMzaIa8lUoZu8C9PBjoxcIBjwyUe3OsCFQ10/u4RF8zGWzX6bveYYw uPcFYTEEErn3iUWwZJWbALEIX4+Odd90wjr+MmDXmcuONE7/4cUnyfsp34htV5OT96bl fDCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=OCsGCcKX; spf=pass (google.com: domain of libc-alpha-return-90098-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90098-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id x11si937337pgp.23.2018.02.07.05.09.55 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Feb 2018 05:09:55 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90098-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=OCsGCcKX; spf=pass (google.com: domain of libc-alpha-return-90098-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90098-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=FPS7rv8sXHxv8wW4XwX+hPal2VQhixh 7OSkU+TWVvwrTfwRuvAeELg5n1gjv9I0+P9WDKT/BtMB1rbtkLjl9rEc4GW9wmS/ pUteQ0f4k0njQd7a2z/VbQcpdjT0H25aUAVz9B9ZDst5s0ZrQdvz5V18U59Nc7Fd EtK8S/BvdXXU= 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:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=TmtwhLrxvin12KYoTnMmQ2g9Cio=; b=OCsGC cKXBqqu4zSkFuw+4iWILAav4Z6AX0UgNX/yHsXFqgRUmYIBH8DnonptDJ36JTxUa LIHmUYuL3QIbNJrbyFlQ85AaFpwZvrT8oPyhYOXgmnY3UvuQ+Am/71TFzKsPIbsU waheh84Tkusm3BPP3KhduX40P9Yzlas8I8O1hE= Received: (qmail 11506 invoked by alias); 7 Feb 2018 13:09:46 -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 11495 invoked by uid 89); 7 Feb 2018 13:09:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=WHO, acquires, preparation, trading X-HELO: mail-qk0-f172.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=9edXBXbg2bScVzHX7jIdfZ17LpPELNfZlpR5GQYg/wA=; b=q6RAtj8BOLD2JiM4K2lioDscbz0fL2JV6WOvzFQ90xZz3gcM29Oe+l/xJ58MKRtasR NvK5JAiVik9C0567jmsOBNLlbUQDY6boewQkuBM09hZYmtK8KJC7AEs8AGLj04N25BgX 3KMUnQyaYUMFkWPq46K58fd74LHKt9ZM8dcjZGG8Ds5SmcAq2t+Pjb41+rDUF/RTPYXj R1YOPcwDSeBm3Afd2mK2/Xd5f4oPe4FNxoCBjg1FcqlaMKqs8gE+rBCGk9SA4CFivZzg dE2onPlZxaRX+kSDA7nI4hFUjK76TdyYsTBYWNa9v4/NUSszLx1Pcrptnbtpnr0N0X+d rHtw== X-Gm-Message-State: APf1xPCrt99np/8LeUmkWXNHlAPILWCT+gWsaTefOBSg3DGUKLLgyJdS zs85Ok28NGtWWGPjrfboiX9U6Y+3SK8= X-Received: by 10.55.6.1 with SMTP id 1mr8769904qkg.38.1518008980445; Wed, 07 Feb 2018 05:09:40 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 3/3] Refactor atfork handlers Date: Wed, 7 Feb 2018 11:09:27 -0200 Message-Id: <1518008967-8310-3-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1518008967-8310-1-git-send-email-adhemerval.zanella@linaro.org> References: <1518008967-8310-1-git-send-email-adhemerval.zanella@linaro.org> Current implementation (sysdeps/nptl/fork.c) replicates the atfork handlers list backward to invoke the child handlers after fork/clone syscall. The internal atfork handlers is implemented as a single-linked list so a lock-free algorithm can be used, trading fork mulithread call performance for some code complexity and dynamic stack allocation (since the backwards list should not fail). This patch refactor it to use a dynarary instead of a linked list. It simplifies the external variables need to be exported and also the internal atfork handler member definition. The downside is a serialization of fork call in multithread, since to operate on the dynarray the internal lock should be used. However as noted by Florian, it already acquires external locks for malloc and libio so it is already hitting some lock contention. Besides, posix_spawn should be faster and more scalable to run external programs in multithread environments. Checked on x86_64-linux-gnu. * nptl/Makefile (routines): Remove unregister-atfork. * nptl/register-atfork.c (fork_handler_pool): Remove variable. (fork_handler_alloc): Remove function. (fork_handlers, fork_handler_init): New variables. (__fork_lock): Rename to atfork_lock. (__register_atforki, __unregister_atfork, libc_freeres_fn): Rewrite to use a dynamic array to add/remove atfork handlers. * sysdeps/nptl/fork.c (__libc_fork): Likewise. * sysdeps/nptl/fork.h (__fork_lock, __fork_handlers, __linkin_atfork): Remove declaration. (fork_handler): Remove next, refcntr, and need_signal member. (__run_fork_handler_type): New enum. (__run_fork_handlers): New prototype. * sysdeps/nptl/libc-lockP.h (__libc_atfork): Remove declaration. --- ChangeLog | 15 +++++ nptl/Makefile | 2 +- nptl/register-atfork.c | 146 +++++++++++++++++++--------------------------- sysdeps/nptl/fork.c | 96 +----------------------------- sysdeps/nptl/fork.h | 31 +++++----- sysdeps/nptl/libc-lockP.h | 2 - 6 files changed, 97 insertions(+), 195 deletions(-) -- 2.7.4 diff --git a/nptl/Makefile b/nptl/Makefile index 6fc2c8b..be7ee3e 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -30,7 +30,7 @@ install-lib-ldscripts := libpthread.so routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \ libc-cleanup libc_pthread_init libc_multiple_threads \ - register-atfork unregister-atfork pthread_self + register-atfork pthread_self shared-only-routines = forward # We need to provide certain routines for compatibility with existing diff --git a/nptl/register-atfork.c b/nptl/register-atfork.c index f309cec..0bc2fe9 100644 --- a/nptl/register-atfork.c +++ b/nptl/register-atfork.c @@ -22,123 +22,97 @@ #include #include +#define DYNARRAY_ELEMENT struct fork_handler +#define DYNARRAY_STRUCT fork_handler_list +#define DYNARRAY_PREFIX fork_handler_list_ +#define DYNARRAY_INITIAL_SIZE 48 +#include -struct fork_handler *__fork_handlers; - -/* Lock to protect allocation and deallocation of fork handlers. */ -int __fork_lock = LLL_LOCK_INITIALIZER; - - -/* Number of pre-allocated handler entries. */ -#define NHANDLER 48 - -/* Memory pool for fork handler structures. */ -static struct fork_handler_pool -{ - struct fork_handler_pool *next; - struct fork_handler mem[NHANDLER]; -} fork_handler_pool; - - -static struct fork_handler * -fork_handler_alloc (void) -{ - struct fork_handler_pool *runp = &fork_handler_pool; - struct fork_handler *result = NULL; - unsigned int i; - - do - { - /* Search for an empty entry. */ - for (i = 0; i < NHANDLER; ++i) - if (runp->mem[i].refcntr == 0) - goto found; - } - while ((runp = runp->next) != NULL); - - /* We have to allocate a new entry. */ - runp = (struct fork_handler_pool *) calloc (1, sizeof (*runp)); - if (runp != NULL) - { - /* Enqueue the new memory pool into the list. */ - runp->next = fork_handler_pool.next; - fork_handler_pool.next = runp; - - /* We use the last entry on the page. This means when we start - searching from the front the next time we will find the first - entry unused. */ - i = NHANDLER - 1; - - found: - result = &runp->mem[i]; - result->refcntr = 1; - result->need_signal = 0; - } - - return result; -} +static struct fork_handler_list fork_handlers; +static bool fork_handler_init = false; +static int atfork_lock = LLL_LOCK_INITIALIZER; int __register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void), void *dso_handle) { - /* Get the lock to not conflict with other allocations. */ - lll_lock (__fork_lock, LLL_PRIVATE); + lll_lock (atfork_lock, LLL_PRIVATE); - struct fork_handler *newp = fork_handler_alloc (); + if (!fork_handler_init) + { + fork_handler_list_init (&fork_handlers); + fork_handler_init = true; + } + struct fork_handler *newp = fork_handler_list_emplace (&fork_handlers); if (newp != NULL) { - /* Initialize the new record. */ newp->prepare_handler = prepare; newp->parent_handler = parent; newp->child_handler = child; newp->dso_handle = dso_handle; - - __linkin_atfork (newp); } /* Release the lock. */ - lll_unlock (__fork_lock, LLL_PRIVATE); + lll_unlock (atfork_lock, LLL_PRIVATE); return newp == NULL ? ENOMEM : 0; } libc_hidden_def (__register_atfork) - void -attribute_hidden -__linkin_atfork (struct fork_handler *newp) +__unregister_atfork (void *dso_handle) { - do - newp->next = __fork_handlers; - while (catomic_compare_and_exchange_bool_acq (&__fork_handlers, - newp, newp->next) != 0); -} + lll_lock (atfork_lock, LLL_PRIVATE); + for (size_t i = 0; i < fork_handler_list_size (&fork_handlers); i++) + if (fork_handler_list_at (&fork_handlers, i)->dso_handle == dso_handle) + { + fork_handler_list_remove (&fork_handlers, i); + break; + } -libc_freeres_fn (free_mem) + lll_unlock (atfork_lock, LLL_PRIVATE); +} + +void +__run_fork_handlers (enum __run_fork_handler_type who) { - /* Get the lock to not conflict with running forks. */ - lll_lock (__fork_lock, LLL_PRIVATE); + struct fork_handler *runp; - /* No more fork handlers. */ - __fork_handlers = NULL; + if (who == atfork_run_prepare) + { + lll_lock (atfork_lock, LLL_PRIVATE); + size_t sl = fork_handler_list_size (&fork_handlers); + for (size_t i = sl; i > 0; i--) + { + runp = fork_handler_list_at (&fork_handlers, i - 1); + if (runp->prepare_handler != NULL) + runp->prepare_handler (); + } + } + else + { + size_t sl = fork_handler_list_size (&fork_handlers); + for (size_t i = 0; i < sl; i++) + { + runp = fork_handler_list_at (&fork_handlers, i); + if (who == atfork_run_child && runp->child_handler) + runp->child_handler (); + else if (who == atfork_run_parent && runp->parent_handler) + runp->parent_handler (); + } + lll_unlock (atfork_lock, LLL_PRIVATE); + } +} - /* Free eventually allocated memory blocks for the object pool. */ - struct fork_handler_pool *runp = fork_handler_pool.next; - memset (&fork_handler_pool, '\0', sizeof (fork_handler_pool)); +libc_freeres_fn (free_mem) +{ + lll_lock (atfork_lock, LLL_PRIVATE); - /* Release the lock. */ - lll_unlock (__fork_lock, LLL_PRIVATE); + fork_handler_list_free (&fork_handlers); - /* We can free the memory after releasing the lock. */ - while (runp != NULL) - { - struct fork_handler_pool *oldp = runp; - runp = runp->next; - free (oldp); - } + lll_unlock (atfork_lock, LLL_PRIVATE); } diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c index 0061ee0..ec56a82 100644 --- a/sysdeps/nptl/fork.c +++ b/sysdeps/nptl/fork.c @@ -48,11 +48,6 @@ pid_t __libc_fork (void) { pid_t pid; - struct used_handler - { - struct fork_handler *handler; - struct used_handler *next; - } *allp = NULL; /* Determine if we are running multiple threads. We skip some fork handlers in the single-thread case, to make fork safer to use in @@ -60,60 +55,7 @@ __libc_fork (void) but our current fork implementation is not. */ bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads); - /* Run all the registered preparation handlers. In reverse order. - While doing this we build up a list of all the entries. */ - struct fork_handler *runp; - while ((runp = __fork_handlers) != NULL) - { - /* Make sure we read from the current RUNP pointer. */ - atomic_full_barrier (); - - unsigned int oldval = runp->refcntr; - - if (oldval == 0) - /* This means some other thread removed the list just after - the pointer has been loaded. Try again. Either the list - is empty or we can retry it. */ - continue; - - /* Bump the reference counter. */ - if (atomic_compare_and_exchange_bool_acq (&__fork_handlers->refcntr, - oldval + 1, oldval)) - /* The value changed, try again. */ - continue; - - /* We bumped the reference counter for the first entry in the - list. That means that none of the following entries will - just go away. The unloading code works in the order of the - list. - - While executing the registered handlers we are building a - list of all the entries so that we can go backward later on. */ - while (1) - { - /* Execute the handler if there is one. */ - if (runp->prepare_handler != NULL) - runp->prepare_handler (); - - /* Create a new element for the list. */ - struct used_handler *newp - = (struct used_handler *) alloca (sizeof (*newp)); - newp->handler = runp; - newp->next = allp; - allp = newp; - - /* Advance to the next handler. */ - runp = runp->next; - if (runp == NULL) - break; - - /* Bump the reference counter for the next entry. */ - atomic_increment (&runp->refcntr); - } - - /* We are done. */ - break; - } + __run_fork_handlers (atfork_run_prepare); /* If we are not running multiple threads, we do not have to preserve lock state. If fork runs from a signal handler, only @@ -192,29 +134,7 @@ __libc_fork (void) __rtld_lock_initialize (GL(dl_load_lock)); /* Run the handlers registered for the child. */ - while (allp != NULL) - { - if (allp->handler->child_handler != NULL) - allp->handler->child_handler (); - - /* Note that we do not have to wake any possible waiter. - This is the only thread in the new process. The count - may have been bumped up by other threads doing a fork. - We reset it to 1, to avoid waiting for non-existing - thread(s) to release the count. */ - allp->handler->refcntr = 1; - - /* XXX We could at this point look through the object pool - and mark all objects not on the __fork_handlers list as - unused. This is necessary in case the fork() happened - while another thread called dlclose() and that call had - to create a new list. */ - - allp = allp->next; - } - - /* Initialize the fork lock. */ - __fork_lock = LLL_LOCK_INITIALIZER; + __run_fork_handlers (atfork_run_child); } else { @@ -229,17 +149,7 @@ __libc_fork (void) } /* Run the handlers registered for the parent. */ - while (allp != NULL) - { - if (allp->handler->parent_handler != NULL) - allp->handler->parent_handler (); - - if (atomic_decrement_and_test (&allp->handler->refcntr) - && allp->handler->need_signal) - futex_wake (&allp->handler->refcntr, 1, FUTEX_PRIVATE); - - allp = allp->next; - } + __run_fork_handlers (atfork_run_parent); } return pid; diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h index f0330cc..6eab61c 100644 --- a/sysdeps/nptl/fork.h +++ b/sysdeps/nptl/fork.h @@ -24,29 +24,37 @@ extern unsigned long int __fork_generation attribute_hidden; /* Pointer to the fork generation counter in the thread library. */ extern unsigned long int *__fork_generation_pointer attribute_hidden; -/* Lock to protect allocation and deallocation of fork handlers. */ -extern int __fork_lock attribute_hidden; - /* Elements of the fork handler lists. */ struct fork_handler { - struct fork_handler *next; void (*prepare_handler) (void); void (*parent_handler) (void); void (*child_handler) (void); void *dso_handle; - unsigned int refcntr; - int need_signal; }; -/* The single linked list of all currently registered for handlers. */ -extern struct fork_handler *__fork_handlers attribute_hidden; - - /* Function to call to unregister fork handlers. */ extern void __unregister_atfork (void *dso_handle) attribute_hidden; #define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle) +enum __run_fork_handler_type +{ + atfork_run_prepare, + atfork_run_child, + atfork_run_parent +}; + +/* Run the atfork handlers and lock/unlock the internal lock depending + of the WHO argument: + + - atfork_run_prepare: run all the PREPARE_HANDLER in reverse order of + insertion and locks the internal lock. + - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal + lock. + - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal + lock. */ +extern void __run_fork_handlers (enum __run_fork_handler_type who) + attribute_hidden; /* C library side function to register new fork handlers. */ extern int __register_atfork (void (*__prepare) (void), @@ -54,6 +62,3 @@ extern int __register_atfork (void (*__prepare) (void), void (*__child) (void), void *dso_handle); libc_hidden_proto (__register_atfork) - -/* Add a new element to the fork list. */ -extern void __linkin_atfork (struct fork_handler *newp) attribute_hidden; diff --git a/sysdeps/nptl/libc-lockP.h b/sysdeps/nptl/libc-lockP.h index 8539bbf..989fefa 100644 --- a/sysdeps/nptl/libc-lockP.h +++ b/sysdeps/nptl/libc-lockP.h @@ -319,8 +319,6 @@ __libc_cleanup_routine (struct __pthread_cleanup_frame *f) /* Register handlers to execute before and after `fork'. Note that the last parameter is NULL. The handlers registered by the libc are never removed so this is OK. */ -#define __libc_atfork(PREPARE, PARENT, CHILD) \ - __register_atfork (PREPARE, PARENT, CHILD, NULL) extern int __register_atfork (void (*__prepare) (void), void (*__parent) (void), void (*__child) (void),