From patchwork Sat Jun 22 04:37:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 33265 Received: (qmail 94416 invoked by alias); 22 Jun 2019 04:46:55 -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 94325 invoked by uid 89); 22 Jun 2019 04:46:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.9 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=59 X-HELO: esa5.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=1561178814; x=1592714814; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nnzx+i+D7Q/nQNKQdu9VoGspPImhiuN6X0N5Ocb+V2E=; b=BSci8u4huPsAIM6oX7/DXzGzHQZG3PSESBhUMigGp8Wc5OJa3V1vzA1I T230F5loJMvE0NWirBgB/Q0KASbeQXYpM7mmKf+/B0XpaMbvm8nxRBp3I Kr5wONXKuea2wfO+1uCU1FGbGRcz+37wqNdgDGoBxJ5582MVKKk+f3gEI BdYoiZ/RZ4k9JJNYW3CiuazOMkYgzYthqsi6CG4uatoENXsqQrJcNtVWd h/f1h6n6FwIZW25Nz/5uRh4rgRd+k9vUh07cx6ZJHbokyJk17MwW34D2C VElhMeYmXhKiV78/rriStG1spwBnhFYpr7tO83a8NOWKfRbfGdd0nzeTa Q==; IronPort-SDR: 4Tf6ExFt/aB6OX4wd+ElOeRkY6CXEno2IYN0mUi1GRLyYIe8CD+3FdcRxUX/IsmXctaQDVfeoS mXbgTxEQT7tREM7bFhyabj16LMeAVaJBTNSSCXnIUE4SaobJzZGzs7tr9xe7ZNRAi8dsYIOA5l NtleXcg4ey6ZNbIDeFJ6QJRv7kL4FueE9yJoihPfy+oh1mqz9aNshrak0jeGtYlilQ5WyEXc1P QCePwZyAUFiRv2IvVExT3eWum+zznf+O3EA7lwH0fHF9Wrn3m0yXnFvMZDc8h2e8sHuuM6r3sI 233mkdjlhdj1mjxum9OLMS/g IronPort-SDR: IVO9ADi1GwBCKPVRM/Gq0XA7NdGl8+Z0D4KvurxZ3U09kyrxfdqX88HBbTp3xaLvA3s7NpqsYK Bi5q68er4ZkgpVWjRLRc3t9wufEm15cYxOV5u9TvNtXDpugNy4FRfw1A6o46aUsaycfEjQ66Mo Ul3OzJI+YVcUdmv105PBXL/HJtW58pcTHqhpGA4olSxpRb+LACttW61IW2uqyQxUX6OTDRU0qH YpQWlUAW0/poROyKLq9s91sC76kR5iM6B4Gj/m08ymK9/0vSFD36cGpo2fdRqcmaxvH3f7nGFQ OSk= From: Alistair Francis To: libc-alpha@sourceware.org Cc: alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v1 04/16] sysdeps/wait: Use __NR_waitid if avaliable Date: Fri, 21 Jun 2019 21:37:23 -0700 Message-Id: <358c124ab1be979da9bc0051dc799dd2c37cdfb2.1561177967.git.alistair.francis@wdc.com> In-Reply-To: References: MIME-Version: 1.0 If the __NR_waitid syscall is avaliable let's use that as __NR_waitpid and __NR_wait4 aren't always avaliable (they aren't avaliable on RV32). Signed-off-by: Alistair Francis --- ChangeLog | 3 ++ sysdeps/unix/sysv/linux/wait.c | 19 ++++++++++++- sysdeps/unix/sysv/linux/waitpid.c | 33 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/waitpid_nocancel.c | 32 +++++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) 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..9e81ea61ba 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, + pid_t result; + +#if defined(__NR_waitid) + siginfo_t infop; + + result = SYSCALL_CANCEL (waitid, P_ALL, 0, &infop, 0); + + 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..8bc15ba92f 100644 --- a/sysdeps/unix/sysv/linux/waitpid.c +++ b/sysdeps/unix/sysv/linux/waitpid.c @@ -20,12 +20,45 @@ #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; + 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(); + } + + ret = SYSCALL_CANCEL (waitid, idtype, pid, &infop, 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..d50d15c488 100644 --- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c +++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c @@ -27,6 +27,38 @@ __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; + 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(); + } + + ret = INLINE_SYSCALL_CALL (waitid, idtype, pid, &infop, 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