Browse Source

r12704@catbus: nickm | 2007-05-09 17:43:34 -0400
Periodically clean the freelist of buffer memory chunks.


svn:r10149

Nick Mathewson 17 years ago
parent
commit
b248ed620f
4 changed files with 31 additions and 2 deletions
  1. 2 0
      ChangeLog
  2. 27 2
      src/or/buffers.c
  3. 1 0
      src/or/main.c
  4. 1 0
      src/or/or.h

+ 2 - 0
ChangeLog

@@ -40,6 +40,8 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
       the server), and avoids the nasty Windows socketpair() workaround.
     - Keep unused 4k buffers on a free list, rather than wasting 8k for every
       single inactive connection_t.
+    - Free items from the 4k-buffer free list when they haven't been used
+      for a while.
 
   o Minor features (build):
     - Make autoconf search for libevent, openssl, and zlib consistently.

+ 27 - 2
src/or/buffers.c

@@ -161,7 +161,7 @@ _split_range(buf_t *buf, char *at, size_t *len,
 /** DOCDOC */
 static char *free_mem_list = NULL;
 static int free_mem_list_len = 0;
-/*XXXX020 Actually remove stuff from freelist when it gets too big */
+static int free_mem_list_lowwater = 0;
 
 /** DOCDOC */
 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;
 }
 
+/** DOCDOC 64k of 4k buffers. */
+#define BUF_FREELIST_SLACK 16
+
+/** DOCDOC */
+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;
+}
+
 /** Change a buffer's capacity. <b>new_capacity</b> must be \>=
  * buf->datalen. */
 static void

+ 1 - 0
src/or/main.c

@@ -1021,6 +1021,7 @@ run_scheduled_events(time_t now)
         buf_shrink(conn->inbuf);
     }
     clean_cell_pool();
+    buf_shrink_freelist();
     time_to_shrink_memory = now + MEM_SHRINK_INTERVAL;
   }
 

+ 1 - 0
src/or/or.h

@@ -2020,6 +2020,7 @@ 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);
+void buf_shrink_freelist(void);
 
 size_t buf_datalen(const buf_t *buf);
 size_t buf_capacity(const buf_t *buf);