diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-05-02 23:17:08 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-05-02 23:17:08 +0000 |
commit | a312ce1d3b77522b08e91e1524c91e9dfb05f90a (patch) | |
tree | 2d5278d8d300931542417c7272c8eec18bcad4bc /src | |
parent | 9c683c7613ba5d15477e7f21d74cc465e82ac5bd (diff) | |
download | tor-a312ce1d3b77522b08e91e1524c91e9dfb05f90a.tar tor-a312ce1d3b77522b08e91e1524c91e9dfb05f90a.tar.gz |
Change buffer shrinking strategy: only try to shrink once every 3 minutes. Do not try to read over buffer size unless buffer is nearly empty.
svn:r4165
Diffstat (limited to 'src')
-rw-r--r-- | src/or/buffers.c | 13 | ||||
-rw-r--r-- | src/or/connection.c | 17 | ||||
-rw-r--r-- | src/or/main.c | 12 | ||||
-rw-r--r-- | src/or/or.h | 2 |
4 files changed, 40 insertions, 4 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index d1ae871c6..8aaa962de 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -118,7 +118,7 @@ static INLINE void _split_range(buf_t *buf, char *at, size_t *len, } /** Change a buffer's capacity. <b>new_capacity</b> must be \>= buf->datalen. */ -static INLINE void buf_resize(buf_t *buf, size_t new_capacity) +static void buf_resize(buf_t *buf, size_t new_capacity) { off_t offset; #ifdef CHECK_AFTER_RESIZE @@ -134,6 +134,9 @@ static INLINE void buf_resize(buf_t *buf, size_t new_capacity) peek_from_buf(tmp, buf->datalen, buf); #endif + if (buf->len == new_capacity) + return; + offset = buf->cur - buf->mem; if (offset + buf->datalen >= new_capacity) { /* We need to move stuff before we shrink. */ @@ -214,6 +217,7 @@ static INLINE int buf_ensure_capacity(buf_t *buf, size_t capacity) return 0; } +#if 0 /** If the buffer is at least 2*MIN_GREEDY_SHRINK_SIZE bytes in capacity, * and if the buffer is less than 1/8 full, shrink the buffer until * one of the above no longer holds. (We shrink the buffer by @@ -236,6 +240,9 @@ static INLINE void buf_shrink_if_underfull(buf_t *buf) { (int)buf->len, (int)new_len); buf_resize(buf, new_len); } +#else +#define buf_shrink_if_underfull(buf) do {} while (0) +#endif void buf_shrink(buf_t *buf) @@ -278,13 +285,11 @@ static INLINE int buf_nul_terminate(buf_t *buf) */ buf_t *buf_new_with_capacity(size_t size) { buf_t *buf; - buf = tor_malloc(sizeof(buf_t)); + buf = tor_malloc_zero(sizeof(buf_t)); buf->magic = BUFFER_MAGIC; buf->cur = buf->mem = GUARDED_MEM(tor_malloc(ALLOC_LEN(size))); SET_GUARDS(buf->mem, size); buf->len = size; - buf->datalen = 0; -// memset(buf->mem,0,size); assert_buf_ok(buf); return buf; diff --git a/src/or/connection.c b/src/or/connection.c index 55da6899d..665f246b1 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1036,12 +1036,22 @@ loop_again: */ static int connection_read_to_buf(connection_t *conn, int *max_to_read) { int result, at_most = *max_to_read; + size_t bytes_in_buf, more_to_read; if (at_most == -1) { /* we need to initialize it */ /* how many bytes are we allowed to read? */ at_most = connection_bucket_read_limit(conn); } + bytes_in_buf = buf_capacity(conn->inbuf) - buf_datalen(conn->inbuf); + again: + if (at_most > bytes_in_buf && bytes_in_buf >= 1024) { + more_to_read = at_most - bytes_in_buf; + at_most = bytes_in_buf; + } else { + more_to_read = 0; + } + if (connection_speaks_cells(conn) && conn->state > OR_CONN_STATE_PROXY_READING) { int pending; if (conn->state == OR_CONN_STATE_HANDSHAKING) { @@ -1107,6 +1117,13 @@ static int connection_read_to_buf(connection_t *conn, int *max_to_read) { connection_read_bucket_decrement(conn, result); } + if (more_to_read && result == at_most) { + bytes_in_buf = buf_capacity(conn->inbuf) - buf_datalen(conn->inbuf); + tor_assert(bytes_in_buf < 1024); + at_most = more_to_read; + goto again; + } + /* Call even if result is 0, since the global read bucket may * have reached 0 on a different conn, and this guy needs to * know to stop reading. */ diff --git a/src/or/main.c b/src/or/main.c index e2abfaedd..12e8536aa 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -103,6 +103,7 @@ static int nt_service_is_stopped(void); #endif #define CHECK_DESCRIPTOR_INTERVAL 60 /* one minute */ +#define BUF_SHRINK_INTERVAL 180 /* three minutes */ #define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60) /* 20 minutes */ /********* END VARIABLES ************/ @@ -606,6 +607,7 @@ static void run_scheduled_events(time_t now) { static time_t last_rotated_certificate = 0; static time_t time_to_check_listeners = 0; static time_t time_to_check_descriptor = 0; + static time_t time_to_shrink_buffers = 0; or_options_t *options = get_options(); int i; @@ -744,6 +746,16 @@ static void run_scheduled_events(time_t now) { for (i=0;i<nfds;i++) { run_connection_housekeeping(i, now); } + if (time_to_shrink_buffers < now) { + for (i=0;i<nfds;i++) { + connection_t *conn = connection_array[i]; + if (conn->outbuf) + buf_shrink(conn->outbuf); + if (conn->inbuf) + buf_shrink(conn->inbuf); + } + time_to_shrink_buffers = now + BUF_SHRINK_INTERVAL; + } /** 6. And remove any marked circuits... */ circuit_close_all_marked(); diff --git a/src/or/or.h b/src/or/or.h index 31922901c..a96e1eea8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1123,9 +1123,11 @@ buf_t *buf_new(void); buf_t *buf_new_with_capacity(size_t size); void buf_free(buf_t *buf); void buf_clear(buf_t *buf); +void buf_shrink(buf_t *buf); size_t buf_datalen(const buf_t *buf); size_t buf_capacity(const buf_t *buf); +unsigned int buf_n_times_resized(const buf_t *buf); const char *_buf_peek_raw_buffer(const buf_t *buf); int read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof); |