diff options
Diffstat (limited to 'contrib/sendmail/libsm/rpool.c')
-rw-r--r-- | contrib/sendmail/libsm/rpool.c | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/contrib/sendmail/libsm/rpool.c b/contrib/sendmail/libsm/rpool.c deleted file mode 100644 index 39344c268fc4..000000000000 --- a/contrib/sendmail/libsm/rpool.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (c) 2000-2004 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. - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: rpool.c,v 1.28 2004/08/03 20:44:04 ca Exp $") - -/* -** resource pools -** For documentation, see rpool.html -*/ - -#include <sm/exc.h> -#include <sm/heap.h> -#include <sm/rpool.h> -#include <sm/varargs.h> -#include <sm/conf.h> -#if _FFR_PERF_RPOOL -# include <syslog.h> -#endif /* _FFR_PERF_RPOOL */ - -const char SmRpoolMagic[] = "sm_rpool"; - -typedef union -{ - SM_POOLLINK_T link; - char align[SM_ALIGN_SIZE]; -} SM_POOLHDR_T; - -static char *sm_rpool_allocblock_x __P((SM_RPOOL_T *, size_t)); -static char *sm_rpool_allocblock __P((SM_RPOOL_T *, size_t)); - -/* -** Tune this later -*/ - -#define POOLSIZE 4096 -#define BIG_OBJECT_RATIO 10 - -/* -** SM_RPOOL_ALLOCBLOCK_X -- allocate a new block for an rpool. -** -** Parameters: -** rpool -- rpool to which the block should be added. -** size -- size of block. -** -** Returns: -** Pointer to block. -** -** Exceptions: -** F:sm_heap -- out of memory -*/ - -static char * -sm_rpool_allocblock_x(rpool, size) - SM_RPOOL_T *rpool; - size_t size; -{ - SM_POOLLINK_T *p; - - p = sm_malloc_x(sizeof(SM_POOLHDR_T) + size); - p->sm_pnext = rpool->sm_pools; - rpool->sm_pools = p; - return (char*) p + sizeof(SM_POOLHDR_T); -} - -/* -** SM_RPOOL_ALLOCBLOCK -- allocate a new block for an rpool. -** -** Parameters: -** rpool -- rpool to which the block should be added. -** size -- size of block. -** -** Returns: -** Pointer to block, NULL on failure. -*/ - -static char * -sm_rpool_allocblock(rpool, size) - SM_RPOOL_T *rpool; - size_t size; -{ - SM_POOLLINK_T *p; - - p = sm_malloc(sizeof(SM_POOLHDR_T) + size); - if (p == NULL) - return NULL; - p->sm_pnext = rpool->sm_pools; - rpool->sm_pools = p; - return (char*) p + sizeof(SM_POOLHDR_T); -} - -/* -** SM_RPOOL_MALLOC_TAGGED_X -- allocate memory from rpool -** -** Parameters: -** rpool -- rpool from which memory should be allocated; -** can be NULL, use sm_malloc() then. -** size -- size of block. -** file -- filename. -** line -- line number in file. -** group -- heap group for debugging. -** -** Returns: -** Pointer to block. -** -** Exceptions: -** F:sm_heap -- out of memory -** -** Notice: XXX -** if size == 0 and the rpool is new (no memory -** allocated yet) NULL is returned! -** We could solve this by -** - wasting 1 byte (size < avail) -** - checking for rpool->sm_poolptr != NULL -** - not asking for 0 sized buffer -*/ - -void * -#if SM_HEAP_CHECK -sm_rpool_malloc_tagged_x(rpool, size, file, line, group) - SM_RPOOL_T *rpool; - size_t size; - char *file; - int line; - int group; -#else /* SM_HEAP_CHECK */ -sm_rpool_malloc_x(rpool, size) - SM_RPOOL_T *rpool; - size_t size; -#endif /* SM_HEAP_CHECK */ -{ - char *ptr; - - if (rpool == NULL) - return sm_malloc_tagged_x(size, file, line, group); - - /* Ensure that size is properly aligned. */ - if (size & SM_ALIGN_BITS) - size = (size & ~SM_ALIGN_BITS) + SM_ALIGN_SIZE; - - /* The common case. This is optimized for speed. */ - if (size <= rpool->sm_poolavail) - { - ptr = rpool->sm_poolptr; - rpool->sm_poolptr += size; - rpool->sm_poolavail -= size; - return ptr; - } - - /* - ** The slow case: we need to call malloc. - ** The SM_REQUIRE assertion is deferred until now, for speed. - ** That's okay: we set rpool->sm_poolavail to 0 when we free an rpool, - ** so the common case code won't be triggered on a dangling pointer. - */ - - SM_REQUIRE(rpool->sm_magic == SmRpoolMagic); - - /* - ** If size > sm_poolsize, then malloc a new block especially for - ** this request. Future requests will be allocated from the - ** current pool. - ** - ** What if the current pool is mostly unallocated, and the current - ** request is larger than the available space, but < sm_poolsize? - ** If we discard the current pool, and start allocating from a new - ** pool, then we will be wasting a lot of space. For this reason, - ** we malloc a block just for the current request if size > - ** sm_bigobjectsize, where sm_bigobjectsize <= sm_poolsize. - ** Thus, the most space that we will waste at the end of a pool - ** is sm_bigobjectsize - 1. - */ - - if (size > rpool->sm_bigobjectsize) - { -#if _FFR_PERF_RPOOL - ++rpool->sm_nbigblocks; -#endif /* _FFR_PERF_RPOOL */ - return sm_rpool_allocblock_x(rpool, size); - } - SM_ASSERT(rpool->sm_bigobjectsize <= rpool->sm_poolsize); - ptr = sm_rpool_allocblock_x(rpool, rpool->sm_poolsize); - rpool->sm_poolptr = ptr + size; - rpool->sm_poolavail = rpool->sm_poolsize - size; -#if _FFR_PERF_RPOOL - ++rpool->sm_npools; -#endif /* _FFR_PERF_RPOOL */ - return ptr; -} - -/* -** SM_RPOOL_MALLOC_TAGGED -- allocate memory from rpool -** -** Parameters: -** rpool -- rpool from which memory should be allocated; -** can be NULL, use sm_malloc() then. -** size -- size of block. -** file -- filename. -** line -- line number in file. -** group -- heap group for debugging. -** -** Returns: -** Pointer to block, NULL on failure. -** -** Notice: XXX -** if size == 0 and the rpool is new (no memory -** allocated yet) NULL is returned! -** We could solve this by -** - wasting 1 byte (size < avail) -** - checking for rpool->sm_poolptr != NULL -** - not asking for 0 sized buffer -*/ - -void * -#if SM_HEAP_CHECK -sm_rpool_malloc_tagged(rpool, size, file, line, group) - SM_RPOOL_T *rpool; - size_t size; - char *file; - int line; - int group; -#else /* SM_HEAP_CHECK */ -sm_rpool_malloc(rpool, size) - SM_RPOOL_T *rpool; - size_t size; -#endif /* SM_HEAP_CHECK */ -{ - char *ptr; - - if (rpool == NULL) - return sm_malloc_tagged(size, file, line, group); - - /* Ensure that size is properly aligned. */ - if (size & SM_ALIGN_BITS) - size = (size & ~SM_ALIGN_BITS) + SM_ALIGN_SIZE; - - /* The common case. This is optimized for speed. */ - if (size <= rpool->sm_poolavail) - { - ptr = rpool->sm_poolptr; - rpool->sm_poolptr += size; - rpool->sm_poolavail -= size; - return ptr; - } - - /* - ** The slow case: we need to call malloc. - ** The SM_REQUIRE assertion is deferred until now, for speed. - ** That's okay: we set rpool->sm_poolavail to 0 when we free an rpool, - ** so the common case code won't be triggered on a dangling pointer. - */ - - SM_REQUIRE(rpool->sm_magic == SmRpoolMagic); - - /* - ** If size > sm_poolsize, then malloc a new block especially for - ** this request. Future requests will be allocated from the - ** current pool. - ** - ** What if the current pool is mostly unallocated, and the current - ** request is larger than the available space, but < sm_poolsize? - ** If we discard the current pool, and start allocating from a new - ** pool, then we will be wasting a lot of space. For this reason, - ** we malloc a block just for the current request if size > - ** sm_bigobjectsize, where sm_bigobjectsize <= sm_poolsize. - ** Thus, the most space that we will waste at the end of a pool - ** is sm_bigobjectsize - 1. - */ - - if (size > rpool->sm_bigobjectsize) - { -#if _FFR_PERF_RPOOL - ++rpool->sm_nbigblocks; -#endif /* _FFR_PERF_RPOOL */ - return sm_rpool_allocblock(rpool, size); - } - SM_ASSERT(rpool->sm_bigobjectsize <= rpool->sm_poolsize); - ptr = sm_rpool_allocblock(rpool, rpool->sm_poolsize); - if (ptr == NULL) - return NULL; - rpool->sm_poolptr = ptr + size; - rpool->sm_poolavail = rpool->sm_poolsize - size; -#if _FFR_PERF_RPOOL - ++rpool->sm_npools; -#endif /* _FFR_PERF_RPOOL */ - return ptr; -} - -/* -** SM_RPOOL_NEW_X -- create a new rpool. -** -** Parameters: -** parent -- pointer to parent rpool, can be NULL. -** -** Returns: -** Pointer to new rpool. -*/ - -SM_RPOOL_T * -sm_rpool_new_x(parent) - SM_RPOOL_T *parent; -{ - SM_RPOOL_T *rpool; - - rpool = sm_malloc_x(sizeof(SM_RPOOL_T)); - if (parent == NULL) - rpool->sm_parentlink = NULL; - else - { - SM_TRY - rpool->sm_parentlink = sm_rpool_attach_x(parent, - (SM_RPOOL_RFREE_T) sm_rpool_free, - (void *) rpool); - SM_EXCEPT(exc, "*") - sm_free(rpool); - sm_exc_raise_x(exc); - SM_END_TRY - } - rpool->sm_magic = SmRpoolMagic; - - rpool->sm_poolsize = POOLSIZE - sizeof(SM_POOLHDR_T); - rpool->sm_bigobjectsize = rpool->sm_poolsize / BIG_OBJECT_RATIO; - rpool->sm_poolptr = NULL; - rpool->sm_poolavail = 0; - rpool->sm_pools = NULL; - - rpool->sm_rptr = NULL; - rpool->sm_ravail = 0; - rpool->sm_rlists = NULL; -#if _FFR_PERF_RPOOL - rpool->sm_nbigblocks = 0; - rpool->sm_npools = 0; -#endif /* _FFR_PERF_RPOOL */ - - return rpool; -} - -/* -** SM_RPOOL_SETSIZES -- set sizes for rpool. -** -** Parameters: -** poolsize -- size of a single rpool block. -** bigobjectsize -- if this size is exceeded, an individual -** block is allocated (must be less or equal poolsize). -** -** Returns: -** none. -*/ - -void -sm_rpool_setsizes(rpool, poolsize, bigobjectsize) - SM_RPOOL_T *rpool; - size_t poolsize; - size_t bigobjectsize; -{ - SM_REQUIRE(poolsize >= bigobjectsize); - if (poolsize == 0) - poolsize = POOLSIZE - sizeof(SM_POOLHDR_T); - if (bigobjectsize == 0) - bigobjectsize = poolsize / BIG_OBJECT_RATIO; - rpool->sm_poolsize = poolsize; - rpool->sm_bigobjectsize = bigobjectsize; -} - -/* -** SM_RPOOL_FREE -- free an rpool and release all of its resources. -** -** Parameters: -** rpool -- rpool to free. -** -** Returns: -** none. -*/ - -void -sm_rpool_free(rpool) - SM_RPOOL_T *rpool; -{ - SM_RLIST_T *rl, *rnext; - SM_RESOURCE_T *r, *rmax; - SM_POOLLINK_T *pp, *pnext; - - if (rpool == NULL) - return; - - /* - ** It's important to free the resources before the memory pools, - ** because the resource free functions might modify the contents - ** of the memory pools. - */ - - rl = rpool->sm_rlists; - if (rl != NULL) - { - rmax = rpool->sm_rptr; - for (;;) - { - for (r = rl->sm_rvec; r < rmax; ++r) - { - if (r->sm_rfree != NULL) - r->sm_rfree(r->sm_rcontext); - } - rnext = rl->sm_rnext; - sm_free(rl); - if (rnext == NULL) - break; - rl = rnext; - rmax = &rl->sm_rvec[SM_RLIST_MAX]; - } - } - - /* - ** Now free the memory pools. - */ - - for (pp = rpool->sm_pools; pp != NULL; pp = pnext) - { - pnext = pp->sm_pnext; - sm_free(pp); - } - - /* - ** Disconnect rpool from its parent. - */ - - if (rpool->sm_parentlink != NULL) - *rpool->sm_parentlink = NULL; - - /* - ** Setting these fields to zero means that any future to attempt - ** to use the rpool after it is freed will cause an assertion failure. - */ - - rpool->sm_magic = NULL; - rpool->sm_poolavail = 0; - rpool->sm_ravail = 0; - -#if _FFR_PERF_RPOOL - if (rpool->sm_nbigblocks > 0 || rpool->sm_npools > 1) - syslog(LOG_NOTICE, - "perf: rpool=%lx, sm_nbigblocks=%d, sm_npools=%d", - (long) rpool, rpool->sm_nbigblocks, rpool->sm_npools); - rpool->sm_nbigblocks = 0; - rpool->sm_npools = 0; -#endif /* _FFR_PERF_RPOOL */ - sm_free(rpool); -} - -/* -** SM_RPOOL_ATTACH_X -- attach a resource to an rpool. -** -** Parameters: -** rpool -- rpool to which resource should be attached. -** rfree -- function to call when rpool is freed. -** rcontext -- argument for function to call when rpool is freed. -** -** Returns: -** Pointer to allocated function. -** -** Exceptions: -** F:sm_heap -- out of memory -*/ - -SM_RPOOL_ATTACH_T -sm_rpool_attach_x(rpool, rfree, rcontext) - SM_RPOOL_T *rpool; - SM_RPOOL_RFREE_T rfree; - void *rcontext; -{ - SM_RLIST_T *rl; - SM_RPOOL_ATTACH_T a; - - SM_REQUIRE_ISA(rpool, SmRpoolMagic); - - if (rpool->sm_ravail == 0) - { - rl = sm_malloc_x(sizeof(SM_RLIST_T)); - rl->sm_rnext = rpool->sm_rlists; - rpool->sm_rlists = rl; - rpool->sm_rptr = rl->sm_rvec; - rpool->sm_ravail = SM_RLIST_MAX; - } - - a = &rpool->sm_rptr->sm_rfree; - rpool->sm_rptr->sm_rfree = rfree; - rpool->sm_rptr->sm_rcontext = rcontext; - ++rpool->sm_rptr; - --rpool->sm_ravail; - return a; -} - -#if DO_NOT_USE_STRCPY -/* -** SM_RPOOL_STRDUP_X -- Create a copy of a C string -** -** Parameters: -** rpool -- rpool to use. -** s -- the string to copy. -** -** Returns: -** pointer to newly allocated string. -*/ - -char * -sm_rpool_strdup_x(rpool, s) - SM_RPOOL_T *rpool; - const char *s; -{ - size_t l; - char *n; - - l = strlen(s); - SM_ASSERT(l + 1 > l); - n = sm_rpool_malloc_x(rpool, l + 1); - sm_strlcpy(n, s, l + 1); - return n; -} -#endif /* DO_NOT_USE_STRCPY */ |