From patchwork Tue Feb 2 15:11:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 41899 X-Patchwork-Delegate: azanella@linux.vnet.ibm.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E094398B15D; Tue, 2 Feb 2021 15:11:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0E094398B15D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1612278707; bh=GF3GtWZIiCz15BI8O90OxHdKgDcIewq9KJir9lZwvqs=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=AIKjQVIbFkZ0ZG4W9h+J2t8kMbYcntunf2kuRlT1Oj5r6uMPM/51z0SbFjWsMUmbm VFMEUN6tk63fzGuBovHco2WZTM/LJo3Py5kf2yCpFvR2RO3rFNi/6YKAWiAPy/7dcl VXqWrUu6fkM1pA4Koe1kPe9jk+6fNOWHn+0aeVjQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x82f.google.com (mail-qt1-x82f.google.com [IPv6:2607:f8b0:4864:20::82f]) by sourceware.org (Postfix) with ESMTPS id F22A9398B14A for ; Tue, 2 Feb 2021 15:11:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org F22A9398B14A Received: by mail-qt1-x82f.google.com with SMTP id t14so15095654qto.8 for ; Tue, 02 Feb 2021 07:11:42 -0800 (PST) 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:mime-version :content-transfer-encoding; bh=GF3GtWZIiCz15BI8O90OxHdKgDcIewq9KJir9lZwvqs=; b=a2vGcMHBy+5iwq8ENeriNZBhwk/3nNiNgfzHDmuIt/LJbwZR2Xm8Mxo+3viYxXVQHT G9RjerQEJLzUuzOBswBMpjgO4W+F24kvoFdNCYaORW7j03/B1mPqGA3P66jimhp1UG4y OCFeexpteTZ69siQK7tKpTFF0buI8lGDBZ7NPAE0pmCe3Ig4kiRExBPQC6nvKIieBlcY vfKGuPKJ3kTZE/S73WwDhexmcFzHzrHKQpgyS1YwKwt39aoXCybvcYIJq1ToHg86AgRk 3iWYqEA62lKpVkbnhbDx3oJptnO52DHpfiWXg6CxaqBea7Yvovjl1AMMDLEom4xPRgt2 cyug== X-Gm-Message-State: AOAM5311RhWoyvCTEx3L/O9NUZjlFINnBwKZXyzl6CffQRB1ZeqGSy9k 8TU0nQlVF8cW0nf9iR6XnB5K5SZT5Wb5MA== X-Google-Smtp-Source: ABdhPJx2fwrRlzWet/pDwmpFWHbd56mFSsQqagS7N/w2VJGJA67Hl+7hlkPYdkgxiRSSau3dJohP7Q== X-Received: by 2002:ac8:5786:: with SMTP id v6mr712160qta.200.1612278699709; Tue, 02 Feb 2021 07:11:39 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id z20sm16617267qki.93.2021.02.02.07.11.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Feb 2021 07:11:39 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 1/8] posix: Consolidate register-atfork Date: Tue, 2 Feb 2021 12:11:27 -0300 Message-Id: <20210202151134.2123748-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Spam-Status: No, score=-13.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Both htl and nptl uses a different data structure to implement atfork handlers. The nptl one was refactored by 27761a1042d to use a dynarray which simplifies the code. This patch moves the nptl one to be the generic implementation and replace Hurd linked one. Different than previous NPTL, Hurd also uses a global lock, so performance should be similar. Checked on x86_64-linux-gnu, i686-linux-gnu, and with a build for i686-gnu. --- htl/Makefile | 2 +- htl/register-atfork.c | 157 ------------------------------ include/register-atfork.h | 63 ++++++++++++ nptl/Makefile | 1 - posix/Makefile | 2 +- {nptl => posix}/register-atfork.c | 8 +- sysdeps/mach/hurd/fork.c | 15 +-- sysdeps/nptl/fork.h | 42 +------- 8 files changed, 73 insertions(+), 217 deletions(-) delete mode 100644 htl/register-atfork.c create mode 100644 include/register-atfork.h rename {nptl => posix}/register-atfork.c (97%) diff --git a/htl/Makefile b/htl/Makefile index 38d9f8c590..2dfe19c17f 100644 --- a/htl/Makefile +++ b/htl/Makefile @@ -166,7 +166,7 @@ headers := \ distribute := -routines := forward libc_pthread_init alloca_cutoff register-atfork pt-atfork +routines := forward libc_pthread_init alloca_cutoff pt-atfork shared-only-routines = forward static-only-routines = pt-atfork diff --git a/htl/register-atfork.c b/htl/register-atfork.c deleted file mode 100644 index 8be132f981..0000000000 --- a/htl/register-atfork.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Atfork handling. Hurd pthread version. - Copyright (C) 2002-2021 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 - -struct atfork -{ - void (*prepare) (void); - void (*parent) (void); - void (*child) (void); - void *dso_handle; - struct atfork *prev; - struct atfork *next; -}; - -/* TODO: better locking */ -__libc_lock_define_initialized (static, atfork_lock); -static struct atfork *fork_handlers, *fork_last_handler; - -static void -atfork_pthread_prepare (void) -{ - struct atfork *handlers, *last_handler; - - __libc_lock_lock (atfork_lock); - handlers = fork_handlers; - last_handler = fork_last_handler; - __libc_lock_unlock (atfork_lock); - - if (last_handler == NULL) - return; - - while (1) - { - if (last_handler->prepare != NULL) - last_handler->prepare (); - if (last_handler == handlers) - break; - last_handler = last_handler->prev; - } -} -text_set_element (_hurd_atfork_prepare_hook, atfork_pthread_prepare); - -static void -atfork_pthread_parent (void) -{ - struct atfork *handlers; - - __libc_lock_lock (atfork_lock); - handlers = fork_handlers; - __libc_lock_unlock (atfork_lock); - - while (handlers != NULL) - { - if (handlers->parent != NULL) - handlers->parent (); - handlers = handlers->next; - } -} -text_set_element (_hurd_atfork_parent_hook, atfork_pthread_parent); - -static void -atfork_pthread_child (void) -{ - struct atfork *handlers; - - __libc_lock_lock (atfork_lock); - handlers = fork_handlers; - __libc_lock_unlock (atfork_lock); - - while (handlers != NULL) - { - if (handlers->child != NULL) - handlers->child (); - handlers = handlers->next; - } -} -text_set_element (_hurd_atfork_child_hook, atfork_pthread_child); - -int -__register_atfork (void (*prepare) (void), - void (*parent) (void), - void (*child) (void), - void *dso_handle) -{ - struct atfork *new = malloc (sizeof (*new)); - if (new == NULL) - return errno; - - new->prepare = prepare; - new->parent = parent; - new->child = child; - new->dso_handle = dso_handle; - new->next = NULL; - - __libc_lock_lock (atfork_lock); - new->prev = fork_last_handler; - if (fork_last_handler != NULL) - fork_last_handler->next = new; - if (fork_handlers == NULL) - fork_handlers = new; - fork_last_handler = new; - __libc_lock_unlock (atfork_lock); - - return 0; -} -libc_hidden_def (__register_atfork) - -void -__unregister_atfork (void *dso_handle) -{ - struct atfork **handlers, *prev = NULL, *next; - __libc_lock_lock (atfork_lock); - handlers = &fork_handlers; - while (*handlers != NULL) - { - if ((*handlers)->dso_handle == dso_handle) - { - /* Drop this handler from the list. */ - if (*handlers == fork_last_handler) - { - /* Was last, new last is prev, if any. */ - fork_last_handler = prev; - } - - next = (*handlers)->next; - if (next != NULL) - next->prev = prev; - *handlers = next; - } - else - { - /* Just proceed to next handler. */ - prev = *handlers; - handlers = &prev->next; - } - } - __libc_lock_unlock (atfork_lock); -} diff --git a/include/register-atfork.h b/include/register-atfork.h new file mode 100644 index 0000000000..fadde14700 --- /dev/null +++ b/include/register-atfork.h @@ -0,0 +1,63 @@ +/* Internal pthread_atfork definitions. + Copyright (C) 2021 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 + . */ + +#ifndef _REGISTER_ATFORK_H +#define _REGISTER_ATFORK_H + +/* Elements of the fork handler lists. */ +struct fork_handler +{ + void (*prepare_handler) (void); + void (*parent_handler) (void); + void (*child_handler) (void); + void *dso_handle; +}; + +/* 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. + + Perform locking only if DO_LOCKING. */ +extern void __run_fork_handlers (enum __run_fork_handler_type who, + _Bool do_locking) attribute_hidden; + +/* C library side function to register new fork handlers. */ +extern int __register_atfork (void (*__prepare) (void), + void (*__parent) (void), + void (*__child) (void), + void *dso_handle); +libc_hidden_proto (__register_atfork) + +#endif diff --git a/nptl/Makefile b/nptl/Makefile index 0282e07390..85645d9dab 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -68,7 +68,6 @@ routines = \ pthread_self \ pthread_setschedparam \ pthread_sigmask \ - register-atfork \ shared-only-routines = forward static-only-routines = pthread_atfork diff --git a/posix/Makefile b/posix/Makefile index 956ef7d397..b7d92a5cc9 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -39,7 +39,7 @@ routines := \ times \ wait waitpid wait3 wait4 waitid \ alarm sleep pause nanosleep \ - fork vfork _exit \ + fork vfork _exit register-atfork \ execve fexecve execv execle execl execvp execlp execvpe \ getpid getppid \ getuid geteuid getgid getegid getgroups setuid setgid group_member \ diff --git a/nptl/register-atfork.c b/posix/register-atfork.c similarity index 97% rename from nptl/register-atfork.c rename to posix/register-atfork.c index 30c16fba40..6fd9e4c56a 100644 --- a/nptl/register-atfork.c +++ b/posix/register-atfork.c @@ -16,11 +16,9 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include -#include +#include +#include +#include #define DYNARRAY_ELEMENT struct fork_handler #define DYNARRAY_STRUCT fork_handler_list diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index fb6c7ee8b7..436d741f32 100644 --- a/sysdeps/mach/hurd/fork.c +++ b/sysdeps/mach/hurd/fork.c @@ -29,6 +29,7 @@ #include #include #include +#include #undef __fork @@ -36,12 +37,6 @@ /* Things that want to be locked while forking. */ symbol_set_declare (_hurd_fork_locks) - -/* Application callbacks registered through pthread_atfork. */ -DEFINE_HOOK (_hurd_atfork_prepare_hook, (void)); -DEFINE_HOOK (_hurd_atfork_child_hook, (void)); -DEFINE_HOOK (_hurd_atfork_parent_hook, (void)); - /* Things that want to be called before we fork, to prepare the parent for task_create, when the new child task will inherit our address space. */ DEFINE_HOOK (_hurd_fork_prepare_hook, (void)); @@ -71,7 +66,7 @@ __fork (void) struct hurd_sigstate *volatile ss; struct nss_database_data nss_database_data; - RUN_HOOK (_hurd_atfork_prepare_hook, ()); + __run_fork_handlers (atfork_run_prepare, true); ss = _hurd_self_sigstate (); __spin_lock (&ss->critical_section_lock); @@ -723,10 +718,8 @@ __fork (void) if (!err) { - if (pid != 0) - RUN_HOOK (_hurd_atfork_parent_hook, ()); - else - RUN_HOOK (_hurd_atfork_child_hook, ()); + __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent, + true); } return err ? __hurd_fail (err) : pid; diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h index 25002287b1..5246754290 100644 --- a/sysdeps/nptl/fork.h +++ b/sysdeps/nptl/fork.h @@ -17,50 +17,10 @@ . */ #include +#include /* The fork generation counter, defined in libpthread. */ 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; - -/* Elements of the fork handler lists. */ -struct fork_handler -{ - void (*prepare_handler) (void); - void (*parent_handler) (void); - void (*child_handler) (void); - void *dso_handle; -}; - -/* 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. - - Perform locking only if DO_LOCKING. */ -extern void __run_fork_handlers (enum __run_fork_handler_type who, - _Bool do_locking) attribute_hidden; - -/* C library side function to register new fork handlers. */ -extern int __register_atfork (void (*__prepare) (void), - void (*__parent) (void), - void (*__child) (void), - void *dso_handle); -libc_hidden_proto (__register_atfork)