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