/********************************************************************** * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. * * All Rights Reserved. * * Reference "/usr/src/COPYRIGHT" for applicable restrictions. * **********************************************************************/ /* SCCSID: @(#)mallint.h 3.0 4/22/86 */ /* (System 5) mallint.h 1.1 */ /* template for the header */ struct header { struct header *nextblk; struct header *nextfree; struct header *prevfree; #ifdef pdp11 struct header *dummy; /* pad to a multple of 4 bytes */ #endif }; /* template for a small block */ struct lblk { union { struct lblk *nextfree; /* the next free little block in this holding block. This field is used when the block is free */ struct holdblk *holder; /* the holding block containing this little block. This field is used when the block is allocated */ } header; char byte; /* There is no telling how big this field freally is. */ }; /* template for holding block */ struct holdblk { struct holdblk *nexthblk; /* next holding block */ struct holdblk *prevhblk; /* previous holding block */ struct lblk *lfreeq; /* head of free queue within block */ struct lblk *unused; /* pointer to 1st little block never used */ int blksz; /* size of little blocks contained */ #ifdef pdp11 int pad; /* pad to an even # of words */ #endif char space[1]; /* start of space to allocate. This must be on a word boundary */ }; /* The following manipulate the free queue DELFREEQ will remove x from the free queue ADDFREEQ will add an element to the head of the free queue. MOVEHEAD will move the free pointers so that x is at the front of the queue */ #define ADDFREEQ(x) (x)->prevfree = &(freeptr[0]);\ (x)->nextfree = freeptr[0].nextfree;\ freeptr[0].nextfree->prevfree = (x);\ freeptr[0].nextfree = (x);\ assert((x)->nextfree != (x));\ assert((x)->prevfree != (x)); #define DELFREEQ(x) (x)->prevfree->nextfree = (x)->nextfree;\ (x)->nextfree->prevfree = (x)->prevfree;\ assert((x)->nextfree != (x));\ assert((x)->prevfree != (x)); #define MOVEHEAD(x) freeptr[1].prevfree->nextfree = \ freeptr[0].nextfree;\ freeptr[0].nextfree->prevfree = \ freeptr[1].prevfree;\ (x)->prevfree->nextfree = &(freeptr[1]);\ freeptr[1].prevfree = (x)->prevfree;\ (x)->prevfree = &(freeptr[0]);\ freeptr[0].nextfree = (x);\ assert((x)->nextfree != (x));\ assert((x)->prevfree != (x)); /* The following manipulate the busy flag */ #define BUSY 1 #define SETBUSY(x) ((struct header *)((int)(x) | BUSY)) #define CLRBUSY(x) ((struct header *)((int)(x) & ~BUSY)) #define TESTBUSY(x) ((int)(x) & BUSY) /* The following manipulate the small block flag */ #define SMAL 2 #define SETSMAL(x) ((struct lblk *)((int)(x) | SMAL)) #define CLRSMAL(x) ((struct lblk *)((int)(x) & ~SMAL)) #define TESTSMAL(x) ((int)(x) & SMAL) /* The following manipulate both flags. They must be type coerced */ #define SETALL(x) ((int)(x) | (SMAL | BUSY)) #define CLRALL(x) ((int)(x) & ~(SMAL | BUSY)) /* Other useful constants */ #define TRUE 1 #define FALSE 0 #define HEADSZ sizeof(struct header) /* size of unallocated block header */ /* MINHEAD is the minimum size of an allocated block header */ #ifdef pdp11 #define MINHEAD 4 #else #define MINHEAD sizeof(struct header *) #endif #define MINBLKSZ 12 /* min. block size must as big as HEADSZ */ #define BLOCKSZ 2048 /* memory is gotten from sbrk in multiples of BLOCKSZ */ #define GROUND (struct header *)0 #define LGROUND (struct lblk *)0 /* ground for a queue within a holding block */ #define HGROUND (struct holdblk *)0 /* ground for the holding block queue */ /* number of bytes to align to (must be at least 4, because lower 2 bits are used for flags */ #define ALIGNSZ 4 #ifndef NULL #define NULL (char *)0 #endif /* Structures and constants describing the holding blocks */ #define NUMLBLKS 100 /* default number of small blocks per holding block */ /* size of a holding block with small blocks of size blksz */ #define HOLDSZ(blksz) (sizeof(struct holdblk) - sizeof(int) + blksz*numlblks) #ifndef pdp11 #define FASTCT 6 /* default number of block sizes that can be allocated quickly */ #else #define FASTCT 0 #endif #define MAXFAST ALIGNSZ*FASTCT /* default maximum size block for fast allocation */ #ifdef debug #define CHECKQ checkq(); static checkq() { register struct header *p; p = &(freeptr[0]); /* check forward */ while(p != &(freeptr[1])) { p = p->nextfree; assert(p->prevfree->nextfree == p); } /* check backward */ while(p != &(freeptr[0])) { p = p->prevfree; assert(p->nextfree->prevfree == p); } } #else #define CHECKQ #endif