microoptimization of lib/poll.c
authorPaolo Bonzini <bonzini@gnu.org>
Wed, 6 Aug 2008 08:27:53 +0000 (10:27 +0200)
committerPaolo Bonzini <bonzini@gnu.org>
Wed, 6 Aug 2008 08:27:53 +0000 (10:27 +0200)
2008-08-06  Paolo Bonzini  <bonzini@gnu.org>

* lib/poll.c (poll): Avoid division when timeout is 0, cache
_SC_OPEN_MAX, avoid repeated access to errno.  Check for nfd < 0.

ChangeLog
lib/poll.c

index 9fe6dcc..9273b33 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-08-06  Paolo Bonzini  <bonzini@gnu.org>
+
+       * lib/poll.c (poll): Avoid division when timeout is 0, cache
+       _SC_OPEN_MAX, avoid repeated access to errno.  Check for nfd < 0.
+
 2008-08-06  Jim Meyering  <meyering@redhat.com>
 
        * modules/inet_pton (License): Relicense under LGPLv2+.
index b3eda5d..2138b81 100644 (file)
@@ -55,19 +55,25 @@ poll (pfd, nfd, timeout)
      int timeout;
 {
   fd_set rfds, wfds, efds;
-  struct timeval tv, *ptv;
+  struct timeval tv = { 0, 0 };
+  struct timeval *ptv;
   int maxfd, rc;
   nfds_t i;
 
 #ifdef _SC_OPEN_MAX
-  if (nfd > sysconf (_SC_OPEN_MAX))
+  static int sc_open_max = -1;
+
+  if (nfd < 0
+      || (nfd > sc_open_max
+          && (sc_open_max != -1
+             || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
     {
       errno = EINVAL;
       return -1;
     }
 #else /* !_SC_OPEN_MAX */
 #ifdef OPEN_MAX
-  if (nfd > OPEN_MAX)
+  if (nfd < 0 || nfd > OPEN_MAX)
     {
       errno = EINVAL;
       return -1;
@@ -84,10 +90,11 @@ poll (pfd, nfd, timeout)
     }
 
   /* convert timeout number into a timeval structure */
-  ptv = &tv;
-  if (timeout >= 0)
+  if (timeout == 0)
+    ptv = &tv;
+  else if (timeout > 0)
     {
-      /* return immediately or after timeout */
+      ptv = &tv;
       ptv->tv_sec = timeout / 1000;
       ptv->tv_usec = (timeout % 1000) * 1000;
     }
@@ -155,6 +162,7 @@ poll (pfd, nfd, timeout)
        if (FD_ISSET (pfd[i].fd, &rfds))
          {
            int r;
+           int socket_errno;
 
 #if defined __MACH__ && defined __APPLE__
            /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
@@ -162,23 +170,25 @@ poll (pfd, nfd, timeout)
               connected socket, a server socket, or something else using a
               0-byte recv, and use ioctl(2) to detect POLLHUP.  */
            r = recv (pfd[i].fd, NULL, 0, MSG_PEEK);
-           if (r == 0 || errno == ENOTSOCK)
+           socket_errno = (r < 0) ? errno : 0;
+           if (r == 0 || socket_errno == ENOTSOCK)
              ioctl(pfd[i].fd, FIONREAD, &r);
 #else
            char data[64];
            r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK);
+           socket_errno = (r < 0) ? errno : 0;
 #endif
            if (r == 0)
              happened |= POLLHUP;
 
            /* If the event happened on an unconnected server socket,
               that's fine. */
-           else if (r > 0 || ( /* (r == -1) && */ errno == ENOTCONN))
+           else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
              happened |= (POLLIN | POLLRDNORM) & sought;
 
            /* Distinguish hung-up sockets from other errors.  */
-           else if (errno == ESHUTDOWN || errno == ECONNRESET
-                    || errno == ECONNABORTED || errno == ENETRESET)
+           else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
+                    || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
              happened |= POLLHUP;
 
            else