1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
/*
* Copyright (c) 2000-2001, 2003 Proofpoint, 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: rpool.h,v 1.17 2013-11-22 20:51:31 ca Exp $
*/
/*
** libsm resource pools
** See libsm/rpool.html for documentation.
*/
#ifndef SM_RPOOL_H
# define SM_RPOOL_H 1
# include <sm/gen.h>
# include <sm/heap.h>
# include <sm/string.h>
/*
** Each memory pool object consists of an SM_POOLLINK_T,
** followed by a platform specific amount of padding,
** followed by 'poolsize' bytes of pool data,
** where 'poolsize' is the value of rpool->sm_poolsize at the time
** the pool is allocated.
*/
typedef struct sm_poollink SM_POOLLINK_T;
struct sm_poollink
{
SM_POOLLINK_T *sm_pnext;
};
typedef void (*SM_RPOOL_RFREE_T) __P((void *_rcontext));
typedef SM_RPOOL_RFREE_T *SM_RPOOL_ATTACH_T;
typedef struct sm_resource SM_RESOURCE_T;
struct sm_resource
{
/*
** Function for freeing this resource. It may be NULL,
** meaning that this resource has already been freed.
*/
SM_RPOOL_RFREE_T sm_rfree;
void *sm_rcontext; /* resource data */
};
# define SM_RLIST_MAX 511
typedef struct sm_rlist SM_RLIST_T;
struct sm_rlist
{
SM_RESOURCE_T sm_rvec[SM_RLIST_MAX];
SM_RLIST_T *sm_rnext;
};
typedef struct
{
/* Points to SmRpoolMagic, or is NULL if rpool is freed. */
const char *sm_magic;
/*
** If this rpool object has no parent, then sm_parentlink
** is NULL. Otherwise, we set *sm_parentlink = NULL
** when this rpool is freed, so that it isn't freed a
** second time when the parent is freed.
*/
SM_RPOOL_RFREE_T *sm_parentlink;
/*
** Memory pools
*/
/* Size of the next pool to be allocated, not including the header. */
size_t sm_poolsize;
/*
** If an sm_rpool_malloc_x request is too big to fit
** in the current pool, and the request size > bigobjectsize,
** then the object will be given its own malloc'ed block.
** sm_bigobjectsize <= sm_poolsize. The maximum wasted space
** at the end of a pool is maxpooledobjectsize - 1.
*/
size_t sm_bigobjectsize;
/* Points to next free byte in the current pool. */
char *sm_poolptr;
/*
** Number of bytes available in the current pool.
** Initially 0. Set to 0 by sm_rpool_free.
*/
size_t sm_poolavail;
/* Linked list of memory pools. Initially NULL. */
SM_POOLLINK_T *sm_pools;
/*
** Resource lists
*/
SM_RESOURCE_T *sm_rptr; /* Points to next free resource slot. */
/*
** Number of available resource slots in current list.
** Initially 0. Set to 0 by sm_rpool_free.
*/
size_t sm_ravail;
/* Linked list of resource lists. Initially NULL. */
SM_RLIST_T *sm_rlists;
#if _FFR_PERF_RPOOL
int sm_nbigblocks;
int sm_npools;
#endif
} SM_RPOOL_T;
extern SM_RPOOL_T *
sm_rpool_new_x __P((
SM_RPOOL_T *_parent));
extern void
sm_rpool_free __P((
SM_RPOOL_T *_rpool));
# if SM_HEAP_CHECK
extern void *
sm_rpool_malloc_tagged_x __P((
SM_RPOOL_T *_rpool,
size_t _size,
char *_file,
int _line,
int _group));
# define sm_rpool_malloc_x(rpool, size) \
sm_rpool_malloc_tagged_x(rpool, size, __FILE__, __LINE__, SmHeapGroup)
extern void *
sm_rpool_malloc_tagged __P((
SM_RPOOL_T *_rpool,
size_t _size,
char *_file,
int _line,
int _group));
# define sm_rpool_malloc(rpool, size) \
sm_rpool_malloc_tagged(rpool, size, __FILE__, __LINE__, SmHeapGroup)
# else /* SM_HEAP_CHECK */
extern void *
sm_rpool_malloc_x __P((
SM_RPOOL_T *_rpool,
size_t _size));
extern void *
sm_rpool_malloc __P((
SM_RPOOL_T *_rpool,
size_t _size));
# define sm_rpool_malloc_tagged(rpool, size, file, line, group) sm_rpool_malloc(rpool, size)
# define sm_rpool_malloc_tagged_x(rpool, size, file, line, group) sm_rpool_malloc_x(rpool, size)
# endif /* SM_HEAP_CHECK */
#if DO_NOT_USE_STRCPY
# if SM_HEAP_CHECK > 2
extern char *sm_rpool_strdup_tagged_x __P((SM_RPOOL_T *rpool, const char *s, char *, int, int));
# define sm_rpool_strdup_x(rpool, str) sm_rpool_strdup_tagged_x(rpool, str, "sm_rpool_strdup_x:" __FILE__, __LINE__, SmHeapGroup)
# else
extern char *sm_rpool_strdup_x __P((SM_RPOOL_T *rpool, const char *s));
# define sm_rpool_strdup_tagged_x(rpool, str, tag, line, group) sm_rpool_strdup_x(rpool, str)
# endif
#else
# define sm_rpool_strdup_x(rpool, str) \
strcpy(sm_rpool_malloc_x(rpool, strlen(str) + 1), str)
#endif
extern SM_RPOOL_ATTACH_T
sm_rpool_attach_x __P((
SM_RPOOL_T *_rpool,
SM_RPOOL_RFREE_T _rfree,
void *_rcontext));
# define sm_rpool_detach(a) ((void)(*(a) = NULL))
extern void
sm_rpool_setsizes __P((
SM_RPOOL_T *_rpool,
size_t _poolsize,
size_t _bigobjectsize));
#endif /* ! SM_RPOOL_H */
|