diff options
author | Matt Johnston <matt@ucc.asn.au> | 2017-05-21 10:54:11 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2017-05-21 10:54:11 +0800 |
commit | fb8fb7fed0bb822ccc11ed20229db51a3991a0e5 (patch) | |
tree | 55ee48f994e54c285846be8487ffe23876840d9b /dbmalloc.c | |
parent | 1abd239b9ded3386fac8d553aa4652da88a52d58 (diff) |
add dbmalloc epoch cleanup
--HG--
branch : fuzz
Diffstat (limited to 'dbmalloc.c')
-rw-r--r-- | dbmalloc.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/dbmalloc.c b/dbmalloc.c new file mode 100644 index 0000000..e62e020 --- /dev/null +++ b/dbmalloc.c @@ -0,0 +1,128 @@ +#include "dbmalloc.h" +#include "dbutil.h" + +#define LIST_SIZE 1000 + +struct dbmalloc_header { + unsigned int index; + unsigned int epoch; +}; + +static struct dbmalloc_header* dbmalloc_list[LIST_SIZE]; + +unsigned int current_epoch = 0; + +void m_malloc_set_epoch(unsigned int epoch) { + current_epoch = epoch; +} + +void m_malloc_free_epoch(unsigned int epoch) { + unsigned int i; + unsigned int freed = 0; + for (i = 0; i < LIST_SIZE; i++) { + if (dbmalloc_list[i] != NULL) { + assert(dbmalloc_list[i]->index == i); + if (dbmalloc_list[i]->epoch == epoch) { + free(dbmalloc_list[i]); + dbmalloc_list[i] = NULL; + freed++; + } + } + } + TRACE(("free_epoch freed %d", freed)) +} + +static void put_alloc(struct dbmalloc_header *header) { + unsigned int i; + for (i = 0; i < LIST_SIZE; i++) { + if (dbmalloc_list[i] == NULL) { + dbmalloc_list[i] = header; + header->index = i; + return; + } + } + dropbear_exit("ran out of dbmalloc entries"); +} + +static void remove_alloc(struct dbmalloc_header *header) { + assert(header->index < LIST_SIZE); + assert(dbmalloc_list[header->index] == header); + assert(header->epoch == current_epoch); + dbmalloc_list[header->index] = NULL; +} + +static struct dbmalloc_header* get_header(void* ptr) { + char* bptr = ptr; + return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)]; +} + +void * m_malloc(size_t size) { + char* mem = NULL; + struct dbmalloc_header* header = NULL; + + if (size == 0 || size > 1e9) { + dropbear_exit("m_malloc failed"); + } + + size = size + sizeof(struct dbmalloc_header); + + mem = calloc(1, size); + if (mem == NULL) { + dropbear_exit("m_malloc failed"); + } + header = (struct dbmalloc_header*)mem; + put_alloc(header); + header->epoch = current_epoch; + return &mem[sizeof(struct dbmalloc_header)]; +} + +void * m_calloc(size_t nmemb, size_t size) { + assert(nmemb <= 1000 && size <= 10000); + return m_malloc(nmemb*size); +} + +void * m_realloc(void* ptr, size_t size) { + char* mem = NULL; + struct dbmalloc_header* header = NULL; + if (size == 0 || size > 1e9) { + dropbear_exit("m_realloc failed"); + } + + header = get_header(ptr); + remove_alloc(header); + + size = size + sizeof(struct dbmalloc_header); + mem = realloc(header, size); + if (mem == NULL) { + dropbear_exit("m_realloc failed"); + } + + header = (struct dbmalloc_header*)mem; + put_alloc(header); + return &mem[sizeof(struct dbmalloc_header)]; +} + +void m_free_direct(void* ptr) { + struct dbmalloc_header* header = NULL; + if (!ptr) { + return; + } + header = get_header(ptr); + remove_alloc(header); + free(header); +} + +void * m_strdup(const char * str) { + char* ret; + unsigned int len; + len = strlen(str); + + ret = m_malloc(len+1); + if (ret == NULL) { + dropbear_exit("m_strdup failed"); + } + memcpy(ret, str, len+1); + return ret; +} + + |