[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r15133: Lower number of syscalls used to write data to ordinary sock (in tor/trunk: . src/or)



Author: nickm
Date: 2008-06-11 13:56:52 -0400 (Wed, 11 Jun 2008)
New Revision: 15133

Modified:
   tor/trunk/
   tor/trunk/configure.in
   tor/trunk/src/or/buffers.c
Log:
 r16171@tombo:  nickm | 2008-06-11 13:47:41 -0400
 Lower number of syscalls used to write data to ordinary sockets through use of writev.  Disabled till I have time to test it.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r16171] on 49666b30-7950-49c5-bedf-9dc8f3168102

Modified: tor/trunk/configure.in
===================================================================
--- tor/trunk/configure.in	2008-06-11 13:02:06 UTC (rev 15132)
+++ tor/trunk/configure.in	2008-06-11 17:56:52 UTC (rev 15133)
@@ -196,7 +196,7 @@
 dnl Check for functions before libevent, since libevent-1.2 apparently
 dnl exports strlcpy without defining it in a header.
 
-AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit strlcat strlcpy strtoull ftello getaddrinfo localtime_r gmtime_r memmem strtok_r inet_pton inet_ntop)
+AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit strlcat strlcpy strtoull ftello getaddrinfo localtime_r gmtime_r memmem strtok_r inet_pton inet_ntop writev readv)
 
 using_custom_malloc=no
 if test x$enable_openbsd_malloc = xyes ; then
@@ -311,7 +311,7 @@
 
 AC_CHECK_HEADERS(unistd.h string.h signal.h ctype.h sys/stat.h sys/types.h fcntl.h sys/fcntl.h sys/time.h errno.h assert.h time.h, , AC_MSG_WARN(Some headers were not found, compilation may fail.  If compilation succeeds, please send your orconfig.h to the developers so we can fix this warning.))
 
-AC_CHECK_HEADERS(netdb.h sys/ioctl.h sys/socket.h arpa/inet.h netinet/in.h pwd.h grp.h sys/un.h)
+AC_CHECK_HEADERS(netdb.h sys/ioctl.h sys/socket.h arpa/inet.h netinet/in.h pwd.h grp.h sys/un.h sys/uio.h)
 
 dnl These headers are not essential
 

Modified: tor/trunk/src/or/buffers.c
===================================================================
--- tor/trunk/src/or/buffers.c	2008-06-11 13:02:06 UTC (rev 15132)
+++ tor/trunk/src/or/buffers.c	2008-06-11 17:56:52 UTC (rev 15133)
@@ -15,7 +15,14 @@
  **/
 #define BUFFERS_PRIVATE
 #include "or.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
 
+
 //#define PARANOIA
 //#define NOINLINE
 
@@ -545,6 +552,9 @@
   return chunk;
 }
 
+/** DOCDOC */
+#define N_IOV 3
+
 /** Read up to <b>at_most</b> bytes from the socket <b>fd</b> into
  * <b>chunk</b> (which must be on <b>buf</b>). If we get an EOF, set
  * *<b>reached_eof</b> to 1.  Return -1 on error, 0 on eof or blocking,
@@ -554,9 +564,26 @@
               int *reached_eof)
 {
   ssize_t read_result;
+#if 0 && defined(HAVE_READV) && !defined(WIN32)
+  struct iovec iov[N_IOV];
+  int i;
+  size_t remaining = at_most;
+  for (i=0; chunk && i < N_IOV && remaining; ++i) {
+    iov[i].iov_base = CHUNK_WRITE_PTR(chunk);
+    if (remaining > CHUNK_REMAINING_CAPACITY(chunk))
+      iov[i].iov_len = CHUNK_REMAINING_CAPACITY(chunk);
+    else
+      iov[i].iov_len = remaining;
+    remaining -= iov[i].iov_len;
+    chunk = chunk->next;
+  }
+  read_result = readv(fd, iov, i);
+#else
+  if (at_most > CHUNK_REMAINING_CAPACITY(chunk))
+    at_most = CHUNK_REMAINING_CAPACITY(chunk);
+  read_result = tor_socket_recv(fd, CHUNK_WRITE_PTR(chunk), at_most, 0);
+#endif
 
-  tor_assert(CHUNK_REMAINING_CAPACITY(chunk) >= at_most);
-  read_result = tor_socket_recv(fd, CHUNK_WRITE_PTR(chunk), at_most, 0);
   if (read_result < 0) {
     int e = tor_socket_errno(fd);
     if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */
@@ -573,6 +600,14 @@
     return 0;
   } else { /* actually got bytes. */
     buf->datalen += read_result;
+#if 0 && defined(HAVE_READV) && !defined(WIN32)
+    while ((size_t)read_result > CHUNK_REMAINING_CAPACITY(chunk)) {
+      chunk->datalen += CHUNK_REMAINING_CAPACITY(chunk);
+      read_result -= CHUNK_REMAINING_CAPACITY(chunk);
+      chunk = chunk->next;
+      tor_assert(chunk);
+    }
+#endif
     chunk->datalen += read_result;
     log_debug(LD_NET,"Read %ld bytes. %d on inbuf.", (long)read_result,
               (int)buf->datalen);
@@ -707,9 +742,27 @@
             size_t *buf_flushlen)
 {
   ssize_t write_result;
+#if 0 && defined(HAVE_WRITEV) && !defined(WIN32)
+  struct iovec iov[N_IOV];
+  int i;
+  size_t remaining = sz;
+  for (i=0; chunk && i < N_IOV && remaining; ++i) {
+    iov[i].iov_base = chunk->data;
+    if (remaining > chunk->datalen)
+      iov[i].iov_len = chunk->datalen;
+    else
+      iov[i].iov_len = remaining;
+    remaining -= iov[i].iov_len;
+    chunk = chunk->next;
+  }
+  write_result = writev(s, iov, i);
+#else
+  if (sz > chunk->datalen)
+    sz = chunk->datalen;
+  write_result = tor_socket_send(s, chunk->data, sz, 0);
+#endif
 
-  tor_assert(sz <= chunk->datalen);
-  write_result = tor_socket_send(s, chunk->data, sz, 0);
+
   if (write_result < 0) {
     int e = tor_socket_errno(s);
     if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */