From patchwork Wed Jul 17 00:08:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 33703 Received: (qmail 15410 invoked by alias); 17 Jul 2019 00:11:44 -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 15343 invoked by uid 89); 17 Jul 2019 00:11:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.6 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: esa4.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=1563322302; x=1594858302; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=00LbqPsdvkw74T6RToVbCkXSCGVFV+R5sW8+kXLhU3M=; b=jw0WTDYitFAMdBmZhjherd0owMjKKdhiJr2h86W7omwpA//4BAhNoAui dJvaRZVAelmQb5QF2VSccBvNz9Ty5ZYJlehNtjL/I/FMQD7O9TP4Hj/mN zZ5FfZ/tLkpbj+e542hkOhjKz0+HG64br6XUlXtyx1mRSdBZXAHhP8uN3 Gyyyojr3rTJjOSxkC7U9g/nYWhEGdZ4raOYLkeuekbslv2wPmv4hZDT2Q cQmdsDOeshB0DudJwSR38gR/BkazUvKO7ffEfFE5Im7oIcW1XOWq592hC zJH4d1mMmRsOoVwMhEf/JxDXLwma6GR9R/HQGmOOvSXJzKkrErCM9wi1q w==; IronPort-SDR: zdtOI8kTyLtRLu5DjNogbXukzBqr+hLGv/qZhC6ZWOBki37HBO5CFyHfZg/jklqS2b7oKXvQ2S B5ArXV7G/tx6k8evIqwE1VbPiUY7aqNawDCjWkqDP1gmzGdsq5O2kibZyP1i//NCChSKlunYOB saBnJCgcYzjZheBnOGDd6fSkHCqq4w52YHpxv0q8seDBSUPMps6Qmx6YkbpX0CXxITg9HY/aiF WFNVZoYS5YmLuLtxEIi310kbEJ9ci4ZUxCDeQqUK0U07coJeCC8uhflCDPsEFXSio3J7kz+rf0 xeY= IronPort-SDR: OiN5TeQX/F/d7r9I8obZhZVzQw0Ig6oNLYzHonFKjk1aJDrneE5PfotikSWzlLohpYyvdT3GMz h39YMHNDABbQprQia2uudutYHnybNyL4Iv/BLx0WOIdiXZqe/0G0g2/dTARVbikxVkdd1acs9a SwZId1cMvU7fRj3+89n857yZwl+KonTZTzwvcAYUJTCyGi3m3uw9Z74w9tHxidfPTcVXsxh8/v GoqAARtnfUwipPXgUkgX5TIA+0FX8wrxtK67cu9SSqaupCL1e+/OQDMSlh6VyNtehZWjIhoMoV OJxd8HL8TBZrgI2vJZQ7481T IronPort-SDR: FAPTc9BP5JB/PsM85LGB9rV0+QSPmeS4WwQ3jh3CW/nsvsjgyeW/rEbvdeoQdOUvnka75Vn+CM hxvfwhe+su0KpAAH+QZGg002yzMgr4fPwGSRiUijmmzkQSmDF6IvCcfeKlgv1C9CHZG8Vf1PEl p9BYDi2r+A8snvgKJx3jlroJX3sKrH4Tl6GlLNLfS8+hYnbMSb7KgMwTA5Lk4xcrM5fIJuvipf WlZ0VE72IpfDmjXIn+NKo+gxFpD8sOdDzkODAx8Dzy35a1k2jDBhdP/ylflxsNxsYEnJr+i/jU MYo= 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, alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v3 03/23] sysdeps/wait: Use waitid if avaliable Date: Tue, 16 Jul 2019 17:08:48 -0700 Message-Id: <2d3359a195633b85e01f83bf536330d72f7bc8aa.1563321715.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 | 39 ++++++++++++++++-- sysdeps/unix/sysv/linux/waitpid.c | 46 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/waitpid_nocancel.c | 45 +++++++++++++++++++++ 4 files changed, 130 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ca390a9c3..fb54a4aa61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1029,6 +1029,9 @@ * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. * 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..e727afa14b 100644 --- a/sysdeps/unix/sysv/linux/wait.c +++ b/sysdeps/unix/sysv/linux/wait.c @@ -26,9 +26,42 @@ pid_t __libc_wait (int *stat_loc) { - pid_t result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0, - (struct rusage *) NULL); - return result; +#ifdef __NR_waitid + siginfo_t infop; + __pid_t ret; + + ret = SYSCALL_CANCEL (waitid, P_ALL, 0, &infop, WEXITED, NULL); + + if (ret < 0) { + return ret; + } + + if (stat_loc) { + *stat_loc = 0; + switch (infop.si_code) { + case CLD_EXITED: + *stat_loc = infop.si_status << 8; + break; + case CLD_DUMPED: + *stat_loc = 0x80; + case CLD_KILLED: + *stat_loc |= infop.si_status; + break; + case CLD_TRAPPED: + case CLD_STOPPED: + *stat_loc = infop.si_status << 8 | 0x7f; + break; + case CLD_CONTINUED: + *stat_loc = 0xffff; + break; + } + } + + return infop.si_pid; +#else + return SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0, + (struct rusage *) NULL); +#endif } weak_alias (__libc_wait, __wait) diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c index f0897574c0..7d4e0bb77d 100644 --- a/sysdeps/unix/sysv/linux/waitpid.c +++ b/sysdeps/unix/sysv/linux/waitpid.c @@ -20,12 +20,58 @@ #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) + __pid_t ret; + idtype_t idtype = P_PID; + siginfo_t infop; + + if (pid < -1) { + idtype = P_PGID; + pid *= -1; + } else if (pid == -1) { + idtype = P_ALL; + } else if (pid == 0) { + idtype = P_PGID; + pid = getpgrp(); + } + + options |= WEXITED; + + ret = SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, NULL); + + if (ret < 0) { + return ret; + } + + if (stat_loc) { + *stat_loc = 0; + switch (infop.si_code) { + case CLD_EXITED: + *stat_loc = infop.si_status << 8; + break; + case CLD_DUMPED: + *stat_loc = 0x80; + case CLD_KILLED: + *stat_loc |= infop.si_status; + break; + case CLD_TRAPPED: + case CLD_STOPPED: + *stat_loc = infop.si_status << 8 | 0x7f; + break; + case CLD_CONTINUED: + *stat_loc = 0xffff; + break; + } + } + + return infop.si_pid; #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..c92f05421b 100644 --- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c +++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c @@ -27,6 +27,51 @@ __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) + __pid_t ret; + idtype_t idtype = P_PID; + siginfo_t infop; + + if (pid < -1) { + idtype = P_PGID; + pid *= -1; + } else if (pid == -1) { + idtype = P_ALL; + } else if (pid == 0) { + idtype = P_PGID; + pid = getpgrp(); + } + + options |= WEXITED; + + ret = INLINE_SYSCALL_CALL (waitid, idtype, pid, &infop, options, NULL); + + if (ret < 0) { + return ret; + } + + if (stat_loc) { + *stat_loc = 0; + switch (infop.si_code) { + case CLD_EXITED: + *stat_loc = infop.si_status << 8; + break; + case CLD_DUMPED: + *stat_loc = 0x80; + case CLD_KILLED: + *stat_loc |= infop.si_status; + break; + case CLD_TRAPPED: + case CLD_STOPPED: + *stat_loc = infop.si_status << 8 | 0x7f; + break; + case CLD_CONTINUED: + *stat_loc = 0xffff; + break; + } + } + + return infop.si_pid; #else return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL); #endif