190792Sgshapiro/*
2261194Sgshapiro * Copyright (c) 2000-2001, 2003 Proofpoint, Inc. and its suppliers.
390792Sgshapiro *	All rights reserved.
490792Sgshapiro *
590792Sgshapiro * By using this file, you agree to the terms and conditions set
690792Sgshapiro * forth in the LICENSE file which can be found at the top level of
790792Sgshapiro * the sendmail distribution.
890792Sgshapiro *
9266527Sgshapiro *	$Id: rpool.h,v 1.17 2013-11-22 20:51:31 ca Exp $
1090792Sgshapiro */
1190792Sgshapiro
1290792Sgshapiro/*
1390792Sgshapiro**  libsm resource pools
1490792Sgshapiro**  See libsm/rpool.html for documentation.
1590792Sgshapiro*/
1690792Sgshapiro
1790792Sgshapiro#ifndef SM_RPOOL_H
1890792Sgshapiro# define SM_RPOOL_H
1990792Sgshapiro
2090792Sgshapiro# include <sm/gen.h>
2190792Sgshapiro# include <sm/heap.h>
2290792Sgshapiro# include <sm/string.h>
2390792Sgshapiro
2490792Sgshapiro/*
2590792Sgshapiro**  Each memory pool object consists of an SM_POOLLINK_T,
2690792Sgshapiro**  followed by a platform specific amount of padding,
2790792Sgshapiro**  followed by 'poolsize' bytes of pool data,
2890792Sgshapiro**  where 'poolsize' is the value of rpool->sm_poolsize at the time
2990792Sgshapiro**  the pool is allocated.
3090792Sgshapiro*/
3190792Sgshapiro
3290792Sgshapirotypedef struct sm_poollink SM_POOLLINK_T;
3390792Sgshapirostruct sm_poollink
3490792Sgshapiro{
3590792Sgshapiro	SM_POOLLINK_T *sm_pnext;
3690792Sgshapiro};
3790792Sgshapiro
3890792Sgshapirotypedef void (*SM_RPOOL_RFREE_T) __P((void *_rcontext));
3990792Sgshapiro
4090792Sgshapirotypedef SM_RPOOL_RFREE_T *SM_RPOOL_ATTACH_T;
4190792Sgshapiro
4290792Sgshapirotypedef struct sm_resource SM_RESOURCE_T;
4390792Sgshapirostruct sm_resource
4490792Sgshapiro{
4590792Sgshapiro	/*
4690792Sgshapiro	**  Function for freeing this resource.  It may be NULL,
4790792Sgshapiro	**  meaning that this resource has already been freed.
4890792Sgshapiro	*/
4990792Sgshapiro
5090792Sgshapiro	SM_RPOOL_RFREE_T sm_rfree;
5190792Sgshapiro	void *sm_rcontext;	/* resource data */
5290792Sgshapiro};
5390792Sgshapiro
5490792Sgshapiro# define SM_RLIST_MAX 511
5590792Sgshapiro
5690792Sgshapirotypedef struct sm_rlist SM_RLIST_T;
5790792Sgshapirostruct sm_rlist
5890792Sgshapiro{
5990792Sgshapiro	SM_RESOURCE_T sm_rvec[SM_RLIST_MAX];
6090792Sgshapiro	SM_RLIST_T *sm_rnext;
6190792Sgshapiro};
6290792Sgshapiro
6390792Sgshapirotypedef struct
6490792Sgshapiro{
6590792Sgshapiro	/* Points to SmRpoolMagic, or is NULL if rpool is freed. */
6690792Sgshapiro	const char *sm_magic;
6790792Sgshapiro
6890792Sgshapiro	/*
6990792Sgshapiro	**  If this rpool object has no parent, then sm_parentlink
7090792Sgshapiro	**  is NULL.  Otherwise, we set *sm_parentlink = NULL
7190792Sgshapiro	**  when this rpool is freed, so that it isn't freed a
7290792Sgshapiro	**  second time when the parent is freed.
7390792Sgshapiro	*/
7490792Sgshapiro
7590792Sgshapiro	SM_RPOOL_RFREE_T *sm_parentlink;
7690792Sgshapiro
7790792Sgshapiro	/*
7890792Sgshapiro	**  Memory pools
7990792Sgshapiro	*/
8090792Sgshapiro
8190792Sgshapiro	/* Size of the next pool to be allocated, not including the header. */
8290792Sgshapiro	size_t sm_poolsize;
8390792Sgshapiro
8490792Sgshapiro	/*
8590792Sgshapiro	**  If an sm_rpool_malloc_x request is too big to fit
8690792Sgshapiro	**  in the current pool, and the request size > bigobjectsize,
8790792Sgshapiro	**  then the object will be given its own malloc'ed block.
8890792Sgshapiro	**  sm_bigobjectsize <= sm_poolsize.  The maximum wasted space
8990792Sgshapiro	**  at the end of a pool is maxpooledobjectsize - 1.
9090792Sgshapiro	*/
9190792Sgshapiro
9290792Sgshapiro	size_t sm_bigobjectsize;
9390792Sgshapiro
9490792Sgshapiro	/* Points to next free byte in the current pool. */
9590792Sgshapiro	char *sm_poolptr;
9690792Sgshapiro
9790792Sgshapiro	/*
9890792Sgshapiro	**  Number of bytes available in the current pool.
9990792Sgshapiro	**	Initially 0. Set to 0 by sm_rpool_free.
10090792Sgshapiro	*/
10190792Sgshapiro
10290792Sgshapiro	size_t sm_poolavail;
10390792Sgshapiro
10490792Sgshapiro	/* Linked list of memory pools.  Initially NULL. */
10590792Sgshapiro	SM_POOLLINK_T *sm_pools;
10690792Sgshapiro
10790792Sgshapiro	/*
10890792Sgshapiro	** Resource lists
10990792Sgshapiro	*/
11090792Sgshapiro
11190792Sgshapiro	SM_RESOURCE_T *sm_rptr; /* Points to next free resource slot. */
11290792Sgshapiro
11390792Sgshapiro	/*
11490792Sgshapiro	**  Number of available resource slots in current list.
11590792Sgshapiro	**	Initially 0. Set to 0 by sm_rpool_free.
11690792Sgshapiro	*/
11790792Sgshapiro
11890792Sgshapiro	size_t sm_ravail;
11990792Sgshapiro
12090792Sgshapiro	/* Linked list of resource lists. Initially NULL. */
12190792Sgshapiro	SM_RLIST_T *sm_rlists;
12290792Sgshapiro
12390792Sgshapiro#if _FFR_PERF_RPOOL
12490792Sgshapiro	int	sm_nbigblocks;
12590792Sgshapiro	int	sm_npools;
12690792Sgshapiro#endif /* _FFR_PERF_RPOOL */
12790792Sgshapiro
12890792Sgshapiro} SM_RPOOL_T;
12990792Sgshapiro
13090792Sgshapiroextern SM_RPOOL_T *
13190792Sgshapirosm_rpool_new_x __P((
13290792Sgshapiro	SM_RPOOL_T *_parent));
13390792Sgshapiro
13490792Sgshapiroextern void
13590792Sgshapirosm_rpool_free __P((
13690792Sgshapiro	SM_RPOOL_T *_rpool));
13790792Sgshapiro
13890792Sgshapiro# if SM_HEAP_CHECK
13990792Sgshapiroextern void *
14090792Sgshapirosm_rpool_malloc_tagged_x __P((
14190792Sgshapiro	SM_RPOOL_T *_rpool,
14290792Sgshapiro	size_t _size,
14390792Sgshapiro	char *_file,
14490792Sgshapiro	int _line,
14590792Sgshapiro	int _group));
14690792Sgshapiro#  define sm_rpool_malloc_x(rpool, size) \
14790792Sgshapiro	sm_rpool_malloc_tagged_x(rpool, size, __FILE__, __LINE__, SmHeapGroup)
14890792Sgshapiroextern void *
14990792Sgshapirosm_rpool_malloc_tagged __P((
15090792Sgshapiro	SM_RPOOL_T *_rpool,
15190792Sgshapiro	size_t _size,
15290792Sgshapiro	char *_file,
15390792Sgshapiro	int _line,
15490792Sgshapiro	int _group));
15590792Sgshapiro#  define sm_rpool_malloc(rpool, size) \
15690792Sgshapiro	sm_rpool_malloc_tagged(rpool, size, __FILE__, __LINE__, SmHeapGroup)
15790792Sgshapiro# else /* SM_HEAP_CHECK */
15890792Sgshapiroextern void *
15990792Sgshapirosm_rpool_malloc_x __P((
16090792Sgshapiro	SM_RPOOL_T *_rpool,
16190792Sgshapiro	size_t _size));
16290792Sgshapiroextern void *
16390792Sgshapirosm_rpool_malloc __P((
16490792Sgshapiro	SM_RPOOL_T *_rpool,
16590792Sgshapiro	size_t _size));
16690792Sgshapiro# endif /* SM_HEAP_CHECK */
16790792Sgshapiro
168132943Sgshapiro#if DO_NOT_USE_STRCPY
169132943Sgshapiroextern char *sm_rpool_strdup_x __P((SM_RPOOL_T *rpool, const char *s));
170132943Sgshapiro#else /* DO_NOT_USE_STRCPY */
17190792Sgshapiro# define sm_rpool_strdup_x(rpool, str) \
17290792Sgshapiro	strcpy(sm_rpool_malloc_x(rpool, strlen(str) + 1), str)
173132943Sgshapiro#endif /* DO_NOT_USE_STRCPY */
17490792Sgshapiro
17590792Sgshapiroextern SM_RPOOL_ATTACH_T
17690792Sgshapirosm_rpool_attach_x __P((
17790792Sgshapiro	SM_RPOOL_T *_rpool,
17890792Sgshapiro	SM_RPOOL_RFREE_T _rfree,
17990792Sgshapiro	void *_rcontext));
18090792Sgshapiro
18190792Sgshapiro# define sm_rpool_detach(a) ((void)(*(a) = NULL))
18290792Sgshapiro
18390792Sgshapiroextern void
18490792Sgshapirosm_rpool_setsizes __P((
18590792Sgshapiro	SM_RPOOL_T *_rpool,
18690792Sgshapiro	size_t _poolsize,
18790792Sgshapiro	size_t _bigobjectsize));
18890792Sgshapiro
18990792Sgshapiro#endif /* ! SM_RPOOL_H */
190