Explorar o código

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 %!s(int64=14) %!d(string=hai) anos
pai
achega
c403e32526
Modificáronse 2 ficheiros con 28 adicións e 33 borrados
  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 SIGCHLD was already blocked, no need to check SIG_IGN. Else...  */
-    if (!__sigismember (&oset, SIGCHLD))
+    if (!__sigismember (&set, SIGCHLD)) {
-    {
-	int saved_errno;
 	struct sigaction oact;
 	struct sigaction oact;
 
 
-	__sigemptyset (&set);
+	/* Is SIGCHLD set to SIG_IGN? */
-	__sigaddset (&set, SIGCHLD);
-
 	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)
+	    /* Yes, run nanosleep with SIGCHLD blocked.  */
-	{
-	    /* We should leave SIGCHLD blocked.  */
 	    result = nanosleep (&ts, &ts);
 	    result = nanosleep (&ts, &ts);
 
 
-	    saved_errno = errno;
+	    /* Unblock SIGCHLD by restoring signal mask.  */
-	    /* Restore the original signal mask.  */
+	    /* this sigprocmask call never fails, thus never updates errno,
-	    sigprocmask (SIG_SETMASK, &oset, NULL);
+	       and therefore we don't need to save/restore it.  */
-	    __set_errno (saved_errno);
+	    //saved_errno = errno;
-	}
+	    sigprocmask (SIG_SETMASK, &set, NULL);
-	else
+	    //__set_errno (saved_errno);
-	{
+	} else {
-	    /* We should unblock SIGCHLD.  Restore the original signal mask.  */
+	    /* No workaround needed, unblock SIGCHLD by restoring signal mask.  */
-	    sigprocmask (SIG_SETMASK, &oset, NULL);
+	    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 = {
+	const struct timespec ts = {
-	.tv_sec = (long int) (usec / 1000000),
+		.tv_sec = (long int) (usec / 1000000),
-	.tv_nsec = (long int) (usec % 1000000) * 1000ul
+		.tv_nsec = (long int) (usec % 1000000) * 1000ul
-    };
+	};
-    return(nanosleep(&ts, NULL));
+	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_sec = (long int) (usec / 1000000);
-	tv.tv_usec = usec;
+	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__ */