xref: /illumos-gate/usr/src/lib/libmalloc/common/mallint.h (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #ifndef _MALLINT_H
31 #define	_MALLINT_H
32 
33 #pragma ident	"%Z%%M%	%I%	%E% SMI"
34 
35 /*	From:	SVr4.0	libmalloc:mallint.h	1.3		*/
36 
37 /*
38  * number of bytes to align to  (must be at least 4, because lower 2 bits
39  * are used for flags
40  *
41  * header and code assume ALIGNSZ is exact multiple of sizeof (struct header *)
42  * several places assume sizeof (long) == sizeof (struct holdblk *)
43  */
44 
45 #include <sys/types.h>
46 
47 #ifdef	__cplusplus
48 extern "C" {
49 #endif
50 
51 #ifdef _LP64
52 #define	ALIGNSZ	16
53 #else
54 #define	ALIGNSZ	8
55 #endif
56 
57 /*
58  *	template for the header
59  */
60 
61 struct header {
62 	struct header *nextblk;
63 	struct header *nextfree;
64 	struct header *prevfree;
65 	struct header *__Pad;	/* pad to a multiple of ALIGNSZ */
66 };
67 
68 /*
69  *	template for a small block
70  */
71 
72 struct lblk  {
73 	union {
74 		/*
75 		 * the next free little block in this holding block.
76 		 * This field is used when the block is free
77 		 */
78 		struct lblk *nextfree;
79 		/*
80 		 * the holding block containing this little block.
81 		 * This field is used when the block is allocated
82 		 */
83 		struct holdblk *holder;
84 		/*
85 		 * Insure over head is multiple of ALIGNSZ
86 		 * assumes  ALIGNSZ >= sizeof pointer
87 		 */
88 		char __Overhead[ALIGNSZ];
89 	}  header;
90 	/* There is no telling how big this field really is.  */
91 	/* This must be on a ALIGNSZ  boundary */
92 	char byte;
93 };
94 
95 /*
96  *	template for holding block
97  */
98 struct holdblk {
99 	struct holdblk *nexthblk;   /* next holding block */
100 	struct holdblk *prevhblk;   /* previous holding block */
101 	struct lblk *lfreeq;	/* head of free queue within block */
102 	struct lblk *unused;	/* pointer to 1st little block never used */
103 	long blksz;		/* size of little blocks contained */
104 	struct lblk *__Pad;	/* pad to a multiple of ALIGNSZ */
105 	char space[1];		/* start of space to allocate. */
106 				/* This must be on a ALIGNSZ boundary */
107 };
108 
109 /*
110  *	 The following manipulate the free queue
111  *
112  *		DELFREEQ will remove x from the free queue
113  *		ADDFREEQ will add an element to the head
114  *			 of the free queue.
115  *		MOVEHEAD will move the free pointers so that
116  *			 x is at the front of the queue
117  */
118 #define	ADDFREEQ(x)	(x)->prevfree = &(freeptr[0]);\
119 				(x)->nextfree = freeptr[0].nextfree;\
120 				freeptr[0].nextfree->prevfree = (x);\
121 				freeptr[0].nextfree = (x);\
122 				assert((x)->nextfree != (x));\
123 				assert((x)->prevfree != (x));
124 #define	DELFREEQ(x)	(x)->prevfree->nextfree = (x)->nextfree;\
125 				(x)->nextfree->prevfree = (x)->prevfree;\
126 				assert((x)->nextfree != (x));\
127 				assert((x)->prevfree != (x));
128 #define	MOVEHEAD(x)	freeptr[1].prevfree->nextfree = freeptr[0].nextfree;\
129 				freeptr[0].nextfree->prevfree = \
130 				    freeptr[1].prevfree;\
131 				(x)->prevfree->nextfree = &(freeptr[1]);\
132 				freeptr[1].prevfree = (x)->prevfree;\
133 				(x)->prevfree = &(freeptr[0]);\
134 				freeptr[0].nextfree = (x);\
135 				assert((x)->nextfree != (x));\
136 				assert((x)->prevfree != (x));
137 /*
138  *	The following manipulate the busy flag
139  */
140 #define	BUSY	1L
141 #define	SETBUSY(x)	((struct header *)((long)(x) | BUSY))
142 #define	CLRBUSY(x)	((struct header *)((long)(x) & ~BUSY))
143 #define	TESTBUSY(x)	((long)(x) & BUSY)
144 /*
145  *	The following manipulate the small block flag
146  */
147 #define	SMAL	2L
148 #define	SETSMAL(x)	((struct lblk *)((long)(x) | SMAL))
149 #define	CLRSMAL(x)	((struct lblk *)((long)(x) & ~SMAL))
150 #define	TESTSMAL(x)	((long)(x) & SMAL)
151 /*
152  *	The following manipulate both flags.  They must be
153  *	type coerced
154  */
155 #define	SETALL(x)	((long)(x) | (SMAL | BUSY))
156 #define	CLRALL(x)	((long)(x) & ~(SMAL | BUSY))
157 /*
158  *	Other useful constants
159  */
160 #define	TRUE	1
161 #define	FALSE	0
162 #define	HEADSZ	sizeof (struct header)	/* size of unallocated block header */
163 
164 /* MINHEAD is the minimum size of an allocated block header */
165 #define	MINHEAD	ALIGNSZ
166 
167 /* min. block size must as big as HEADSZ */
168 #define	MINBLKSZ	HEADSZ
169 
170 /* memory is gotten from sbrk in multiples of BLOCKSZ */
171 #define	BLOCKSZ		2048	/* ??? Too Small, ?? pagesize? */
172 
173 #define	GROUND	(struct header *)0
174 #define	LGROUND	(struct lblk *)0
175 #define	HGROUND	(struct holdblk *)0	/* ground for the holding block queue */
176 #ifndef	NULL
177 #define	NULL	(char *)0
178 #endif
179 /*
180  *	Structures and constants describing the holding blocks
181  */
182 /* default number of small blocks per holding block */
183 #define	NUMLBLKS	100
184 
185 /* size of a holding block with small blocks of size blksz */
186 #define	HOLDSZ(blksz)	\
187 	    (sizeof (struct holdblk) - sizeof (struct lblk *) + blksz*numlblks)
188 #define	FASTCT	6	/* number of blocks that can be allocated quickly */
189 
190 /* default maximum size block for fast allocation */
191 /* assumes initial value of grain == ALIGNSZ */
192 #define	MAXFAST	ALIGNSZ*FASTCT
193 
194 #ifdef	debug
195 #define	CHECKQ	checkq();
196 #else
197 #define	CHECKQ
198 #endif
199 
200 #ifdef	__cplusplus
201 }
202 #endif
203 
204 #endif	/* _MALLINT_H */
205