mempool-system.c revision 478858aa9ca65a7a1b0bc028793d85b9591956a4
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger/* @UNSAFE: whole file */
345648b341f228bd7f0b89f8aa3ecb9c470d817eTimo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "lib.h"
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen#include "safe-memset.h"
5a2cb3d097a2d9a9e930af997e7bf3400a8d840dTimo Sirainen#include "mempool.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include <stdlib.h>
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#ifndef HAVE_MALLOC_USABLE_SIZE
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainen/* no extra includes needed */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#elif defined (HAVE_MALLOC_NP_H)
16f46efe0e090fe6975acf012a61a160f4787985Andrey Panin# include <malloc_np.h> /* FreeBSD */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#elif defined (HAVE_MALLOC_H)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen# include <malloc.h> /* Linux */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#ifdef HAVE_GC_GC_H
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen# include <gc/gc.h>
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#elif defined (HAVE_GC_H)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen# include <gc.h>
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
16f46efe0e090fe6975acf012a61a160f4787985Andrey Panin#define CLEAR_CHR 0xde
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic const char *pool_system_get_name(pool_t pool);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic void pool_system_ref(pool_t pool);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic void pool_system_unref(pool_t *pool);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenstatic void *pool_system_malloc(pool_t pool, size_t size);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic void pool_system_free(pool_t pool, void *mem);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic void *pool_system_realloc(pool_t pool, void *mem,
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen size_t old_size, size_t new_size);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic void pool_system_clear(pool_t pool);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic size_t pool_system_get_max_easy_alloc_size(pool_t pool);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstatic struct pool_vfuncs static_system_pool_vfuncs = {
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen pool_system_get_name,
7242e1ce7803b83bc82e239ef111b47c1c72dd4bAndrey Panin
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen pool_system_ref,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen pool_system_unref,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen pool_system_malloc,
c57776c06ec99ba9b0dafdbf9475ea72ea8ca134Timo Sirainen pool_system_free,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen pool_system_realloc,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen pool_system_clear,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen pool_system_get_max_easy_alloc_size
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen};
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainenstruct pool static_system_pool = {
4051fa1f367553cac34f74c2e332a678390bcee5Timo Sirainen .v = &static_system_pool_vfuncs,
50782de8a9d5ebe11ee61496b4e695a1d3875230Timo Sirainen
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen .alloconly_pool = FALSE,
4051fa1f367553cac34f74c2e332a678390bcee5Timo Sirainen .datastack_pool = FALSE
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen};
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainenpool_t system_pool = &static_system_pool;
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainenstatic const char *pool_system_get_name(pool_t pool ATTR_UNUSED)
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen{
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen return "system";
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen}
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainenstatic void pool_system_ref(pool_t pool ATTR_UNUSED)
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen{
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen}
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainenstatic void pool_system_unref(pool_t *pool ATTR_UNUSED)
59beb411159176b39e48a52d60dd3239732e67b4Timo Sirainen{
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen}
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen
15cb9549422ccee416b21d26fec97a556ad0fa36Florian Zeitzstatic void *pool_system_malloc(pool_t pool ATTR_UNUSED, size_t size)
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen{
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen void *mem;
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (unlikely(size == 0 || size > SSIZE_T_MAX))
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen#ifndef USE_GC
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen mem = calloc(size, 1);
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen#else
2c38504860da8a8de915f8e0f5f39d7e7bd00cf8Timo Sirainen mem = GC_malloc(size);
2c38504860da8a8de915f8e0f5f39d7e7bd00cf8Timo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen if (unlikely(mem == NULL)) {
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen i_fatal_status(FATAL_OUTOFMEM, "pool_system_malloc(%"PRIuSIZE_T
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen "): Out of memory", size);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen }
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen return mem;
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen}
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainenstatic void pool_system_free(pool_t pool ATTR_UNUSED,
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen void *mem ATTR_UNUSED)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen{
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#if !defined(USE_GC) && defined(HAVE_MALLOC_USABLE_SIZE) && defined(DEBUG)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen safe_memset(mem, CLEAR_CHR, malloc_usable_size(mem));
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#endif
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#ifndef USE_GC
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen free(mem);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#endif
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen}
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainenstatic void *pool_system_realloc(pool_t pool ATTR_UNUSED, void *mem,
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen size_t old_size, size_t new_size)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen{
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen if (unlikely(new_size == 0 || new_size > SSIZE_T_MAX))
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#if !defined(USE_GC) && defined(HAVE_MALLOC_USABLE_SIZE)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen i_assert(old_size == (size_t)-1 || mem == NULL ||
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen old_size <= malloc_usable_size(mem));
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#endif
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#ifndef USE_GC
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen mem = realloc(mem, new_size);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#else
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen mem = GC_realloc(mem, new_size);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen#endif
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen if (unlikely(mem == NULL)) {
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen i_fatal_status(FATAL_OUTOFMEM, "pool_system_realloc(%"PRIuSIZE_T
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen "): Out of memory", new_size);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen }
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen if (old_size < new_size) {
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen /* clear new data */
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen memset((char *) mem + old_size, 0, new_size - old_size);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen }
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen return mem;
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen}
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainen
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainenstatic void ATTR_NORETURN
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainenpool_system_clear(pool_t pool ATTR_UNUSED)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen{
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen i_panic("pool_system_clear() must not be called");
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen}
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainenstatic size_t pool_system_get_max_easy_alloc_size(pool_t pool ATTR_UNUSED)
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainen{
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen return 0;
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainen}
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainen