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