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