From patchwork Sat Aug 10 00:59:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 34031 Received: (qmail 72429 invoked by alias); 10 Aug 2019 01:03:21 -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 72345 invoked by uid 89); 10 Aug 2019 01:03:20 -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: esa6.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=1565398999; x=1596934999; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+edhZOqiT+9FkzLKpvAhGZPC2rc1VTSkx4oWwtfl4NM=; b=hWn4L++H/4aZ30X2ZyufQk5cXsgPd/0+LVMiAiMfifsuIY1R1jB7Ym5M 66AkThlszJdaoMYhYnZZvFapCAnoKjIgUnXL7EEtwFT9K0hHoczMtvfIh Vu+7vUmWs4tlJ31YxTmekoHR21P5oKzDyDrmo9hP9JGNb0z7aAcqL68B2 wP6upd4UjfyKCCdLg8h5AlF+gOhk5VSW2f0alWaWkc+zlDy0gYdrdGpB6 dO4yAj+Yxbcl+KHmW1HTsRAZU0tGKfvkVC/ZeoJiHeRy+7G6I6QtqK3ws k46IhcKLFYzDvKpKiM8ArtLSniLptdwlwMQOySLXIQEmaE9ghbzxkQWcC A==; IronPort-SDR: o3WJbiZ4iw7K8/cP0kUKlddqunyPruTUaMRkwwFCk/ZgzDAOmMX2lkzFPy84w4Zv8wOcZtc3oi qSekLlqt5CRMsFXa1+1bIF1hzVC5BjsFW/7e+uV0Ui/dKmkCPe17aWqhHuErieKcK7MYPPRe10 /GwWaomqkR6KT2h0LPaopz6pAWH/CZ9xqC55rnhOP6M5iRqcr4RULdnLrcIMNKQ/l+j8bjG9xz 4Itqw0C5kKdRR7JElqBa+Mvkwgp/YDFxCTt/GfKZU62rRomvE+SaT8Dgb7EWt94Xj35/8pOz/D 4xQ= IronPort-SDR: usdqxGsaaoDAt1EixzQl/vS7AUL4/Dhdi8X9lEFhsYhveEVcgX736Y4MyN8pLQiQ4lfsXGkkA8 /2Ds7eFHytOFWljFg0YF3O5aZpWg0Nzqh1/NpJBpOHwKibxwZbM+HyYo+w+vzABLy0DgUmnJJL 9Bq9g83FAi9+a8q6ybhW4iJ0J3JhIAm672CNDkRZ4eMGQPvIEHc8mIL6nyzuZhEvqy85g/O3Zb UPVdebYjjq+S3jWcRH7YqgzRUHSJE3dMdFqY4ZafmZwti8+QqhEfreQUmwtahrmQAr+aB7XRod 4aDzZjEr+1s1KKeSFUWfdYmu IronPort-SDR: 3ZeZUt6Zx0yGaISmPQ8dVpUFxBjkY67HDAkI5xrvuRfuXFfECv3zcGHurlYsRj2df39W9z9Qiz 2KC4r2QwPEfay9eqVFw/3+2rfNSJCXAFKOnMZssPmXQDhbP8yFj86cPNeEDijeZAAyninsOBRg CfmjZfSK4/Ac2DU1o1/QmUuvdhZxfHfOzR07tgVtiZiXnoTgs2S8BzA8tqXkra0gWUByVbVjbA MTtJS/K1+JtDxddy2HxytsrLznljuNdQCxRuo0Nb/UTq1QdzfB0uE70Nokx5yHpNJAuRN/d7p4 wcs= 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 v4 04/24] sysdeps/wait: Use waitid if avaliable Date: Fri, 9 Aug 2019 17:59:57 -0700 Message-Id: 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 | 41 +++++++++++++-- sysdeps/unix/sysv/linux/waitpid.c | 58 +++++++++++++++++++++- sysdeps/unix/sysv/linux/waitpid_nocancel.c | 55 +++++++++++++++++++- 4 files changed, 152 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 82a2cdc746d..6daa6f259e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1425,6 +1425,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 498bd1c095e..cd124ed11fb 100644 --- a/sysdeps/unix/sysv/linux/wait.c +++ b/sysdeps/unix/sysv/linux/wait.c @@ -26,9 +26,44 @@ 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_wait4 + return SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0, + (struct rusage *) NULL); +#else + 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; + /* Fallthrough */ + 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; +#endif } weak_alias (__libc_wait, __wait) diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c index f0897574c0b..2add17b3023 100644 --- a/sysdeps/unix/sysv/linux/waitpid.c +++ b/sysdeps/unix/sysv/linux/waitpid.c @@ -20,14 +20,70 @@ #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); -#else +#elif defined(__NR_wait4) return SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL); +#else + __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) + { + /* FIXME: This can lead to a race condition */ + 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; + /* Fallthrough */ + 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; #endif } libc_hidden_def (__waitpid) diff --git a/sysdeps/unix/sysv/linux/waitpid_nocancel.c b/sysdeps/unix/sysv/linux/waitpid_nocancel.c index 89e36a5c0b1..00d566a9931 100644 --- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c +++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c @@ -27,8 +27,61 @@ __waitpid_nocancel (__pid_t pid, int *stat_loc, int options) { #ifdef __NR_waitpid return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options); -#else +#elif defined (__NR_wait4) return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL); +#else + __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) + { + /* FIXME: This can lead to a race condition */ + 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; + /* Fallthrough */ + 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; #endif } libc_hidden_def (__waitpid_nocancel)