From patchwork Sun Nov 8 22:52:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 56178 Delivered-To: patch@linaro.org Received: by 10.112.1.169 with SMTP id 9csp166454lbn; Sun, 8 Nov 2015 14:53:16 -0800 (PST) X-Received: by 10.68.57.137 with SMTP id i9mr25765946pbq.66.1447023196131; Sun, 08 Nov 2015 14:53:16 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id x16si3276915pbt.151.2015.11.08.14.53.15 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 14:53:16 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-64818-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; spf=pass (google.com: domain of libc-alpha-return-64818-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-64818-patch=linaro.org@sourceware.org; dkim=pass header.i=@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=I53jrKE/omytlpRXVIyRlyhe6ow0TfIRyWwrYMU2gssBhfcm8P/tX iLpKTLjcxn1zymH6lf8d6/KOTgGzt25Gk2We0TUae7zFClnu2Hyvr0Cu6rDr4DJ4 iFVGk96LfyLlCvSnhCce0rYpq5IBipHTvDc2DePH/wB0i1QDsDozQY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=IdRKhE9qGRj7btxtIRjbnqurAYc=; b=DgSva4IjkKT4/Phi+yo2SWIh4kw4 lS6Af+Ppsol2UY8QSiNlt2LtZX3qV1INuElPJWMkaO8c0ldzd4HNEFjoEkJnhVlE ExRSJmeS76UB0rINapELONBepk6JXgR2jpejxudcjo1EwGFfJBEgZ8OizvTh7aKi 3jYQ3F0LhMKsqH4= Received: (qmail 49480 invoked by alias); 8 Nov 2015 22:53:06 -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 49464 invoked by uid 89); 8 Nov 2015 22:53:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-yk0-f170.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=RCWlXBhx119TyziBOgw2y0gVKSl7KqpBMPqN9oRnF/g=; b=IjnskRm6vW7Btv3bRFeoU1O7eGu1dJmVLb9rffxNW42A1kAAAOlR4NqST7zpdB211q TW5B8f32zxiYCqZeIG1JtdkbCCbyb3d+COULILpTAExEvTVhr38rC5K9vL0Das9WRhdw ++eGURmg6IgC393HlBYUGVtsBa7QuPQ6qdFHgEC2vuq3LGeN8EDf4waH11Q5CV39gMcI 7ZaMgDcK8L32PUqA5qrlV0hYBtFEcG43BEvd1mdX4Nxxno0Nznf/QLFdZjXY0uIoA3dh z/+oo9+HIrQlmRAQIoG/dg6Koehsno5iH4im4WPfTjrqWiwo83kXtuo/MSKcpcvzWenj iSkw== X-Gm-Message-State: ALoCoQllWPQit87ctziQqvJULyErfY4RNMcF4HiAqJmdHplBYH2joPofhZ7Y7PTnWLvzSSvTt60d X-Received: by 10.129.137.198 with SMTP id z189mr20167966ywf.307.1447023182486; Sun, 08 Nov 2015 14:53:02 -0800 (PST) From: Adhemerval Zanella X-Google-Original-From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH] Remove signal handling for nanosleep (bug 16364) Date: Sun, 8 Nov 2015 20:52:51 -0200 Message-Id: <1447023171-31542-1-git-send-email-adhemerval.zanella@linaro.com> Linux 2.6.32 and forward do not show the issue regarding SysV SIGCHLD vs. SIG_IGN for nanosleep which make it feasible to use it for sleep implementation without requiring any hacking to handle the spurious wake up. This patch simplifies the sleep code to call nanosleep directly. Checked on x86_64, ppc64le, and aarch64. [BZ #16364] * sysdeps/unix/sysv/linux/sleep.c (__sleep): Simplify code to use nanosleep without requiring to handle spurious wakeups. --- sysdeps/unix/sysv/linux/sleep.c | 127 ++-------------------------------------- 2 files changed, 11 insertions(+), 122 deletions(-) -- 1.9.1 diff --git a/sysdeps/unix/sysv/linux/sleep.c b/sysdeps/unix/sysv/linux/sleep.c index 2a06d5a..3885a34 100644 --- a/sysdeps/unix/sysv/linux/sleep.c +++ b/sysdeps/unix/sysv/linux/sleep.c @@ -17,133 +17,16 @@ License along with the GNU C Library; if not, see . */ -#include #include -#include -#include /* For the real memset prototype. */ #include -#include -#include +#include - -#if 0 -static void -cl (void *arg) -{ - (void) __sigprocmask (SIG_SETMASK, arg, (sigset_t *) NULL); -} -#endif - - -/* We are going to use the `nanosleep' syscall of the kernel. But the - kernel does not implement the stupid SysV SIGCHLD vs. SIG_IGN - behaviour for this syscall. Therefore we have to emulate it here. */ unsigned int __sleep (unsigned int seconds) { - const unsigned int max - = (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1); - struct timespec ts; - sigset_t set, oset; - unsigned int result; - - /* This is not necessary but some buggy programs depend on this. */ - if (__glibc_unlikely (seconds == 0)) - { -#ifdef CANCELLATION_P - CANCELLATION_P (THREAD_SELF); -#endif - return 0; - } - - ts.tv_sec = 0; - ts.tv_nsec = 0; - again: - if (sizeof (ts.tv_sec) <= sizeof (seconds)) - { - /* Since SECONDS is unsigned assigning the value to .tv_sec can - overflow it. In this case we have to wait in steps. */ - ts.tv_sec += MIN (seconds, max); - seconds -= (unsigned int) ts.tv_sec; - } - else - { - ts.tv_sec = (time_t) seconds; - seconds = 0; - } - - /* Linux will wake up the system call, nanosleep, when SIGCHLD - arrives even if SIGCHLD is ignored. We have to deal with it - in libc. We block SIGCHLD first. */ - __sigemptyset (&set); - __sigaddset (&set, SIGCHLD); - if (__sigprocmask (SIG_BLOCK, &set, &oset)) - return -1; - - /* If SIGCHLD is already blocked, we don't have to do anything. */ - if (!__sigismember (&oset, SIGCHLD)) - { - int saved_errno; - struct sigaction oact; - - __sigemptyset (&set); - __sigaddset (&set, SIGCHLD); - - /* We get the signal handler for SIGCHLD. */ - if (__sigaction (SIGCHLD, (struct sigaction *) NULL, &oact) < 0) - { - saved_errno = errno; - /* Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); - __set_errno (saved_errno); - return -1; - } - - /* Note the sleep() is a cancellation point. But since we call - nanosleep() which itself is a cancellation point we do not - have to do anything here. */ - if (oact.sa_handler == SIG_IGN) - { - //__libc_cleanup_push (cl, &oset); - - /* We should leave SIGCHLD blocked. */ - while (1) - { - result = __nanosleep (&ts, &ts); - - if (result != 0 || seconds == 0) - break; - - if (sizeof (ts.tv_sec) <= sizeof (seconds)) - { - ts.tv_sec = MIN (seconds, max); - seconds -= (unsigned int) ts.tv_nsec; - } - } - - //__libc_cleanup_pop (0); - - saved_errno = errno; - /* Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); - __set_errno (saved_errno); - - goto out; - } - - /* We should unblock SIGCHLD. Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); - } - - result = __nanosleep (&ts, &ts); - if (result == 0 && seconds != 0) - goto again; - - out: - if (result != 0) - /* Round remaining time. */ - result = seconds + (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L); - - return result; + struct timespec ts = { .tv_sec = seconds, .tv_nsec = 0 }; + if (__nanosleep (&ts, &ts)) + return ts.tv_sec; + return 0; } weak_alias (__sleep, sleep)