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
This commit is contained in:
Nick Mathewson 2005-05-02 23:17:08 +00:00
parent 9c683c7613
commit a312ce1d3b
4 changed files with 40 additions and 4 deletions

View File

@ -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. */ /** 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; off_t offset;
#ifdef CHECK_AFTER_RESIZE #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); peek_from_buf(tmp, buf->datalen, buf);
#endif #endif
if (buf->len == new_capacity)
return;
offset = buf->cur - buf->mem; offset = buf->cur - buf->mem;
if (offset + buf->datalen >= new_capacity) { if (offset + buf->datalen >= new_capacity) {
/* We need to move stuff before we shrink. */ /* 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; return 0;
} }
#if 0
/** If the buffer is at least 2*MIN_GREEDY_SHRINK_SIZE bytes in capacity, /** 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 * 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 * 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); (int)buf->len, (int)new_len);
buf_resize(buf, new_len); buf_resize(buf, new_len);
} }
#else
#define buf_shrink_if_underfull(buf) do {} while (0)
#endif
void void
buf_shrink(buf_t *buf) 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_new_with_capacity(size_t size) {
buf_t *buf; buf_t *buf;
buf = tor_malloc(sizeof(buf_t)); buf = tor_malloc_zero(sizeof(buf_t));
buf->magic = BUFFER_MAGIC; buf->magic = BUFFER_MAGIC;
buf->cur = buf->mem = GUARDED_MEM(tor_malloc(ALLOC_LEN(size))); buf->cur = buf->mem = GUARDED_MEM(tor_malloc(ALLOC_LEN(size)));
SET_GUARDS(buf->mem, size); SET_GUARDS(buf->mem, size);
buf->len = size; buf->len = size;
buf->datalen = 0;
// memset(buf->mem,0,size);
assert_buf_ok(buf); assert_buf_ok(buf);
return buf; return buf;

View File

@ -1036,12 +1036,22 @@ loop_again:
*/ */
static int connection_read_to_buf(connection_t *conn, int *max_to_read) { static int connection_read_to_buf(connection_t *conn, int *max_to_read) {
int result, at_most = *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 */ if (at_most == -1) { /* we need to initialize it */
/* how many bytes are we allowed to read? */ /* how many bytes are we allowed to read? */
at_most = connection_bucket_read_limit(conn); 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) { if (connection_speaks_cells(conn) && conn->state > OR_CONN_STATE_PROXY_READING) {
int pending; int pending;
if (conn->state == OR_CONN_STATE_HANDSHAKING) { 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); 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 /* Call even if result is 0, since the global read bucket may
* have reached 0 on a different conn, and this guy needs to * have reached 0 on a different conn, and this guy needs to
* know to stop reading. */ * know to stop reading. */

View File

@ -103,6 +103,7 @@ static int nt_service_is_stopped(void);
#endif #endif
#define CHECK_DESCRIPTOR_INTERVAL 60 /* one minute */ #define CHECK_DESCRIPTOR_INTERVAL 60 /* one minute */
#define BUF_SHRINK_INTERVAL 180 /* three minutes */
#define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60) /* 20 minutes */ #define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60) /* 20 minutes */
/********* END VARIABLES ************/ /********* END VARIABLES ************/
@ -606,6 +607,7 @@ static void run_scheduled_events(time_t now) {
static time_t last_rotated_certificate = 0; static time_t last_rotated_certificate = 0;
static time_t time_to_check_listeners = 0; static time_t time_to_check_listeners = 0;
static time_t time_to_check_descriptor = 0; static time_t time_to_check_descriptor = 0;
static time_t time_to_shrink_buffers = 0;
or_options_t *options = get_options(); or_options_t *options = get_options();
int i; int i;
@ -744,6 +746,16 @@ static void run_scheduled_events(time_t now) {
for (i=0;i<nfds;i++) { for (i=0;i<nfds;i++) {
run_connection_housekeeping(i, now); 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... */ /** 6. And remove any marked circuits... */
circuit_close_all_marked(); circuit_close_all_marked();

View File

@ -1123,9 +1123,11 @@ buf_t *buf_new(void);
buf_t *buf_new_with_capacity(size_t size); buf_t *buf_new_with_capacity(size_t size);
void buf_free(buf_t *buf); void buf_free(buf_t *buf);
void buf_clear(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_datalen(const buf_t *buf);
size_t buf_capacity(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); 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); int read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof);