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