|
@@ -161,7 +161,7 @@ _split_range(buf_t *buf, char *at, size_t *len,
|
|
|
|
|
|
static char *free_mem_list = NULL;
|
|
|
static int free_mem_list_len = 0;
|
|
|
-
|
|
|
+static int free_mem_list_lowwater = 0;
|
|
|
|
|
|
|
|
|
static void
|
|
@@ -194,7 +194,8 @@ buf_get_initial_mem(buf_t *buf)
|
|
|
if (free_mem_list) {
|
|
|
mem = free_mem_list;
|
|
|
free_mem_list = *(char**)mem;
|
|
|
- --free_mem_list_len;
|
|
|
+ if (--free_mem_list_len < free_mem_list_lowwater)
|
|
|
+ free_mem_list_lowwater = free_mem_list_len;
|
|
|
log_info(LD_GENERAL, "Got buf mem from freelist. Freelist has %d entries.",
|
|
|
free_mem_list_len);
|
|
|
} else {
|
|
@@ -209,6 +210,30 @@ buf_get_initial_mem(buf_t *buf)
|
|
|
buf->cur = buf->mem;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+#define BUF_FREELIST_SLACK 16
|
|
|
+
|
|
|
+
|
|
|
+void
|
|
|
+buf_shrink_freelist(void)
|
|
|
+{
|
|
|
+ if (free_mem_list_lowwater > BUF_FREELIST_SLACK) {
|
|
|
+ int i;
|
|
|
+ log_info(LD_GENERAL, "We haven't used %d/%d allocated buffer memory "
|
|
|
+ "chunks since the last call(); freeing all but %d of them",
|
|
|
+ free_mem_list_lowwater, free_mem_list_len,
|
|
|
+ BUF_FREELIST_SLACK);
|
|
|
+ for (i = BUF_FREELIST_SLACK; i < free_mem_list_lowwater; ++i) {
|
|
|
+ char *mem = free_mem_list;
|
|
|
+ tor_assert(mem);
|
|
|
+ free_mem_list = *(char**)mem;
|
|
|
+ tor_free(mem);
|
|
|
+ --free_mem_list_len;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ free_mem_list_lowwater = free_mem_list_len;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* buf->datalen. */
|
|
|
static void
|