Browse Source

sleep: code shrink

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>
Denys Vlasenko 13 years ago
parent
commit
c403e32526
2 changed files with 28 additions and 33 deletions
  1. 21 26
      libc/unistd/sleep.c
  2. 7 7
      libc/unistd/usleep.c

+ 21 - 26
libc/unistd/sleep.c

@@ -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);
 	}
     }

+ 7 - 7
libc/unistd/usleep.c

@@ -14,19 +14,19 @@
 
 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__ */