X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/707c58248fb6359088b7fa10d43cc0532d2a9a97..3898f97325dbed800d4b424e68a0c2858b8d8be7:/core/nsmalloc.c diff --git a/core/nsmalloc.c b/core/nsmalloc.c index 990fa406..7208b0f0 100644 --- a/core/nsmalloc.c +++ b/core/nsmalloc.c @@ -1,19 +1,21 @@ /* nsmalloc: Simple pooled malloc() thing. */ #include +#include +#include #include "nsmalloc.h" #define __NSMALLOC_C #undef __NSMALLOC_H #include "nsmalloc.h" +#include "../lib/valgrind.h" +#include "../lib/memcheck.h" #include "../core/hooks.h" #include "../core/error.h" struct nsmpool nsmpools[MAXPOOL]; -#ifndef USE_NSMALLOC_VALGRIND - void *nsmalloc(unsigned int poolid, size_t size) { struct nsminfo *nsmp; @@ -25,39 +27,69 @@ void *nsmalloc(unsigned int poolid, size_t size) { if (!nsmp) return NULL; - + + VALGRIND_CREATE_MEMPOOL(nsmp, 0, 0); + nsmp->size=size; nsmpools[poolid].size+=size; nsmpools[poolid].count++; - nsmp->next=nsmpools[poolid].first.next; - nsmp->prev=&nsmpools[poolid].first; - if (nsmpools[poolid].first.next) - nsmpools[poolid].first.next->prev=nsmp; - nsmpools[poolid].first.next=nsmp; + if (nsmpools[poolid].blocks) { + nsmpools[poolid].blocks->prev = nsmp; + } + nsmp->next=nsmpools[poolid].blocks; + nsmp->prev=NULL; + nsmpools[poolid].blocks=nsmp; + + VALGRIND_MEMPOOL_ALLOC(nsmp, nsmp->data, nsmp->size); + + nsmp->redzone = REDZONE_MAGIC; + VALGRIND_MAKE_MEM_NOACCESS(&nsmp->redzone, sizeof(nsmp->redzone)); return (void *)nsmp->data; } -/* we dump core on ptr == NULL */ +void *nscalloc(unsigned int poolid, size_t nmemb, size_t size) { + size_t total = nmemb * size; + void *m; + + m = nsmalloc(poolid, total); + if(!m) + return NULL; + + memset(m, 0, total); + + return m; +} + void nsfree(unsigned int poolid, void *ptr) { struct nsminfo *nsmp; - if (poolid >= MAXPOOL) + if (!ptr || poolid >= MAXPOOL) return; /* evil */ nsmp=(struct nsminfo*)ptr - 1; - /* always set as we have a sentinel */ - nsmp->prev->next=nsmp->next; - if (nsmp->next) - nsmp->next->prev=nsmp->prev; + VALGRIND_MAKE_MEM_DEFINED(&nsmp->redzone, sizeof(nsmp->redzone)); + assert(nsmp->redzone == REDZONE_MAGIC); + + if (nsmp->prev) { + nsmp->prev->next = nsmp->next; + } else + nsmpools[poolid].blocks = NULL; + + if (nsmp->next) { + nsmp->next->prev = nsmp->prev; + } nsmpools[poolid].size-=nsmp->size; nsmpools[poolid].count--; + VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data); free(nsmp); + VALGRIND_DESTROY_MEMPOOL(nsmp); + return; } @@ -78,6 +110,8 @@ void *nsrealloc(unsigned int poolid, void *ptr, size_t size) { /* evil */ nsmp=(struct nsminfo *)ptr - 1; + VALGRIND_MAKE_MEM_DEFINED(nsmp, sizeof(struct nsminfo)); + if (size == nsmp->size) return (void *)nsmp->data; @@ -85,14 +119,21 @@ void *nsrealloc(unsigned int poolid, void *ptr, size_t size) { if (!nsmpn) return NULL; + VALGRIND_MOVE_MEMPOOL(nsmp, nsmpn); + nsmpools[poolid].size+=size-nsmpn->size; nsmpn->size=size; - /* always set as we have a sentinel */ - nsmpn->prev->next=nsmpn; + if (nsmpn->prev) { + nsmpn->prev->next=nsmpn; + } else + nsmpools[poolid].blocks = nsmpn; - if (nsmpn->next) + if (nsmpn->next) { nsmpn->next->prev=nsmpn; + } + + VALGRIND_MEMPOOL_CHANGE(nsmpn, nsmp->data, nsmpn->data, nsmpn->size); return (void *)nsmpn->data; } @@ -103,12 +144,14 @@ void nsfreeall(unsigned int poolid) { if (poolid >= MAXPOOL) return; - for (nsmp=nsmpools[poolid].first.next;nsmp;nsmp=nnsmp) { + for (nsmp=nsmpools[poolid].blocks;nsmp;nsmp=nnsmp) { nnsmp=nsmp->next; + VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data); free(nsmp); + VALGRIND_DESTROY_MEMPOOL(nsmp); } - nsmpools[poolid].first.next=NULL; + nsmpools[poolid].blocks=NULL; nsmpools[poolid].size=0; nsmpools[poolid].count=0; } @@ -117,41 +160,20 @@ void nscheckfreeall(unsigned int poolid) { if (poolid >= MAXPOOL) return; - if (nsmpools[poolid].first.next) { - Error("core",ERR_INFO,"nsmalloc: Blocks still allocated in pool #%d (%s): %lub, %lu items",poolid,nsmpoolnames[poolid]?nsmpoolnames[poolid]:"??",nsmpools[poolid].size,nsmpools[poolid].count); + if (nsmpools[poolid].blocks) { + Error("core",ERR_INFO,"nsmalloc: Blocks still allocated in pool #%d (%s): %zub, %lu items",poolid,nsmpoolnames[poolid]?nsmpoolnames[poolid]:"??",nsmpools[poolid].size,nsmpools[poolid].count); nsfreeall(poolid); } } +void nsinit(void) { + memset(nsmpools, 0, sizeof(nsmpools)); +} + void nsexit(void) { unsigned int i; for (i=0;i