From patchwork Mon Dec 7 21:27:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1412224 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=rjyBA+G3; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cqbyk5b3mz9sWH for ; Tue, 8 Dec 2020 08:28:30 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EC12D3943540; Mon, 7 Dec 2020 21:28:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EC12D3943540 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1607376495; bh=MhMiiC4KKLtEv+F5BHMQFzDz+2WXwHbgzzeF0upExfE=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=rjyBA+G3wnNsykmrrT1CM44/mUtYnPjm28VTeT5D2UmGi01RB3cv6bQkQwDj/MgsG EJ5UZb5+YFNDN8AtlLnVIqbrbX0A5aWGio7fSefDo8UfvAGjLjnDFOOxRrHryPSu2Z J0LWx5Z4BFMfMTFSuYvjcAVZtaaAMaHyWRd4M7tM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x743.google.com (mail-qk1-x743.google.com [IPv6:2607:f8b0:4864:20::743]) by sourceware.org (Postfix) with ESMTPS id 21B2A393BC09 for ; Mon, 7 Dec 2020 21:28:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 21B2A393BC09 Received: by mail-qk1-x743.google.com with SMTP id y18so14112902qki.11 for ; Mon, 07 Dec 2020 13:28:11 -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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MhMiiC4KKLtEv+F5BHMQFzDz+2WXwHbgzzeF0upExfE=; b=DycLvv1b799q7q3csgq1wYL3BU9hKWmGOtosyyPdi2JNtccTAN+gt2Jc/q+N5XPXwE 97gvyfIQJuakfDsclJptWXeF5Tewmw+XregaN2E6fDJugIGxCwaXbNJDi5NMqF7W/s4H fiuumkSYB+DsN+LwdGyBO11om8dDZc9iU68pOMyFTtiyUPkTPdF5WQ0+wZ2W8Gf/dgYS 6CewtanwkC7iPIxzgNC1AkTHu0BiJ5e/DSuu7ixfMzLV+tR3uV8MpYSM9/ShjYjQqfnC RES9mz5XWEdvsiPRJPyVnBoJxmhyvC3oDtWa10vTawtoC5cT/Q1BFBmQyKV9KAWJkuT6 8/Qw== X-Gm-Message-State: AOAM533dsMorJeegLWsUqa4VXEPBphiH/AjuSmd4WDre0ZfWXLcxZaw6 9R/sL+8BzvnmVwkUCGB2TGFLB2Vjkkv2fQ== X-Google-Smtp-Source: ABdhPJzlcVKxJntgDtwajai71IDbGEHZlwFR3Lpy6CqbufEc2gwlRD3MqyWOZJ3nJ47gLpJnBXUcOA== X-Received: by 2002:a37:4f4e:: with SMTP id d75mr27434028qkb.284.1607376490395; Mon, 07 Dec 2020 13:28:10 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id o29sm12832317qtl.7.2020.12.07.13.28.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Dec 2020 13:28:10 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v2 5/8] nptl: Implement raise in terms of pthread_kill Date: Mon, 7 Dec 2020 18:27:54 -0300 Message-Id: <20201207212757.3948164-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201207212757.3948164-1-adhemerval.zanella@linaro.org> References: <20201207212757.3948164-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 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, URIBL_BLACK 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 Cc: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Changes from previous version: * Handle vfork usage for raise and obtain the TID using a syscall instead of reading from TCB. --- Now that pthread_kill is provided by libc.so and async-signal-safe, it is possible to implement the generic POSIX implementation as pthread_kill(pthread_self(), sig). For Linux implementation, pthread_kill read the targetting TID from the TCB. For raise, this it not possible because it would make raise fail when issue after vfork (where creates the resulting process has a different TID from the parent, but its TCB is not updated as for pthread_create). For this case, gettid is called directly. Checked on x86_64-linux-gnu. --- include/pthread.h | 5 ++++ nptl/pthreadP.h | 4 +-- nptl/pthread_kill.c | 40 +++++++++++++------------ nptl/pthread_self.c | 4 ++- sysdeps/htl/pthreadP.h | 2 -- sysdeps/posix/raise.c | 11 +++++-- sysdeps/unix/sysv/linux/raise.c | 52 --------------------------------- 7 files changed, 41 insertions(+), 77 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/raise.c diff --git a/include/pthread.h b/include/pthread.h index 858c869a16..2623fb5e95 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -13,4 +13,9 @@ extern int __pthread_barrier_wait (pthread_barrier_t *__barrier) /* This function is called to initialize the pthread library. */ extern void __pthread_initialize (void) __attribute__ ((weak)); + +extern int __pthread_kill (pthread_t threadid, int signo); + +extern pthread_t __pthread_self (void); + #endif diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index a7510f9f63..968adcdb6a 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -521,11 +521,11 @@ extern int __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)); extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void)); -extern pthread_t __pthread_self (void); +libc_hidden_proto (__pthread_self) extern int __pthread_equal (pthread_t thread1, pthread_t thread2); extern int __pthread_detach (pthread_t th); extern int __pthread_cancel (pthread_t th); -extern int __pthread_kill (pthread_t threadid, int signo); +libc_hidden_proto (__pthread_kill) extern void __pthread_exit (void *value) __attribute__ ((__noreturn__)); extern int __pthread_join (pthread_t threadid, void **thread_return); extern int __pthread_setcanceltype (int type, int *oldtype); diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c index 006322ea9f..cf12fa743f 100644 --- a/nptl/pthread_kill.c +++ b/nptl/pthread_kill.c @@ -30,28 +30,32 @@ __pthread_kill (pthread_t threadid, int signo) sigset_t set; __libc_signal_block_all (&set); - int val; - - /* Force load of pd->tid into local variable or register. Otherwise - if a thread exits between ESRCH test and tgkill, we might return - EINVAL, because pd->tid would be cleared by the kernel. */ + pid_t tid; struct pthread *pd = (struct pthread *) threadid; - pid_t tid = atomic_forced_read (pd->tid); - if (__glibc_unlikely (tid <= 0)) - /* Not a valid thread handle. */ - val = ESRCH; - else - { - /* We have a special syscall to do the work. */ - pid_t pid = __getpid (); - val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); - val = (INTERNAL_SYSCALL_ERROR_P (val) - ? INTERNAL_SYSCALL_ERRNO (val) : 0); - } + if (pd == THREAD_SELF) + tid = INLINE_SYSCALL_CALL (gettid); + else + /* Force load of pd->tid into local variable or register. Otherwise + if a thread exits between ESRCH test and tgkill, we might return + EINVAL, because pd->tid would be cleared by the kernel. */ + tid = atomic_forced_read (pd->tid); + + int val; + if (__glibc_likely (tid > 0)) + { + pid_t pid = __getpid (); + + val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); + val = (INTERNAL_SYSCALL_ERROR_P (val) + ? INTERNAL_SYSCALL_ERRNO (val) : 0); + } + else + val = ESRCH; __libc_signal_restore_set (&set); return val; } -strong_alias (__pthread_kill, pthread_kill) +libc_hidden_def (__pthread_kill) +weak_alias (__pthread_kill, pthread_kill) diff --git a/nptl/pthread_self.c b/nptl/pthread_self.c index 00a8474909..4fab462bbf 100644 --- a/nptl/pthread_self.c +++ b/nptl/pthread_self.c @@ -20,7 +20,9 @@ #include pthread_t -pthread_self (void) +__pthread_self (void) { return (pthread_t) THREAD_SELF; } +libc_hidden_def (__pthread_self) +weak_alias (__pthread_self, pthread_self) diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h index bf00f7d2f0..befe18b421 100644 --- a/sysdeps/htl/pthreadP.h +++ b/sysdeps/htl/pthreadP.h @@ -31,8 +31,6 @@ extern void __pthread_init_static_tls (struct link_map *) attribute_hidden; /* These represent the interface used by glibc itself. */ -extern pthread_t __pthread_self (void); -extern int __pthread_kill (pthread_t threadid, int signo); extern struct __pthread **__pthread_threads; extern int __pthread_mutex_init (pthread_mutex_t *__mutex, const pthread_mutexattr_t *__attr); diff --git a/sysdeps/posix/raise.c b/sysdeps/posix/raise.c index 32cb108f0b..586116fc1c 100644 --- a/sysdeps/posix/raise.c +++ b/sysdeps/posix/raise.c @@ -16,13 +16,20 @@ . */ #include -#include +#include +#include /* Raise the signal SIG. */ int raise (int sig) { - return __kill (__getpid (), sig); + int ret = __pthread_kill (__pthread_self (), sig); + if (ret != 0) + { + __set_errno (ret); + ret = -1; + } + return ret; } libc_hidden_def (raise) weak_alias (raise, gsignal) diff --git a/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c deleted file mode 100644 index 3b90ae1d55..0000000000 --- a/sysdeps/unix/sysv/linux/raise.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2002-2020 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 -#include -#include -#include - -int -raise (int sig) -{ - /* rt_sigprocmask may fail if: - - 1. sigsetsize != sizeof (sigset_t) (EINVAL) - 2. a failure in copy from/to user space (EFAULT) - 3. an invalid 'how' operation (EINVAL) - - The first case is already handle in glibc syscall call by using the arch - defined _NSIG. Second case is handled by using a stack allocated mask. - The last one should be handled by the block/unblock functions. */ - - sigset_t set; - __libc_signal_block_app (&set); - - pid_t pid = INTERNAL_SYSCALL_CALL (getpid); - pid_t tid = INTERNAL_SYSCALL_CALL (gettid); - - int ret = INLINE_SYSCALL_CALL (tgkill, pid, tid, sig); - - __libc_signal_restore_set (&set); - - return ret; -} -libc_hidden_def (raise) -weak_alias (raise, gsignal)