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