mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 14:40:51 +01:00
r19243@catbus: nickm | 2008-04-08 13:28:59 -0400
Use a freelist to hold a few recent memarea chunks. We do a kazillion memarea allocs and frees; that cant be good for us. svn:r14319
This commit is contained in:
parent
a627407fcb
commit
31153d6374
3 changed files with 54 additions and 12 deletions
|
@ -53,6 +53,8 @@ typedef struct memarea_chunk_t {
|
||||||
|
|
||||||
#define CHUNK_HEADER_SIZE STRUCT_OFFSET(memarea_chunk_t, u)
|
#define CHUNK_HEADER_SIZE STRUCT_OFFSET(memarea_chunk_t, u)
|
||||||
|
|
||||||
|
#define CHUNK_SIZE 8192
|
||||||
|
|
||||||
/** A memarea_t is an allocation region for a set of small memory requests
|
/** A memarea_t is an allocation region for a set of small memory requests
|
||||||
* that will all be freed at once. */
|
* that will all be freed at once. */
|
||||||
struct memarea_t {
|
struct memarea_t {
|
||||||
|
@ -60,25 +62,49 @@ struct memarea_t {
|
||||||
size_t chunk_size; /**<Size to use when allocating chunks.*/
|
size_t chunk_size; /**<Size to use when allocating chunks.*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_FREELIST_LEN 4
|
||||||
|
int freelist_len=0;
|
||||||
|
static memarea_chunk_t *freelist = NULL;
|
||||||
|
|
||||||
/** Helper: allocate a new memarea chunk of around <b>chunk_size</b> bytes. */
|
/** Helper: allocate a new memarea chunk of around <b>chunk_size</b> bytes. */
|
||||||
static memarea_chunk_t *
|
static memarea_chunk_t *
|
||||||
alloc_chunk(size_t chunk_size)
|
alloc_chunk(size_t sz)
|
||||||
{
|
{
|
||||||
memarea_chunk_t *res = tor_malloc_roundup(&chunk_size);
|
(void)sz; /*XXXX021 remove this argument. */
|
||||||
res->next_chunk = NULL;
|
if (freelist) {
|
||||||
res->mem_size = chunk_size - CHUNK_HEADER_SIZE;
|
memarea_chunk_t *res = freelist;
|
||||||
res->next_mem = res->u.mem;
|
freelist = res->next_chunk;
|
||||||
return res;
|
--freelist_len;
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
size_t chunk_size = CHUNK_SIZE;
|
||||||
|
memarea_chunk_t *res = tor_malloc_roundup(&chunk_size);
|
||||||
|
res->next_chunk = NULL;
|
||||||
|
res->mem_size = chunk_size - CHUNK_HEADER_SIZE;
|
||||||
|
res->next_mem = res->u.mem;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Allocate and return new memarea, with chunks of approximately
|
static void
|
||||||
* <b>chunk_size</b> bytes. (There is indeed some overhead.) */
|
chunk_free(memarea_chunk_t *chunk)
|
||||||
|
{
|
||||||
|
if (freelist_len >= MAX_FREELIST_LEN) {
|
||||||
|
++freelist_len;
|
||||||
|
chunk->next_chunk = freelist;
|
||||||
|
freelist = chunk;
|
||||||
|
} else {
|
||||||
|
tor_free(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allocate and return new memarea. */
|
||||||
memarea_t *
|
memarea_t *
|
||||||
memarea_new(size_t chunk_size)
|
memarea_new(size_t chunk_size)/*XXXX021 remove this argument.*/
|
||||||
{
|
{
|
||||||
memarea_t *head = tor_malloc(sizeof(memarea_t));
|
memarea_t *head = tor_malloc(sizeof(memarea_t));
|
||||||
head->first = alloc_chunk(chunk_size);
|
head->first = alloc_chunk(chunk_size);
|
||||||
head->chunk_size = chunk_size;
|
(void)chunk_size;
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +116,7 @@ memarea_drop_all(memarea_t *area)
|
||||||
memarea_chunk_t *chunk, *next;
|
memarea_chunk_t *chunk, *next;
|
||||||
for (chunk = area->first; chunk; chunk = next) {
|
for (chunk = area->first; chunk; chunk = next) {
|
||||||
next = chunk->next_chunk;
|
next = chunk->next_chunk;
|
||||||
tor_free(chunk);
|
chunk_free(chunk);
|
||||||
}
|
}
|
||||||
area->first = NULL; /*fail fast on */
|
area->first = NULL; /*fail fast on */
|
||||||
tor_free(area);
|
tor_free(area);
|
||||||
|
@ -106,13 +132,26 @@ memarea_clear(memarea_t *area)
|
||||||
if (area->first->next_chunk) {
|
if (area->first->next_chunk) {
|
||||||
for (chunk = area->first->next_chunk; chunk; chunk = next) {
|
for (chunk = area->first->next_chunk; chunk; chunk = next) {
|
||||||
next = chunk->next_chunk;
|
next = chunk->next_chunk;
|
||||||
tor_free(chunk);
|
chunk_free(chunk);
|
||||||
}
|
}
|
||||||
area->first->next_chunk = NULL;
|
area->first->next_chunk = NULL;
|
||||||
}
|
}
|
||||||
area->first->next_mem = area->first->u.mem;
|
area->first->next_mem = area->first->u.mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
void
|
||||||
|
memarea_clear_freelist(void)
|
||||||
|
{
|
||||||
|
memarea_chunk_t *chunk, *next;
|
||||||
|
freelist_len = 0;
|
||||||
|
for (chunk = freelist; chunk; chunk = next) {
|
||||||
|
next = chunk->next_chunk;
|
||||||
|
tor_free(chunk);
|
||||||
|
}
|
||||||
|
freelist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return true iff <b>p</b> is in a range that has been returned by an
|
/** Return true iff <b>p</b> is in a range that has been returned by an
|
||||||
* allocation from <b>area</b>. */
|
* allocation from <b>area</b>. */
|
||||||
int
|
int
|
||||||
|
|
|
@ -19,6 +19,7 @@ char *memarea_strdup(memarea_t *area, const char *s);
|
||||||
char *memarea_strndup(memarea_t *area, const char *s, size_t n);
|
char *memarea_strndup(memarea_t *area, const char *s, size_t n);
|
||||||
void memarea_get_stats(memarea_t *area,
|
void memarea_get_stats(memarea_t *area,
|
||||||
size_t *allocated_out, size_t *used_out);
|
size_t *allocated_out, size_t *used_out);
|
||||||
|
void memarea_clear_freelist(void);
|
||||||
void memarea_assert_ok(memarea_t *area);
|
void memarea_assert_ok(memarea_t *area);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@ const char main_c_id[] =
|
||||||
#ifdef USE_DMALLOC
|
#ifdef USE_DMALLOC
|
||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "memarea.h"
|
||||||
|
|
||||||
void evdns_shutdown(int);
|
void evdns_shutdown(int);
|
||||||
|
|
||||||
|
@ -1858,6 +1859,7 @@ tor_free_all(int postfork)
|
||||||
entry_guards_free_all();
|
entry_guards_free_all();
|
||||||
connection_free_all();
|
connection_free_all();
|
||||||
buf_shrink_freelists(1);
|
buf_shrink_freelists(1);
|
||||||
|
memarea_clear_freelist();
|
||||||
if (!postfork) {
|
if (!postfork) {
|
||||||
config_free_all();
|
config_free_all();
|
||||||
router_free_all();
|
router_free_all();
|
||||||
|
|
Loading…
Add table
Reference in a new issue