From: Timo Sirainen Date: Sun, 21 Sep 2003 17:55:36 +0000 (+0300) Subject: Added support for Boehm GC. However it seems to be crashing for some reason X-Git-Tag: 1.1.alpha1~4320 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81a07ac5ff4bb89761c2cf8d3e56ae902e4648e1;p=thirdparty%2Fdovecot%2Fcore.git Added support for Boehm GC. However it seems to be crashing for some reason with me.. --HG-- branch : HEAD --- diff --git a/configure.in b/configure.in index e372e2cc41..c70e9c74ac 100644 --- a/configure.in +++ b/configure.in @@ -160,6 +160,19 @@ AC_ARG_WITH(ssldir, ) AC_SUBST(ssldir) +AC_ARG_WITH(gc, +[ --with-gc Use Boehm garbage collector (currently broken)], + if test x$withval = xyes; then + want_gc=yes + else + if test "x$withval" = xno; then + want_gc=no + else + want_gc=yes + fi + fi, + want_gc=no) + AC_ARG_WITH(pop3d, [ --with-pop3d Build POP3 server (default)], if test x$withval = xno; then @@ -839,6 +852,20 @@ if test "$have_ssl" != "no"; then AC_DEFINE(HAVE_SSL,, Build with SSL/TLS support) fi +dnl ** +dnl ** Garbage Collector +dnl ** + +if test "$want_gc" = "yes"; then + AC_CHECK_LIB(gc, GC_malloc, [ + AC_CHECK_HEADERS(gc/gc.h gc.h) + AC_DEFINE(USE_GC,, Define if you want to use Boehm GC) + LIBS="$LIBS -lgc" + ], [ + want_gc=no + ]) +fi + dnl ** dnl ** userdb and passdb checks dnl ** diff --git a/src/lib/data-stack.c b/src/lib/data-stack.c index f477cd571d..f141c6512f 100644 --- a/src/lib/data-stack.c +++ b/src/lib/data-stack.c @@ -7,6 +7,12 @@ #include +#ifdef HAVE_GC_GC_H +# include +#elif defined (HAVE_GC_H) +# include +#endif + /* Use malloc() and free() for all memory allocations. Useful for debugging memory corruption. */ /* #define DISABLE_DATA_STACK */ @@ -21,6 +27,12 @@ # define INITIAL_STACK_SIZE (1024*32) #endif +#ifdef DEBUG +# define CLEAR_CHR 0xde +#elif defined(USE_GC) +# define CLEAR_CHR 0 +#endif + struct stack_block { struct stack_block *next; @@ -75,7 +87,12 @@ unsigned int t_push(void) frame_pos = 0; if (unused_frame_blocks == NULL) { /* allocate new block */ +#ifndef USE_GC frame_block = calloc(sizeof(*frame_block), 1); +#else + frame_block = GC_malloc(sizeof(*frame_block)); + memset(frame_block, 0, sizeof(*frame_block)); +#endif if (frame_block == NULL) i_panic("t_push(): Out of memory"); } else { @@ -96,6 +113,7 @@ unsigned int t_push(void) return data_stack_frame++; } +#ifndef USE_GC static void free_blocks(struct stack_block *block) { struct stack_block *next; @@ -115,6 +133,7 @@ static void free_blocks(struct stack_block *block) block = next; } } +#endif unsigned int t_pop(void) { @@ -127,14 +146,16 @@ unsigned int t_pop(void) /* update the current block */ current_block = current_frame_block->block[frame_pos]; current_block->left = current_frame_block->block_space_used[frame_pos]; -#ifdef DEBUG +#ifdef CLEAR_CHR memset(STACK_BLOCK_DATA(current_block) + - (current_block->size - current_block->left), 0xde, + (current_block->size - current_block->left), CLEAR_CHR, current_block->left); #endif if (current_block->next != NULL) { /* free unused blocks */ +#ifndef USE_GC free_blocks(current_block->next); +#endif current_block->next = NULL; } @@ -163,7 +184,11 @@ static struct stack_block *mem_block_alloc(size_t min_size) prev_size = current_block == NULL ? 0 : current_block->size; alloc_size = nearest_power(prev_size + min_size); +#ifndef USE_GC block = malloc(SIZEOF_MEMBLOCK + alloc_size); +#else + block = GC_malloc_atomic(SIZEOF_MEMBLOCK + alloc_size); +#endif if (block == NULL) { i_panic("mem_block_alloc(): " "Out of memory when allocating %"PRIuSIZE_T" bytes", @@ -342,19 +367,28 @@ void data_stack_deinit(void) if (frame_pos != BLOCK_FRAME_COUNT-1) i_panic("Missing t_pop() call"); +#ifndef USE_GC while (unused_frame_blocks != NULL) { struct stack_frame_block *frame_block = unused_frame_blocks; unused_frame_blocks = unused_frame_blocks->prev; - free(frame_block); + free(frame_block); } free(current_block); free(unused_block); +#endif + unused_frame_blocks = NULL; + current_block = NULL; + unused_block = NULL; } #else +#ifdef USE_GC +# error No GC with disabled data stack +#endif + struct stack_frame { struct stack_frame *next; struct frame_alloc *allocs; diff --git a/src/lib/mempool-alloconly.c b/src/lib/mempool-alloconly.c index 1505a3b6bb..761488c329 100644 --- a/src/lib/mempool-alloconly.c +++ b/src/lib/mempool-alloconly.c @@ -7,6 +7,12 @@ #include +#ifdef HAVE_GC_GC_H +# include +#elif defined (HAVE_GC_H) +# include +#endif + #define MAX_ALLOC_SIZE SSIZE_T_MAX struct alloconly_pool { @@ -64,16 +70,21 @@ static struct pool static_alloconly_pool = { pool_t pool_alloconly_create(const char *name, size_t size) { struct alloconly_pool *apool; - int len; + size_t len; - len = strlen(name); + len = strlen(name)+1; - apool = calloc(SIZEOF_ALLOCONLYPOOL + len+1, 1); +#ifndef USE_GC + apool = calloc(SIZEOF_ALLOCONLYPOOL + len, 1); +#else + apool = GC_malloc(SIZEOF_ALLOCONLYPOOL + len); + memset(apool, 0, SIZEOF_ALLOCONLYPOOL + len); +#endif if (apool == NULL) i_panic("pool_alloconly_create(): Out of memory"); apool->pool = static_alloconly_pool; apool->refcount = 1; - memcpy(apool->name, name, len+1); + memcpy(apool->name, name, len); block_alloc(apool, size); return (struct pool *) apool; @@ -88,8 +99,14 @@ static void pool_alloconly_destroy(struct alloconly_pool *apool) #ifdef DEBUG memset(apool->block, 0xde, SIZEOF_POOLBLOCK + apool->block->size); #endif + +#ifndef USE_GC free(apool->block); free(apool); +#else + apool->block = NULL; + apool = NULL; +#endif } static const char *pool_alloconly_get_name(pool_t pool) @@ -131,7 +148,12 @@ static void block_alloc(struct alloconly_pool *apool, size_t size) } #endif +#ifndef USE_GC block = calloc(size, 1); +#else + block = GC_malloc(size); + memset(block, 0, size); +#endif if (block == NULL) i_panic("block_alloc(): Out of memory"); block->prev = apool->block; @@ -230,7 +252,9 @@ static void pool_alloconly_clear(pool_t pool) #ifdef DEBUG memset(block, 0xde, SIZEOF_POOLBLOCK + block->size); #endif +#ifndef USE_GC free(block); +#endif } /* clear the block */ diff --git a/src/lib/mempool-system.c b/src/lib/mempool-system.c index 3566c0a07f..5e5f0eba03 100644 --- a/src/lib/mempool-system.c +++ b/src/lib/mempool-system.c @@ -7,6 +7,12 @@ #include +#ifdef HAVE_GC_GC_H +# include +#elif defined (HAVE_GC_H) +# include +#endif + static const char *pool_system_get_name(pool_t pool); static void pool_system_ref(pool_t pool); static void pool_system_unref(pool_t pool); @@ -55,17 +61,25 @@ static void *pool_system_malloc(pool_t pool __attr_unused__, size_t size) if (size == 0 || size > SSIZE_T_MAX) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); +#ifndef USE_GC mem = calloc(size, 1); +#else + mem = GC_malloc(size); + memset(mem, 0, size); +#endif if (mem == NULL) i_panic("pool_system_malloc(): Out of memory"); return mem; } -static void pool_system_free(pool_t pool __attr_unused__, void *mem) +static void pool_system_free(pool_t pool __attr_unused__, + void *mem __attr_unused__) { +#ifndef USE_GC if (mem != NULL) free(mem); +#endif } static void *pool_system_realloc(pool_t pool __attr_unused__, void *mem, @@ -74,7 +88,11 @@ static void *pool_system_realloc(pool_t pool __attr_unused__, void *mem, if (new_size == 0 || new_size > SSIZE_T_MAX) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size); +#ifndef USE_GC mem = realloc(mem, new_size); +#else + mem = GC_realloc(mem, new_size); +#endif if (mem == NULL) i_panic("pool_system_realloc(): Out of memory");