Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib/mempool-system-clean.c @ 9532:00cd9aacd03c HEAD
Updated copyright notices to include year 2010.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 25 Jan 2010 01:18:58 +0200 |
parents | d6fcb6d050ba |
children |
line wrap: on
line source
/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */ /* @UNSAFE: whole file */ #include "lib.h" #include "safe-memset.h" #include "mempool.h" #include <stdlib.h> #ifndef HAVE_MALLOC_USABLE_SIZE /* no extra includes needed */ #elif defined (HAVE_MALLOC_NP_H) # include <malloc_np.h> /* FreeBSD */ #elif defined (HAVE_MALLOC_H) # include <malloc.h> /* Linux */ #endif #ifdef HAVE_GC_GC_H # include <gc/gc.h> #elif defined (HAVE_GC_H) # include <gc.h> #endif /* use the maximum of required memory alignment and sizeof(void *) (sizeof(size_t) is assumed to be same. it always is.) */ #if MEM_ALIGN_SIZE > SIZEOF_VOID_P # define EXTRA_SIZE_SPACE MEM_ALIGN_SIZE #else # define EXTRA_SIZE_SPACE SIZEOF_VOID_P #endif /* FIXME: Disabled for now, broken with Valgrind and HP-UX. */ #undef HAVE_MALLOC_USABLE_SIZE static const char *pool_system_clean_get_name(pool_t pool); static void pool_system_clean_ref(pool_t pool); static void pool_system_clean_unref(pool_t *pool); static void *pool_system_clean_malloc(pool_t pool, size_t size); static void pool_system_clean_free(pool_t pool, void *mem); static void *pool_system_clean_realloc(pool_t pool, void *mem, size_t old_size, size_t new_size); static void pool_system_clean_clear(pool_t pool); static size_t pool_system_clean_get_max_easy_alloc_size(pool_t pool); static struct pool_vfuncs static_system_clean_pool_vfuncs = { pool_system_clean_get_name, pool_system_clean_ref, pool_system_clean_unref, pool_system_clean_malloc, pool_system_clean_free, pool_system_clean_realloc, pool_system_clean_clear, pool_system_clean_get_max_easy_alloc_size }; static struct pool static_system_clean_pool = { MEMBER(v) &static_system_clean_pool_vfuncs, MEMBER(alloconly_pool) FALSE, MEMBER(datastack_pool) FALSE }; pool_t system_clean_pool = &static_system_clean_pool; static const char *pool_system_clean_get_name(pool_t pool ATTR_UNUSED) { return "system clean"; } static void pool_system_clean_ref(pool_t pool ATTR_UNUSED) { } static void pool_system_clean_unref(pool_t *pool ATTR_UNUSED) { } static size_t mem_get_size(void *mem) { #ifdef USE_GC return GC_size(mem); #elif defined(HAVE_MALLOC_USABLE_SIZE) return malloc_usable_size(mem); #else return *((size_t *)PTR_OFFSET(mem, -EXTRA_SIZE_SPACE)); #endif } static void *pool_system_clean_malloc(pool_t pool ATTR_UNUSED, size_t size) { void *mem; if (unlikely(size == 0 || size > SSIZE_T_MAX)) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); #ifdef USE_GC mem = GC_malloc(size); #else #ifndef HAVE_MALLOC_USABLE_SIZE size += EXTRA_SIZE_SPACE; #endif mem = calloc(size, 1); #endif if (unlikely(mem == NULL)) { i_fatal_status(FATAL_OUTOFMEM, "pool_system_malloc(%"PRIuSIZE_T "): Out of memory", size); } #if !defined(USE_GC) && !defined(HAVE_MALLOC_USABLE_SIZE) { size_t *saved_size = mem; *saved_size = size - EXTRA_SIZE_SPACE; mem = PTR_OFFSET(mem, EXTRA_SIZE_SPACE); } #endif return mem; } static void pool_system_clean_free(pool_t pool ATTR_UNUSED, void *mem) { if (mem != NULL) { safe_memset(mem, 0, mem_get_size(mem)); #ifndef USE_GC #ifndef HAVE_MALLOC_USABLE_SIZE mem = PTR_OFFSET(mem, -EXTRA_SIZE_SPACE); #endif free(mem); #endif } } static void *pool_system_clean_realloc(pool_t pool ATTR_UNUSED, void *mem, size_t old_size, size_t new_size) { void *new_mem; size_t old_alloc_size; if (unlikely(new_size == 0 || new_size > SSIZE_T_MAX)) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size); new_mem = pool_system_clean_malloc(pool, new_size); if (mem != NULL) { #if !defined(USE_GC) && defined(HAVE_MALLOC_USABLE_SIZE) i_assert(old_size == (size_t)-1 || old_size <= malloc_usable_size(mem)); #endif old_alloc_size = mem_get_size(mem); memcpy(new_mem, mem, I_MIN(old_alloc_size, new_size)); if (old_size < new_size) { /* clear new data */ memset((char *)new_mem + old_size, 0, new_size - old_size); } pool_system_clean_free(pool, mem); } return new_mem; } static void ATTR_NORETURN pool_system_clean_clear(pool_t pool ATTR_UNUSED) { i_panic("pool_system_clean_clear() must not be called"); } static size_t pool_system_clean_get_max_easy_alloc_size(pool_t pool ATTR_UNUSED) { return 0; }