OSDN Git Service

sleep: code shrink
authorDenys Vlasenko <dvlasenk@redhat.com>
Thu, 21 Oct 2010 16:19:35 +0000 (18:19 +0200)
committerDenys Vlasenko <dvlasenk@redhat.com>
Thu, 21 Oct 2010 16:19:35 +0000 (18:19 +0200)
Use less stack by using same "sigset_t set" object for new and saved
signal set, remove redundant clearing of set, and do not save/restore
errno around sigprocmask(SIG_SETMASK) - it never changes it.

While at it, improve comments and make code style consistent
across sleep.c file.

    text           data     bss     dec     hex filename
-    242              0       0     242      f2 libc/unistd/sleep.o
+    197              0       0     197      c5 libc/unistd/sleep.o

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
libc/unistd/sleep.c
libc/unistd/usleep.c

index b0031f0..d844d5b 100644 (file)
@@ -49,50 +49,45 @@ unsigned int sleep (unsigned int sec)
 unsigned int sleep (unsigned int seconds)
 {
     struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
-    sigset_t set, oset;
+    sigset_t set;
     unsigned int result;
 
     /* This is not necessary but some buggy programs depend on this.  */
-    if (seconds == 0)
-       {
+    if (seconds == 0) {
 # ifdef CANCELLATION_P
-               CANCELLATION_P (THREAD_SELF);
+       CANCELLATION_P (THREAD_SELF);
 # endif
-               return 0;
-       }
+       return 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);
-    sigprocmask (SIG_BLOCK, &set, &oset); /* can't fail */
+    sigprocmask (SIG_BLOCK, &set, &set); /* never fails */
 
-    /* If SIGCHLD is already blocked, we don't have to do anything.  */
-    if (!__sigismember (&oset, SIGCHLD))
-    {
-       int saved_errno;
+    /* If SIGCHLD was already blocked, no need to check SIG_IGN. Else...  */
+    if (!__sigismember (&set, SIGCHLD)) {
        struct sigaction oact;
 
-       __sigemptyset (&set);
-       __sigaddset (&set, SIGCHLD);
-
+       /* Is SIGCHLD set to SIG_IGN? */
        sigaction (SIGCHLD, NULL, &oact); /* never fails */
+       if (oact.sa_handler == SIG_IGN) {
+           //int saved_errno;
 
-       if (oact.sa_handler == SIG_IGN)
-       {
-           /* We should leave SIGCHLD blocked.  */
+           /* Yes, run nanosleep with SIGCHLD blocked.  */
            result = nanosleep (&ts, &ts);
 
-           saved_errno = errno;
-           /* Restore the original signal mask.  */
-           sigprocmask (SIG_SETMASK, &oset, NULL);
-           __set_errno (saved_errno);
-       }
-       else
-       {
-           /* We should unblock SIGCHLD.  Restore the original signal mask.  */
-           sigprocmask (SIG_SETMASK, &oset, NULL);
+           /* Unblock SIGCHLD by restoring signal mask.  */
+           /* this sigprocmask call never fails, thus never updates errno,
+              and therefore we don't need to save/restore it.  */
+           //saved_errno = errno;
+           sigprocmask (SIG_SETMASK, &set, NULL);
+           //__set_errno (saved_errno);
+       } else {
+           /* No workaround needed, unblock SIGCHLD by restoring signal mask.  */
+           sigprocmask (SIG_SETMASK, &set, NULL);
            result = nanosleep (&ts, &ts);
        }
     }
index 61ddb90..8d01703 100644 (file)
 
 int usleep (__useconds_t usec)
 {
-    const struct timespec ts = {
-       .tv_sec = (long int) (usec / 1000000),
-       .tv_nsec = (long int) (usec % 1000000) * 1000ul
-    };
-    return(nanosleep(&ts, NULL));
+       const struct timespec ts = {
+               .tv_sec = (long int) (usec / 1000000),
+               .tv_nsec = (long int) (usec % 1000000) * 1000ul
+       };
+       return nanosleep(&ts, NULL);
 }
 #else /* __UCLIBC_HAS_REALTIME__ */
 int usleep (__useconds_t usec)
 {
        struct timeval tv;
 
-       tv.tv_sec = 0;
-       tv.tv_usec = usec;
+       tv.tv_sec = (long int) (usec / 1000000);
+       tv.tv_usec = (long int) (usec % 1000000);
        return select(0, NULL, NULL, NULL, &tv);
 }
 #endif /* __UCLIBC_HAS_REALTIME__ */