Ver Fonte

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 há 13 anos atrás
pai
commit
c403e32526
2 ficheiros alterados com 28 adições e 33 exclusões
  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)
 unsigned int sleep (unsigned int seconds)
 {
 {
     struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
     struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
-    sigset_t set, oset;
+    sigset_t set;
     unsigned int result;
     unsigned int result;
 
 
     /* This is not necessary but some buggy programs depend on this.  */
     /* This is not necessary but some buggy programs depend on this.  */
-    if (seconds == 0)
-	{
+    if (seconds == 0) {
 # ifdef CANCELLATION_P
 # ifdef CANCELLATION_P
-		CANCELLATION_P (THREAD_SELF);
+	CANCELLATION_P (THREAD_SELF);
 # endif
 # endif
-		return 0;
-	}
+	return 0;
+    }
 
 
     /* Linux will wake up the system call, nanosleep, when SIGCHLD
     /* Linux will wake up the system call, nanosleep, when SIGCHLD
        arrives even if SIGCHLD is ignored.  We have to deal with it
        arrives even if SIGCHLD is ignored.  We have to deal with it
        in libc.  We block SIGCHLD first.  */
        in libc.  We block SIGCHLD first.  */
     __sigemptyset (&set);
     __sigemptyset (&set);
     __sigaddset (&set, SIGCHLD);
     __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;
 	struct sigaction oact;
 
 
-	__sigemptyset (&set);
-	__sigaddset (&set, SIGCHLD);
-
+	/* Is SIGCHLD set to SIG_IGN? */
 	sigaction (SIGCHLD, NULL, &oact); /* never fails */
 	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);
 	    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);
 	    result = nanosleep (&ts, &ts);
 	}
 	}
     }
     }

+ 7 - 7
libc/unistd/usleep.c

@@ -14,19 +14,19 @@
 
 
 int usleep (__useconds_t usec)
 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__ */
 #else /* __UCLIBC_HAS_REALTIME__ */
 int usleep (__useconds_t usec)
 int usleep (__useconds_t usec)
 {
 {
 	struct timeval tv;
 	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);
 	return select(0, NULL, NULL, NULL, &tv);
 }
 }
 #endif /* __UCLIBC_HAS_REALTIME__ */
 #endif /* __UCLIBC_HAS_REALTIME__ */