17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1d530678Sraf  * Common Development and Distribution License (the "License").
6*1d530678Sraf  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate 
227c478bd9Sstevel@tonic-gate /*
23*1d530678Sraf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*1d530678Sraf  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
27*1d530678Sraf /*	Copyright (c) 1988 AT&T	*/
28*1d530678Sraf /*	  All Rights Reserved  	*/
29*1d530678Sraf 
307c478bd9Sstevel@tonic-gate #ifndef _MALLINT_H
317c478bd9Sstevel@tonic-gate #define	_MALLINT_H
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /*	From:	SVr4.0	libmalloc:mallint.h	1.3		*/
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate  * number of bytes to align to  (must be at least 4, because lower 2 bits
377c478bd9Sstevel@tonic-gate  * are used for flags
387c478bd9Sstevel@tonic-gate  *
397c478bd9Sstevel@tonic-gate  * header and code assume ALIGNSZ is exact multiple of sizeof (struct header *)
407c478bd9Sstevel@tonic-gate  * several places assume sizeof (long) == sizeof (struct holdblk *)
417c478bd9Sstevel@tonic-gate  */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #include <sys/types.h>
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
467c478bd9Sstevel@tonic-gate extern "C" {
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #ifdef _LP64
507c478bd9Sstevel@tonic-gate #define	ALIGNSZ	16
517c478bd9Sstevel@tonic-gate #else
527c478bd9Sstevel@tonic-gate #define	ALIGNSZ	8
537c478bd9Sstevel@tonic-gate #endif
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate  *	template for the header
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate struct header {
607c478bd9Sstevel@tonic-gate 	struct header *nextblk;
617c478bd9Sstevel@tonic-gate 	struct header *nextfree;
627c478bd9Sstevel@tonic-gate 	struct header *prevfree;
637c478bd9Sstevel@tonic-gate 	struct header *__Pad;	/* pad to a multiple of ALIGNSZ */
647c478bd9Sstevel@tonic-gate };
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
677c478bd9Sstevel@tonic-gate  *	template for a small block
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate struct lblk  {
717c478bd9Sstevel@tonic-gate 	union {
727c478bd9Sstevel@tonic-gate 		/*
737c478bd9Sstevel@tonic-gate 		 * the next free little block in this holding block.
747c478bd9Sstevel@tonic-gate 		 * This field is used when the block is free
757c478bd9Sstevel@tonic-gate 		 */
767c478bd9Sstevel@tonic-gate 		struct lblk *nextfree;
777c478bd9Sstevel@tonic-gate 		/*
787c478bd9Sstevel@tonic-gate 		 * the holding block containing this little block.
797c478bd9Sstevel@tonic-gate 		 * This field is used when the block is allocated
807c478bd9Sstevel@tonic-gate 		 */
817c478bd9Sstevel@tonic-gate 		struct holdblk *holder;
827c478bd9Sstevel@tonic-gate 		/*
837c478bd9Sstevel@tonic-gate 		 * Insure over head is multiple of ALIGNSZ
847c478bd9Sstevel@tonic-gate 		 * assumes  ALIGNSZ >= sizeof pointer
857c478bd9Sstevel@tonic-gate 		 */
867c478bd9Sstevel@tonic-gate 		char __Overhead[ALIGNSZ];
877c478bd9Sstevel@tonic-gate 	}  header;
887c478bd9Sstevel@tonic-gate 	/* There is no telling how big this field really is.  */
897c478bd9Sstevel@tonic-gate 	/* This must be on a ALIGNSZ  boundary */
907c478bd9Sstevel@tonic-gate 	char byte;
917c478bd9Sstevel@tonic-gate };
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate /*
947c478bd9Sstevel@tonic-gate  *	template for holding block
957c478bd9Sstevel@tonic-gate  */
967c478bd9Sstevel@tonic-gate struct holdblk {
977c478bd9Sstevel@tonic-gate 	struct holdblk *nexthblk;   /* next holding block */
987c478bd9Sstevel@tonic-gate 	struct holdblk *prevhblk;   /* previous holding block */
997c478bd9Sstevel@tonic-gate 	struct lblk *lfreeq;	/* head of free queue within block */
1007c478bd9Sstevel@tonic-gate 	struct lblk *unused;	/* pointer to 1st little block never used */
1017c478bd9Sstevel@tonic-gate 	long blksz;		/* size of little blocks contained */
1027c478bd9Sstevel@tonic-gate 	struct lblk *__Pad;	/* pad to a multiple of ALIGNSZ */
1037c478bd9Sstevel@tonic-gate 	char space[1];		/* start of space to allocate. */
1047c478bd9Sstevel@tonic-gate 				/* This must be on a ALIGNSZ boundary */
1057c478bd9Sstevel@tonic-gate };
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate  *	 The following manipulate the free queue
1097c478bd9Sstevel@tonic-gate  *
1107c478bd9Sstevel@tonic-gate  *		DELFREEQ will remove x from the free queue
1117c478bd9Sstevel@tonic-gate  *		ADDFREEQ will add an element to the head
1127c478bd9Sstevel@tonic-gate  *			 of the free queue.
1137c478bd9Sstevel@tonic-gate  *		MOVEHEAD will move the free pointers so that
1147c478bd9Sstevel@tonic-gate  *			 x is at the front of the queue
1157c478bd9Sstevel@tonic-gate  */
1167c478bd9Sstevel@tonic-gate #define	ADDFREEQ(x)	(x)->prevfree = &(freeptr[0]);\
1177c478bd9Sstevel@tonic-gate 				(x)->nextfree = freeptr[0].nextfree;\
1187c478bd9Sstevel@tonic-gate 				freeptr[0].nextfree->prevfree = (x);\
1197c478bd9Sstevel@tonic-gate 				freeptr[0].nextfree = (x);\
1207c478bd9Sstevel@tonic-gate 				assert((x)->nextfree != (x));\
1217c478bd9Sstevel@tonic-gate 				assert((x)->prevfree != (x));
1227c478bd9Sstevel@tonic-gate #define	DELFREEQ(x)	(x)->prevfree->nextfree = (x)->nextfree;\
1237c478bd9Sstevel@tonic-gate 				(x)->nextfree->prevfree = (x)->prevfree;\
1247c478bd9Sstevel@tonic-gate 				assert((x)->nextfree != (x));\
1257c478bd9Sstevel@tonic-gate 				assert((x)->prevfree != (x));
1267c478bd9Sstevel@tonic-gate #define	MOVEHEAD(x)	freeptr[1].prevfree->nextfree = freeptr[0].nextfree;\
1277c478bd9Sstevel@tonic-gate 				freeptr[0].nextfree->prevfree = \
1287c478bd9Sstevel@tonic-gate 				    freeptr[1].prevfree;\
1297c478bd9Sstevel@tonic-gate 				(x)->prevfree->nextfree = &(freeptr[1]);\
1307c478bd9Sstevel@tonic-gate 				freeptr[1].prevfree = (x)->prevfree;\
1317c478bd9Sstevel@tonic-gate 				(x)->prevfree = &(freeptr[0]);\
1327c478bd9Sstevel@tonic-gate 				freeptr[0].nextfree = (x);\
1337c478bd9Sstevel@tonic-gate 				assert((x)->nextfree != (x));\
1347c478bd9Sstevel@tonic-gate 				assert((x)->prevfree != (x));
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate  *	The following manipulate the busy flag
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate #define	BUSY	1L
1397c478bd9Sstevel@tonic-gate #define	SETBUSY(x)	((struct header *)((long)(x) | BUSY))
1407c478bd9Sstevel@tonic-gate #define	CLRBUSY(x)	((struct header *)((long)(x) & ~BUSY))
1417c478bd9Sstevel@tonic-gate #define	TESTBUSY(x)	((long)(x) & BUSY)
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate  *	The following manipulate the small block flag
1447c478bd9Sstevel@tonic-gate  */
1457c478bd9Sstevel@tonic-gate #define	SMAL	2L
1467c478bd9Sstevel@tonic-gate #define	SETSMAL(x)	((struct lblk *)((long)(x) | SMAL))
1477c478bd9Sstevel@tonic-gate #define	CLRSMAL(x)	((struct lblk *)((long)(x) & ~SMAL))
1487c478bd9Sstevel@tonic-gate #define	TESTSMAL(x)	((long)(x) & SMAL)
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate  *	The following manipulate both flags.  They must be
1517c478bd9Sstevel@tonic-gate  *	type coerced
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate #define	SETALL(x)	((long)(x) | (SMAL | BUSY))
1547c478bd9Sstevel@tonic-gate #define	CLRALL(x)	((long)(x) & ~(SMAL | BUSY))
1557c478bd9Sstevel@tonic-gate /*
1567c478bd9Sstevel@tonic-gate  *	Other useful constants
1577c478bd9Sstevel@tonic-gate  */
1587c478bd9Sstevel@tonic-gate #define	TRUE	1
1597c478bd9Sstevel@tonic-gate #define	FALSE	0
1607c478bd9Sstevel@tonic-gate #define	HEADSZ	sizeof (struct header)	/* size of unallocated block header */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate /* MINHEAD is the minimum size of an allocated block header */
1637c478bd9Sstevel@tonic-gate #define	MINHEAD	ALIGNSZ
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /* min. block size must as big as HEADSZ */
1667c478bd9Sstevel@tonic-gate #define	MINBLKSZ	HEADSZ
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate /* memory is gotten from sbrk in multiples of BLOCKSZ */
1697c478bd9Sstevel@tonic-gate #define	BLOCKSZ		2048	/* ??? Too Small, ?? pagesize? */
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate #define	GROUND	(struct header *)0
1727c478bd9Sstevel@tonic-gate #define	LGROUND	(struct lblk *)0
1737c478bd9Sstevel@tonic-gate #define	HGROUND	(struct holdblk *)0	/* ground for the holding block queue */
1747c478bd9Sstevel@tonic-gate #ifndef	NULL
1757c478bd9Sstevel@tonic-gate #define	NULL	(char *)0
1767c478bd9Sstevel@tonic-gate #endif
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate  *	Structures and constants describing the holding blocks
1797c478bd9Sstevel@tonic-gate  */
1807c478bd9Sstevel@tonic-gate /* default number of small blocks per holding block */
1817c478bd9Sstevel@tonic-gate #define	NUMLBLKS	100
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate /* size of a holding block with small blocks of size blksz */
1847c478bd9Sstevel@tonic-gate #define	HOLDSZ(blksz)	\
1857c478bd9Sstevel@tonic-gate 	    (sizeof (struct holdblk) - sizeof (struct lblk *) + blksz*numlblks)
1867c478bd9Sstevel@tonic-gate #define	FASTCT	6	/* number of blocks that can be allocated quickly */
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate /* default maximum size block for fast allocation */
1897c478bd9Sstevel@tonic-gate /* assumes initial value of grain == ALIGNSZ */
1907c478bd9Sstevel@tonic-gate #define	MAXFAST	ALIGNSZ*FASTCT
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate #ifdef	debug
1937c478bd9Sstevel@tonic-gate #define	CHECKQ	checkq();
1947c478bd9Sstevel@tonic-gate #else
1957c478bd9Sstevel@tonic-gate #define	CHECKQ
1967c478bd9Sstevel@tonic-gate #endif
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate #endif
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate #endif	/* _MALLINT_H */
203