From patchwork Tue Jun 25 00:09:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 33377 Received: (qmail 20057 invoked by alias); 25 Jun 2019 00:11:41 -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 19983 invoked by uid 89); 25 Jun 2019 00:11:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy= X-HELO: esa1.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1561421498; x=1592957498; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RGmySVi3f1ofxu8KAhiP9wsrACXKIyQkTt2j+npPzXc=; b=UDSBVyWGhfPGUBPT4nLuroamquz35qSyKSB7CTKX7SQsL5SzBnyZt8FP vvNxikzb3vpHcqLHHQp3yjiNkACqL8iWNPMIKy6LjyGQmpHYIiZBmZjMR t4UeNQ6b0dXvOXzUXeVvSaOscq8svNx4QiBeVTa3wxoY3cU4q3aiEnbFQ ibgBpnZ52esyCLZULm3/+nKzJ1mOzkuulORD44RreVpZMA4FgF9JFoI4q Nc3qO8EX6W8QsYKUdVZkP+jwEbwtxA67f7A3Fr2xFQm9qY/g8r1o08JLk 6wSYO8r/7KcbqP1Geo3YBA/gYFTJVDugVrWRTydWR3jcXzvBYJcBkPI4s w==; IronPort-SDR: Q9FU8/VnrfHhvy8G9EcWT15OzkLz0oUhsGorP8n0aMCYL4F0sjrdo9vpc2BA2Nhkuia7yfe8Vm KOZKpg2nrr/FH9GHVbIu396SkpYH7sxQLb//ayFAI0VFy0dPePenTNIR+iSffMzTWjGp/tbuFb uLUJox8vZJWnNmohRE3jE2++ESArsPDbkGPoY2qYq1uLJEhXfko5g13wPFReqO/ro9wzAwnour BdbAfBvw3rs/yhxwDsuQji9tbsrGv0UCBORn5GJT4M+vIwdV+LSoQax8l17FQp+evAau1DA7Kz hUc+aWScN/bgNStkweXBQ8q4 IronPort-SDR: CPv+H22KMzEakC1zUpIQlOO4l20z/H2j7z1s4LcLYK3b/RDez7SYf70Wat3cC6qOIMLXC6jvtC BnlIMZdQCbQVRG/UDwSAmKrLbndaMnVRm/X0aMhtG8mO5xnchITLrSY9njFFN2PoT4x0Xdzjtx oW0m9hNyNK7RRHyXX+Btw476+MxSNxZq07pa2hhln6oQMEOL9hOLa9XnzNirgixR0sD4Dmgabl uOHTMQvof/VG6SmjHWGhoFndDjs58VIVbIM02Yb3YWL2yp4+gmWPA2tnKlpwd891/s08ta9HMz ODU= From: Alistair Francis To: libc-alpha@sourceware.org Cc: arnd@arndb.de, adhemerval.zanella@linaro.org, fweimer@redhat.com, palmer@sifive.com, macro@wdc.com, zongbox@gmail.com, zong@andestech.com, alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v2 08/20] sysdeps/wait: Use waitid if avaliable Date: Mon, 24 Jun 2019 17:09:07 -0700 Message-Id: <2df9d3878359585ac1cc46243fb6664f7a50b3b3.1561421042.git.alistair.francis@wdc.com> In-Reply-To: References: MIME-Version: 1.0 If the waitid syscall is avaliable let's use that as waitpid and wait4 aren't always avaliable (they aren't avaliable on RV32). Unfortunately waitid is substantially differnt to waitpid and wait4, so the conversion ends up being complex. Signed-off-by: Alistair Francis --- ChangeLog | 3 ++ sysdeps/unix/sysv/linux/wait.c | 21 ++++++++- sysdeps/unix/sysv/linux/waitpid.c | 54 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/waitpid_nocancel.c | 53 +++++++++++++++++++++ 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f1c7acb6ab..9ed9bea8b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. * sysdeps/unix/sysv/linux/lowlevellock-futex.h: Use __NR_futex_time64 if we don't have __NR_futex. * sysdeps/unix/sysv/linux/gettimeofday.c: Use clock_gettime64 syscall for gettimeofday. + * sysdeps/unix/sysv/linux/wait.c: Use __NR_waitid if avaliable. + * sysdeps/unix/sysv/linux/waitpid.c: Likewise. + * sysdeps/unix/sysv/linux/waitpid_nocancel.c: Likewise. 2019-06-20 Dmitry V. Levin Florian Weimer diff --git a/sysdeps/unix/sysv/linux/wait.c b/sysdeps/unix/sysv/linux/wait.c index 498bd1c095..67b94776a4 100644 --- a/sysdeps/unix/sysv/linux/wait.c +++ b/sysdeps/unix/sysv/linux/wait.c @@ -26,8 +26,25 @@ pid_t __libc_wait (int *stat_loc) { - pid_t result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0, - (struct rusage *) NULL); + pid_t result; + +#ifdef __NR_waitid + siginfo_t infop; + + result = SYSCALL_CANCEL (waitid, P_ALL, 0, &infop, WEXITED); + + if (stat_loc) { + *stat_loc = infop.si_status; + } + + if (result == 0) { + result = infop.si_pid; + } +#else + result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0, + (struct rusage *) NULL); +#endif + return result; } diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c index f0897574c0..8c0e2f882a 100644 --- a/sysdeps/unix/sysv/linux/waitpid.c +++ b/sysdeps/unix/sysv/linux/waitpid.c @@ -20,12 +20,66 @@ #include #include #include +#include __pid_t __waitpid (__pid_t pid, int *stat_loc, int options) { #ifdef __NR_waitpid return SYSCALL_CANCEL (waitpid, pid, stat_loc, options); +#elif defined(__NR_waitid) + int ret, waitid_options = 0; + idtype_t idtype = P_PID; + siginfo_t infop; + + /* Set this to zero so we can test if WNOHANG was specified in options + * and there were no children in a waitable state. This is required to match + * waitid() behaviour. + */ + infop.si_pid = 0; + + if (pid < -1) { + idtype = P_PGID; + pid *= -1; + } else if (pid == -1) { + idtype = P_ALL; + } else if (pid == 0) { + idtype = P_PGID; + pid = getpgrp(); + } + + /* Convert the older WNOHANG, WUNTRACED and WCONTINUED options to the newer + * ones uses for waitid(). + */ + if (options | WNOHANG) { + waitid_options |= WNOHANG; + } + if (options | WUNTRACED) { + waitid_options |= WSTOPPED; + } + if (options | WCONTINUED) { + waitid_options |= WCONTINUED; + } + + /* waitid() requires at least WEXITED, WSTOPPED or WCONTINUED to be + * specified. If none were specified default to WEXITED as that is what + * waitpid() and wait4() do. + */ + if (options == 0 || waitid_options == WNOHANG) { + waitid_options |= WEXITED; + } + + ret = SYSCALL_CANCEL (waitid, idtype, pid, &infop, waitid_options); + + if (stat_loc) { + *stat_loc = infop.si_status; + } + + if (ret == 0) { + return infop.si_pid; + } + + return ret; #else return SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL); #endif diff --git a/sysdeps/unix/sysv/linux/waitpid_nocancel.c b/sysdeps/unix/sysv/linux/waitpid_nocancel.c index 89e36a5c0b..d14b7bf260 100644 --- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c +++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c @@ -27,6 +27,59 @@ __waitpid_nocancel (__pid_t pid, int *stat_loc, int options) { #ifdef __NR_waitpid return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options); +#elif defined(__NR_waitid) + int ret, waitid_options = 0; + idtype_t idtype = P_PID; + siginfo_t infop; + + /* Set this to zero so we can test if WNOHANG was specified in options + * and there were no children in a waitable state. This is required to match + * waitid() behaviour. + */ + infop.si_pid = 0; + + if (pid < -1) { + idtype = P_PGID; + pid *= -1; + } else if (pid == -1) { + idtype = P_ALL; + } else if (pid == 0) { + idtype = P_PGID; + pid = getpgrp(); + } + + /* Convert the older WNOHANG, WUNTRACED and WCONTINUED options to the newer + * ones uses for waitid(). + */ + if (options | WNOHANG) { + waitid_options |= WNOHANG; + } + if (options | WUNTRACED) { + waitid_options |= WSTOPPED; + } + if (options | WCONTINUED) { + waitid_options |= WCONTINUED; + } + + /* waitid() requires at least WEXITED, WSTOPPED or WCONTINUED to be + * specified. If none were specified default to WEXITED as that is what + * waitpid() and wait4() do. + */ + if (options == 0 || waitid_options == WNOHANG) { + waitid_options |= WEXITED; + } + + ret = INLINE_SYSCALL_CALL (waitid, idtype, pid, &infop, waitid_options); + + if (stat_loc) { + *stat_loc = infop.si_status; + } + + if (ret == 0) { + return infop.si_pid; + } + + return ret; #else return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL); #endif