diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-06-11 17:56:52 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-06-11 17:56:52 +0000 |
commit | a886e86cbd634cdf1411bae5280eb7c5275d08da (patch) | |
tree | 31ab555f15dd59b3eeff7c1303b14acea42f3389 | |
parent | b2fcc417d4e515059018f282149f95df9bd6caab (diff) | |
download | tor-a886e86cbd634cdf1411bae5280eb7c5275d08da.tar.gz tor-a886e86cbd634cdf1411bae5280eb7c5275d08da.zip |
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.
svn:r15133
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | src/or/buffers.c | 61 |
2 files changed, 59 insertions, 6 deletions
diff --git a/configure.in b/configure.in index d33da17e6e..cd68f4e440 100644 --- a/configure.in +++ b/configure.in @@ -196,7 +196,7 @@ dnl ------------------------------------------------------------------- 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_SYS_LARGEFILE 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 diff --git a/src/or/buffers.c b/src/or/buffers.c index daef1f9357..0f7623a4ce 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -15,6 +15,13 @@ const char buffers_c_id[] = **/ #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 @@ buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped) 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 @@ read_to_chunk(buf_t *buf, chunk_t *chunk, int fd, size_t at_most, int *reached_eof) { ssize_t read_result; - - tor_assert(CHUNK_REMAINING_CAPACITY(chunk) >= at_most); +#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 + if (read_result < 0) { int e = tor_socket_errno(fd); if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */ @@ -573,6 +600,14 @@ read_to_chunk(buf_t *buf, chunk_t *chunk, int fd, size_t at_most, 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 @@ flush_chunk(int s, buf_t *buf, chunk_t *chunk, size_t sz, size_t *buf_flushlen) { ssize_t write_result; - - tor_assert(sz <= chunk->datalen); +#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 + + if (write_result < 0) { int e = tor_socket_errno(s); if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */ |