/* * Copyright (c) 2001-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * * $Id: mem.h,v 1.3 2005/06/16 00:09:34 ca Exp $ */ #ifndef SM_HEAP_H #define SM_HEAP_H 1 #include "sm/generic.h" #include "sm/error.h" #include "sm/assert.h" #include "sm/magic.h" #include "sm/debug.h" #ifndef SM_HEAP_CHECK # define SM_HEAP_CHECK 0 #endif #ifndef DMALLOC # define DMALLOC 0 #endif /* memory context, struct defined in heap.c */ typedef struct sm_mctx_S sm_mctx_T, *sm_mctx_P; /* zero out memory? */ #define SM_FL_ZALLOC 0x0001 /* flags for memory context */ #define SM_MCTX_FL_NONE 0x0000 #define SM_MCTX_FL_CHK 0x0001 typedef sm_ret_T (sm_mctx_oom_F)(size_t _size, size_t _cur, size_t _lim, void *_cbctx); #if SM_HEAP_CHECK # include "sm/iostub.h" # define sm_malloc(size) sm_ctxalloc_tagged(NULL, 0, size, __FILE__, __LINE__, SmHeapGroup) # define sm_zalloc(size) sm_ctxalloc_tagged(NULL, SM_FL_ZALLOC, size, __FILE__, __LINE__, SmHeapGroup) # define sm_free(ptr) sm_ctxfree_tagged(NULL, ptr, __FILE__, __LINE__) # define sm_free_size(ptr, size) sm_ctxfree_size_tagged(NULL, ptr, size, __FILE__, __LINE__) # define sm_malloc_tagged(size, __FILE__, __LINE__, SmHeapGroup) \ sm_ctxalloc_tagged(NULL, 0, size, __FILE__, __LINE__, SmHeapGroup) # define sm_zalloc_tagged(size, __FILE__, __LINE__, SmHeapGroup) \ sm_ctxalloc_tagged(NULL, SM_FL_ZALLOC, size, __FILE__, __LINE__, SmHeapGroup) # define sm_ctxmalloc(mctx, size) sm_ctxalloc_tagged(mctx, 0, size, __FILE__, __LINE__, SmHeapGroup) # define sm_ctxfree(mctx, ptr) sm_ctxfree_tagged(mctx, ptr, __FILE__, __LINE__) # define sm_ctxfree_size(mctx, ptr, size) sm_ctxfree_size_tagged(mctx, ptr, size, __FILE__, __LINE__) # define sm_ctxzalloc(mctx, size) sm_ctxalloc_tagged(mctx, SM_FL_ZALLOC, size, __FILE__, __LINE__, SmHeapGroup) void *sm_ctxalloc_tagged(sm_mctx_P _sm_mctx, uint _flags, size_t, char *, int, int); void sm_ctxfree_tagged(sm_mctx_P _sm_mctx, void *, char *, int); void sm_ctxfree_size_tagged(sm_mctx_P _sm_mctx, void *, size_t, char *, int); bool sm_ctxheap_register(sm_mctx_P _sm_mctx, void *, size_t, char *, int, int); void sm_ctxheap_checkptr_tagged(sm_mctx_P _sm_mctx, void *, char *, int); void sm_ctxheap_report(sm_mctx_P _sm_mctx, sm_file_T *, int); #define sm_heap_report(file, verbosity) sm_ctxheap_report(NULL, file, verbosity) #else /* SM_HEAP_CHECK */ #define sm_malloc(size) sm_ctxalloc(NULL, 0, size) #define sm_zalloc(size) sm_ctxalloc(NULL, SM_FL_ZALLOC, size) #define sm_free(ptr) sm_ctxfree(ptr) # define sm_ctxmalloc_tagged(ctx, size, file, line, grp) \ sm_ctxalloc(ctx, 0, size) # define sm_ctxzalloc_tagged(ctx, size, file, line, grp) \ sm_ctxalloc(ctx, SM_FL_ZALLOC, size) # define sm_ctxrealloc_tagged(ctx, ptr, size, file, line, grp) \ sm_ctxrealloc(ctx, ptr, size) # define sm_ctxfree_tagged(ctx, ptr, file, line) \ sm_ctxfree(ctx, ptr) # define sm_ctxfree_size_tagged(ctx, ptr, size, file, line) \ sm_ctxfree_size(ctx, ptr, size) # define sm_ctxheap_register(ctx, ptr, size, file, line, grp) (true) # define sm_ctxheap_checkptr_tagged(ctx, ptr, tag, num) SM_NOOP # define sm_ctxheap_report(ctx, file, verbose) SM_NOOP # define sm_ctxmalloc(ctx, size) sm_ctxalloc((ctx), 0, (size)) # define sm_ctxzalloc(ctx, size) sm_ctxalloc((ctx), SM_FL_ZALLOC, (size)) void *sm_ctxalloc(sm_mctx_P _sm_mctx, uint _flags, size_t _size); void sm_ctxfree(sm_mctx_P _sm_mctx, void *); void sm_ctxfree_size(sm_mctx_P _sm_mctx, void *, size_t); #endif /* SM_HEAP_CHECK */ void *sm_ctxrealloc(sm_mctx_P _sm_mctx, void *, size_t); void *sm_ctxreallocsize(sm_mctx_P _sm_mctx, void *_ptr, size_t _oldsize, size_t _newsize); #define sm_realloc(ptr, size) sm_ctxrealloc(NULL, ptr, size) #define sm_ctxheap_checkptr(ptr) sm_ctxheap_checkptr_tagged(NULL, ptr, __FILE__, __LINE__) #if 0 /* ** sm_f[mc]alloc are plug in replacements for malloc and calloc ** which can be used in a context requiring a function pointer, ** and which are compatible with sm_free. Warning: sm_heap_report ** cannot report where storage leaked by sm_f[mc]alloc was allocated. */ /* XXX unused right now */ void *sm_fmalloc(size_t); void *sm_fcalloc(size_t, size_t); #endif /* 0 */ /* ** Allocate 'permanent' storage that can be freed but may still be ** allocated when the process exits. sm_heap_report will not complain ** about a storage leak originating from a call to sm_pmalloc. */ #define sm_pmalloc(size) sm_malloc_tagged(size, __FILE__, __LINE__, 0) #define sm_heap_group() SmHeapGroup #define sm_heap_setgroup(g) (SmHeapGroup = (g)) #define sm_heap_newgroup() (SmHeapGroup = ++SmHeapMaxGroup) #if SM_HEAP_CHECK extern int SmHeapGroup; extern int SmHeapMaxGroup; extern SM_DEBUG_T SmHeapTrace; extern SM_DEBUG_T SmHeapCheck; #endif /* SM_HEAP_CHECK */ __BEGIN_DECLS void *sm_memdup(const void *_ptr, size_t _size); sm_ret_T sm_mctx_new(size_t _limit, sm_mctx_oom_F _mctx_oom, void *_cbctx, sm_mctx_P *_psm_mctx); sm_ret_T sm_mctx_destroy(sm_mctx_P _sm_mctx); sm_ret_T sm_mctx_flags(sm_mctx_P _sm_mctx, uint _flags); __END_DECLS #define SM_FREE(ptr) do \ { \ if ((ptr) != NULL) \ { \ sm_free(ptr); \ (ptr) = NULL; \ } \ } while (0) #define SM_FREE_SIZE(ptr, size) do \ { \ if ((ptr) != NULL) \ { \ sm_free_size((ptr), (size)); \ (ptr) = NULL; \ } \ } while (0) #define SM_CTXFREE(mctx, ptr) do \ { \ if ((ptr) != NULL) \ { \ sm_ctxfree((mctx), (ptr)); \ (ptr) = NULL; \ } \ } while (0) #define SM_CTXFREE_SIZE(mctx, ptr, size) do \ { \ if ((ptr) != NULL) \ { \ sm_free_size((mctx), (ptr), (size)); \ (ptr) = NULL; \ } \ } while (0) #if DMALLOC # include "dmalloc.h" #endif #define SM_IS_MCTX(sm_mctx) SM_REQUIRE_ISA(sm_mctx, SM_MCTX_MAGIC) #endif /* ! SM_HEAP_H */