home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdio.h>
-
- struct smallHeader *p;
-
- #ifndef NOEMALLOC
- #include "Kernel/h/assert.h"
- #include "Kernel/h/emTypes.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/emkDefs.h"
- #endif NOEMALLOC
-
- #ifndef DONTUSEHOLDSIGS
- #include "Kernel/h/stdTypes.h"
- #include "Kernel/h/kEvents.h"
- #endif DONTUSEHOLDSIGS
-
- #include "Kernel/h/system.h"
- /* An implementation of malloc(3), free(3) using the QuickFit method.
- * Guy Almes, May 1983.
- *
- * Cf. MALLOC(3) in the Unix manual for external specifications.
- *
- * Cf. Chuck Weinstock's PhD thesis for a discussion of the techniques
- * used. (Charles Weinstock, Dynamic Storage Allocation Techniques,
- * April 1976, CMU)
- * nb: Unlike the original QuickFit, this implementation assumes that
- * TailFit always works. Also, we want to allow for some other user to
- * be using sbrk.
- *
- * NOTE: change made on 11/29/84 by Mike Schwartz to call HoldSigs and
- * ReleaseSigs at beginning and end of malloc if signals weren't
- * already held (and running in Eden Kernel or EFT context). This is needed
- * in case a Unix routine that uses malloc is called, so that signals
- * will be held as needed to protect the critical region variables during
- * the allocation.
- *
- * Hacked by oystr. While the external specification was met, the
- * internal behaviour of the standard malloc(3) was not. To wit:
- * areas free'd do not have their contents touched until reallocated
- * (Almes actually fixed this after considerable pleading); it is
- * possible to do multiple free's of the same area - that is "x = malloc();
- * free(x); free(x);" causes no damage. This turkey originally did
- * not detect such a situation even though the multiple free's caused
- * it to trash the list structures and blow up at some future malloc
- * call. Realloc was also a disaster area, making the assumption that
- * the old block was in use, which is not necessarily the case.
- *
- * Expanded for Emerald, November 1986:
- * emalloc and emfree added so that Emerald objects can be especially
- * identified as such. May be deleted by defining NOEMALLOC.
- * Modifications to enable EmallocDump to traverse the allocated data areas.
- * Small blocks now also use a link field.
- * The reason is that for garbage collection purposes, it is necessary
- * to keep the size with the data.
- * EmallocDump: copyright 1986 Eric Jul
- */
- /* The parts of Unix used by this module:
- */
-
- /* From BRK(2):
- */
- extern char *brk(); /* set break to addr */
- extern char *sbrk(); /* add incr to break */
-
- /* From END(3):
- */
- extern int end; /* first byte beyond bss region */
-
- /* Design parameters; these can be changed to tune the implementation
- * to a specific application.
- */
-
- #define GrainSize 8
- #define LogGrainSize 3
- #define HeaderSize sizeof(int)
- /* number of bytes: every allocated block is
- * (k+1) * GrainSize, for k >= MinGrains
- * GrainSize == (1 << LogGrainSize)
- */
-
- #define MinBytes 0
- #define MaxBytes (SBrkChunk - HeaderSize) /* = 8188 bytes */
- #define MinGrains 0
- #define MaxGrains ((MaxBytes-MinBytes+1) >> LogGrainSize)
- /* The implementation is tuned to use ExactFit for blocks in the range
- * MinBytes .. MaxBytes
- */
-
- #define BtoG(b) ( ((b)-(GrainSize-HeaderSize) + GrainSize-1) >> LogGrainSize )
- /* convert a number of bytes to a number of grains */
- #define GtoB(g) ( ((g) << LogGrainSize) + (GrainSize-HeaderSize) )
- /* and vice versa */
-
- #define Nil ((char *) 0)
- /* a nil pointer; often coerced to various flavors of pointers */
-
- /* Change (by Eric Jul, July 1986): expanded SBrkChunk from 1024 to 2**13 */
- #define SBrkChunk 8192
- /* the number of bytes to get from sbrk when growing the Tail */
- #define roundUp(a,b) ((char *) ( ((int)(a) + (b)-1) & ~((b)-1) ))
- /* round up an address to the nearest 1k boundary like sbrk does */
-
- /* header for Big blocks allocated via MiscFit */
- typedef struct bigHeader {
- struct bigHeader *bNext; /* the next field links available blocks */
- unsigned bSize; /* the size of the block in bytes */
- } bHeader, *bHeaderPtr;
-
- /* header for Small blocks allocated via ExactFit */
- typedef struct smallHeader {
- struct smallHeader *sNext; /* the next field links available blocks */
- unsigned sSize; /* the size of a used block in bytes */
- } sHeader, *sHeaderPtr;
-
- static char *TailMin = (char *) &end; /* points to 1st byte of Tail */
- static char *TailMax = (char *) &end; /* points just beyond end of Tail */
- char *firstAllocated = (char *) &end; /* first addr allocated */
- /* invariants: TailMin and TailMax are each on int boundaries.
- * The area with addresses TailMin <= addr < TailMax is available.
- * &end <= TailMin <= TailMax == sbrk(0).
- */
-
- /*
- * Free/in use magic numbers. WARNING: if we ever get into 16MB+
- * virtual addresses ( >24 bits), you will have to change the headers.
- * The upper byte of the size field contains INUSEMAGIC if the
- * block has been malloc'd but not freed, 0 if the block is free.
- */
- #define INUSEMAGIC 0x55
- #define SETMAGIC 0x55000000
- #define CLRMAGIC 0x00FFFFFF
-
- #ifndef NOEMALLOC
- /*
- * Emerald uses a different MAGIC number as to distinguish Emerald tagged
- * (with an ODTag) data areas from other data areas.
- * The EMINUSEMAGIC is also put into the bNext field of Big blocks.
- */
- #define EMINUSEMAGIC 0x57
- #define EMSETMAGIC 0x57000000
- #endif NOEMALLOC
-
- static char *TailFit(nBytes)
- register unsigned nBytes;
- {
- register char *oldTailMin;
- #ifdef GORP
- printf(
- " TailFit(%d) called. Tail: %x - %x.\n", nBytes, TailMin, TailMax);
- #endif
- while (TailMax < TailMin+nBytes) {
- register char *oldBreak = sbrk(SBrkChunk);
- if ((int) oldBreak == -1) {
- printf( "sbrk returned a -1!!\n");
- printf(
- "Request %d bytes; current max address is 0x%02x\n", nBytes,
- TailMax);
- printf( "OUT OF VIRTUAL MEMORY --- FATAL\n");
- abort();
- return ( Nil );
- }
- if (oldBreak != TailMax) { /* someone else did an sbrk! */
- #ifdef GORP
- printf(
- "TailFit: pushed TailMin from %x to %x.\n",
- TailMin, roundUp(oldBreak, sizeof(int)));
- #endif
- #ifdef GPROF
- /* Gprof uses sbrk, so live with it ! */
- printf( "oldBreak 0x%06x, TailMax 0x%06x end 0x%06x\n",
- oldBreak, TailMax, &end);
- if (TailMax == (char *) & end) {
- /* We have not allocated anything yet */
- firstAllocated = roundUp(oldBreak, sizeof(int));
-
- }
-
- #else GPROF
- #ifndef NOEMALLOC
- /* must not happen!! */
- /* assert(oldBreak == TailMax);*/
- #endif NOEMALLOC
- #endif GPROF
- TailMin = roundUp(oldBreak, sizeof(int));
- }
- TailMax = oldBreak + SBrkChunk;
- if (TailMax != roundUp(TailMax, SBrkChunk)) {
- /* bring TailMax to a page */
- #ifdef GORP
- printf(
- "TailFit: rounding TailMax from %x to %x.\n",
- TailMax, roundUp(TailMax, SBrkChunk));
- #endif
- #ifndef BRKISFIXEDONSUNSUSINGGPROF
- sbrk(roundUp(TailMax, SBrkChunk) - TailMax);
- TailMax = roundUp(TailMax, SBrkChunk);
- #else
- TailMax = roundUp(TailMax, SBrkChunk);
- (void) brk(TailMax);
- #endif
- }
- } /* we now know we have enough in the Tail */
- oldTailMin = TailMin;
- TailMin += nBytes;
- #ifdef GORP
- printf(
- " TailFit returns %x. Tail: %x - %x.\n", oldTailMin, TailMin, TailMax);
- #endif
- return ( oldTailMin );
- } /* TailFit */
-
- static bHeaderPtr BigList;
- /* BigLists points to a ring of zero or more available blocks, each marked
- * with both a size and a next field. This ring is used in the MiscFit
- * portion of the algorithm, which is a simple FirstFit for very large blocks.
- */
-
- static char *MiscFit(nBytes)
- register unsigned nBytes;
- {
- register bHeaderPtr CurrentHdr, PreviousHdr;
- register unsigned oldSize;
- register char *newBlock = Nil;
- #ifdef GORP
- printf( " MiscFit(%d) called.\n", nBytes);
- #endif
- if (BigList != (bHeaderPtr) Nil) {
- PreviousHdr = BigList;
- CurrentHdr = PreviousHdr->bNext;
- oldSize = PreviousHdr->bSize; /* save real size field, then ... */
- PreviousHdr->bSize = nBytes; /* ... forge a stopper value */
- while (CurrentHdr->bSize < nBytes) {
- PreviousHdr = CurrentHdr;
- CurrentHdr = PreviousHdr->bNext;
- } /* this loop always terminates due to the stopper value */
- BigList->bSize = oldSize; /* restore old size */
- if (CurrentHdr->bSize >= nBytes) { /* MiscFit worked */
- PreviousHdr->bNext = CurrentHdr->bNext;
- BigList =
- (PreviousHdr==CurrentHdr ? (bHeaderPtr) Nil : PreviousHdr);
- CurrentHdr->bSize |= SETMAGIC;
- #ifndef NOEMALLOC
- CurrentHdr->bNext = (bHeaderPtr) SETMAGIC;
- #endif NOEMALLOC
- newBlock = (char *) (CurrentHdr+1);
- }
- }
- #ifdef GORP
- printf( " MiscFit returns %x.\n", newBlock);
- #endif
- return( newBlock );
- } /* MiscFit */
-
- /* p = malloc(nBytes);
- * where nBytes is the number of bytes needed and p is some pointer
- */
-
- static sHeaderPtr AvailList[MaxGrains-MinGrains+1];
- /* AvailList[MinGrains .. MaxGrains] is for ExactFit blocks
- *
- * AvailList[MinGrains..MaxGrains] each point to a LIFO singly-linked list of
- * equal sized blocks. These lists are used in the ExactFit portion of the
- * algorithm.
- */
-
- char *__malloc(fReqBytes)
- int fReqBytes;
- {
- register unsigned reqBytes = (unsigned) fReqBytes;
- register char *newBlock;
- register unsigned nGrains = BtoG(reqBytes);
- #ifndef DONTUSEHOLDSIGS
- extern int SigsHeld;
- int SigsWereHeld;
-
- SigsWereHeld = SigsHeld;
- if (!SigsWereHeld) HoldSigs(); /* Make sure HoldSigs is called once (if
- it wasn't already) if running in Eden
- Kernel context */
- #endif DONTUSEHOLDSIGS
-
- #ifdef GORP
- printf( "malloc(%d) called.\n", (unsigned int) reqBytes);
- #endif
-
- if (reqBytes > MaxBytes) {
- register unsigned nBytes = GtoB(nGrains);
- newBlock = MiscFit(nBytes);
- if (newBlock == Nil) {
- register bHeaderPtr newRawBlock =
- (bHeaderPtr) TailFit(nBytes + sizeof(bHeader));
- if (newRawBlock == (bHeaderPtr) Nil) {
- newBlock = Nil;
- } else {
- newBlock = (char *) (newRawBlock+1);
- newRawBlock->bSize = nBytes | SETMAGIC;
- #ifndef NOEMALLOC
- newRawBlock->bNext = (bHeaderPtr) SETMAGIC;
- #endif NOEMALLOC
- }
- }
- } else {
- register sHeaderPtr newRawBlock = AvailList[nGrains];
- if (newRawBlock != (sHeaderPtr) Nil) {
- AvailList[nGrains] = newRawBlock->sNext;
- newRawBlock->sSize = GtoB(nGrains) | SETMAGIC;
- newBlock = (char *) (newRawBlock + 1);
- } else {
- newRawBlock = (sHeaderPtr) TailFit(GtoB(nGrains)+sizeof(sHeader));
- if (newRawBlock == (sHeaderPtr) Nil) {
- newBlock = Nil;
- } else {
- newBlock = (char *) (newRawBlock + 1);
- newRawBlock->sSize = GtoB(nGrains) | SETMAGIC;
- }
- }
- }
- #ifdef GORP
- printf( "malloc returns %x.\n", newBlock);
- (void) fflush(stderr);
- #endif
-
- #ifndef DONTUSEHOLDSIGS
- if (!SigsWereHeld) ReleaseSigs();
- #endif DONTUSEHOLDSIGS
-
- return( newBlock );
- } /* malloc */
-
- /**********************************************************************/
- /* Free */
- /**********************************************************************/
-
- __free(ptr)
- char *ptr;
- {
- register sHeaderPtr oldBlock = ((sHeaderPtr) ptr) - 1;
- register unsigned nGrains = BtoG( (oldBlock->sSize & CLRMAGIC) );
-
- #ifndef DONTUSEHOLDSIGS
- extern int SigsHeld;
- int SigsWereHeld;
-
- SigsWereHeld = SigsHeld;
- if (!SigsWereHeld) HoldSigs(); /* Make sure HoldSigs is called once (if
- it was not already) if running in Eden
- Kernel context */
- #endif DONTUSEHOLDSIGS
-
- if ( ! (oldBlock->sSize & SETMAGIC) ) {
- /* already free */
- printf( "free(%x) called returning %d grains (already free!).\n",
- ptr, nGrains);
- return;
- }
- else oldBlock->sSize &= CLRMAGIC;
-
- #ifdef GORP
- printf( "free(%x) called returning %d grains.\n", ptr, nGrains);
- #endif
-
- if (nGrains <= MaxGrains) {
- oldBlock->sNext = AvailList[nGrains];
- AvailList[nGrains] = oldBlock;
- } else {
- register bHeaderPtr oldBlock2 = ((bHeaderPtr) ptr) - 1;
- if (BigList == (bHeaderPtr) Nil) {
- BigList = oldBlock2;
- oldBlock2->bNext = oldBlock2;
- } else {
- oldBlock2->bNext = BigList->bNext;
- BigList->bNext = oldBlock2;
- }
- }
-
- #ifdef GORP
- (void) fflush(stderr);
- #endif
- #ifndef DONTUSEHOLDSIGS
- if (!SigsWereHeld) ReleaseSigs();
- #endif DONTUSEHOLDSIGS
-
- } /* free */
-
- /**********************************************************************/
- /* Realloc */
- /**********************************************************************/
-
- char *__realloc(oldBlock, nBytes)
- register char *oldBlock;
- unsigned nBytes;
- {
- register char *newBlock = __malloc((int) nBytes);
-
- #ifndef DONTUSEHOLDSIGS
- extern int SigsHeld;
- int SigsWereHeld;
-
- SigsWereHeld = SigsHeld;
- if (!SigsWereHeld) HoldSigs(); /* Make sure HoldSigs is called once (if
- it wasn't already) if running in Eden
- Kernel context */
- #endif DONTUSEHOLDSIGS
-
- if (newBlock != Nil) {
- register int *newPtr = (int *) newBlock;
- register int *oldPtr = (int *) oldBlock;
- register sHeaderPtr oldRawBlock = ((sHeaderPtr) oldPtr) - 1;
- register unsigned count = (GrainSize/sizeof(int)) *
- ((oldRawBlock->sSize > nBytes)
- ? BtoG(nBytes)
- : BtoG((oldRawBlock->sSize & CLRMAGIC)));
- while (count != 0) {
- *newPtr++ = *oldPtr++;
- count--;
- }
- *newPtr++ = *oldPtr++;
- __free(oldBlock);
- }
-
- #ifndef DONTUSEHOLDSIGS
- if (!SigsWereHeld) ReleaseSigs();
- #endif DONTUSEHOLDSIGS
- return( newBlock );
- } /* realloc */
-
-
- #ifndef NOEMALLOC
- /**********************************************************************/
- /* EmMiscFit */
- /**********************************************************************/
-
- static char *EmMiscFit(nBytes)
- register unsigned nBytes;
- {
- register bHeaderPtr CurrentHdr, PreviousHdr;
- register unsigned oldSize;
- register char *newBlock = Nil;
- #ifdef GORP
- printf( " EmMiscFit(%d) called.\n", nBytes);
- #endif
- if (BigList != (bHeaderPtr) Nil) {
- PreviousHdr = BigList;
- CurrentHdr = PreviousHdr->bNext;
- oldSize = PreviousHdr->bSize; /* save real size field, then ... */
- PreviousHdr->bSize = nBytes; /* ... forge a stopper value */
- while (CurrentHdr->bSize < nBytes) {
- PreviousHdr = CurrentHdr;
- CurrentHdr = PreviousHdr->bNext;
- } /* this loop always terminates due to the stopper value */
- BigList->bSize = oldSize; /* restore old size */
- if (CurrentHdr->bSize >= nBytes) { /* EmMiscFit worked */
- PreviousHdr->bNext = CurrentHdr->bNext;
- BigList =
- (PreviousHdr==CurrentHdr ? (bHeaderPtr) Nil : PreviousHdr);
- CurrentHdr->bSize |= EMSETMAGIC;
- CurrentHdr->bNext = (bHeaderPtr) EMSETMAGIC;
- newBlock = (char *) (CurrentHdr+1);
- }
- }
- #ifdef GORP
- printf( " EmMiscFit returns %x.\n", newBlock);
- #endif
- return( newBlock );
- } /* EmMiscFit */
-
- /**********************************************************************/
- /* emalloc */
- /**********************************************************************/
-
- char *emalloc(fReqBytes)
- int fReqBytes;
- {
- register unsigned reqBytes = (unsigned) fReqBytes+sizeof(int) + 0 /* Safety */;
- register char *newBlock;
- register unsigned nGrains = BtoG(reqBytes);
- #ifndef DONTUSEHOLDSIGS
- extern int SigsHeld;
- int SigsWereHeld;
-
- SigsWereHeld = SigsHeld;
- if (!SigsWereHeld) HoldSigs(); /* Make sure HoldSigs is called once (if
- it wasn't already) if running in Eden
- Kernel context */
- #endif DONTUSEHOLDSIGS
-
- #ifdef GORP
- printf( "emalloc(%d) called.\n", (unsigned int) reqBytes);
- #endif
-
-
- if (reqBytes > MaxBytes) {
- register unsigned nBytes = GtoB(nGrains);
- newBlock = EmMiscFit(nBytes);
- if (newBlock == Nil) {
- register bHeaderPtr newRawBlock =
- (bHeaderPtr) TailFit(nBytes + sizeof(bHeader));
- if (newRawBlock == (bHeaderPtr) Nil) {
- newBlock = Nil;
- } else {
- newBlock = (char *) (newRawBlock+1);
- newRawBlock->bSize = nBytes | EMSETMAGIC;
- newRawBlock->bNext = (bHeaderPtr) EMSETMAGIC;
- }
- }
- } else {
- register sHeaderPtr newRawBlock = AvailList[nGrains];
- if (newRawBlock != (sHeaderPtr) Nil) {
- AvailList[nGrains] = newRawBlock->sNext;
- newRawBlock->sSize = GtoB(nGrains) | EMSETMAGIC;
- newBlock = (char *) (newRawBlock + 1);
- } else {
- newRawBlock = (sHeaderPtr) TailFit(GtoB(nGrains)+sizeof(sHeader));
- if (newRawBlock == (sHeaderPtr) Nil) {
- newBlock = Nil;
- } else {
- newBlock = (char *) (newRawBlock + 1);
- newRawBlock->sSize = GtoB(nGrains) | EMSETMAGIC;
- }
- }
- }
- #ifdef GORP
- printf( "emalloc returns %x.\n", newBlock);
- (void) fflush(stderr);
- #endif
-
- #ifndef DONTUSEHOLDSIGS
- if (!SigsWereHeld) ReleaseSigs();
- #endif DONTUSEHOLDSIGS
-
- KMDTrace("Emalloc", 3, "Emalloc %3d bytes returns addr 0x%04x\n",
- reqBytes, newBlock);
-
- return( newBlock );
- } /* emalloc */
-
- /**********************************************************************/
- /* emfree */
- /**********************************************************************/
-
- void emfree(ptr)
- char *ptr;
- {
- register sHeaderPtr oldBlock = ((sHeaderPtr) ptr) - 1;
- register unsigned nGrains = BtoG( (oldBlock->sSize & CLRMAGIC) );
-
- #ifndef DONTUSEHOLDSIGS
- extern int SigsHeld;
- int SigsWereHeld;
-
- SigsWereHeld = SigsHeld;
- if (!SigsWereHeld) HoldSigs(); /* Make sure HoldSigs is called once (if
- it was not already) if running in Eden
- Kernel context */
- #endif DONTUSEHOLDSIGS
-
- KMDTrace("Emalloc", 3, "emfree(0x%04x)\n", ptr);
-
- if ( ! (oldBlock->sSize & EMSETMAGIC) ) {
- /* already free */
- printf(
- "free(%x) called returning %d grains (already free!).\n",
- ptr, nGrains);
- abort();
- return;
- }
- else oldBlock->sSize &= CLRMAGIC;
-
- #ifdef GORP
- printf( "free(%x) called returning %d grains.\n", ptr, nGrains);
- #endif
-
- if (nGrains <= MaxGrains) {
- oldBlock->sNext = AvailList[nGrains];
- AvailList[nGrains] = oldBlock;
- } else {
- register bHeaderPtr oldBlock2 = ((bHeaderPtr) ptr) - 1;
- if (BigList == (bHeaderPtr) Nil) {
- BigList = oldBlock2;
- oldBlock2->bNext = oldBlock2;
- } else {
- oldBlock2->bNext = BigList->bNext;
- BigList->bNext = oldBlock2;
- }
- }
-
- #ifdef GORP
- (void) fflush(stderr);
- #endif
- #ifndef DONTUSEHOLDSIGS
- if (!SigsWereHeld) ReleaseSigs();
- #endif DONTUSEHOLDSIGS
-
- } /* emfree */
-
- /**********************************************************************/
- /* EmallocDump */
- /**********************************************************************/
-
- /* Snapshot */
- void EmallocDump()
- {
- register sHeaderPtr s;
- register bHeaderPtr b;
- register unsigned int mark;
- register unsigned int size;
- register int isBig;
-
- KMDPrint("EmallocDump called\n");
- KMDPrint("Addr\tSize\tSize\tUsage\n");
-
- for (s = (sHeaderPtr) firstAllocated; (char *) s < TailMin;) {
- mark = (s->sSize & ~CLRMAGIC);
- size = (s->sSize & CLRMAGIC);
-
- if (isBig = (size == 0)) {
- /* It is a big block */
- b = (bHeaderPtr) (s);
- size = (b->bSize & CLRMAGIC);
- }
- if (mark == SETMAGIC) {
- KMDPrint("%06x\t%06x\t%06d\tKernel\t%s\n",
- (isBig ? (char *) (b+1) : (char *) (s+1)), size, size,
- (isBig ? "Big" : ""));
- } else if (mark == EMSETMAGIC) {
- KMDPrint("%06x\t%06x\t%06d\tEm\t%s\n",
- (isBig ? (char *) (b+1) : (char *) (s+1)), size, size,
- (isBig ? "Big" : ""));
- } else if (mark == 0) {
- KMDPrint("%06x\t%06x\t%06d\tFree\t%s\n",
- (isBig ? (char *) (b+1) : (char *) (s+1)), size, size,
- (isBig ? "Big" : ""));
- } else {
- /* error */
- abort();
- }
- s = (sHeaderPtr) ( (char *) s + size +
- (isBig ? sizeof(bHeader) : sizeof(sHeader)));
- }
- KMDPrint("Done\n");
- }
-
- /**********************************************************************/
- /* EmallocDump */
- /**********************************************************************/
-
- void EmallocForEach(fHandlerPtr)
- GenericHandlerPtr fHandlerPtr;
- /* Calls the given handler for each allocated Emerald Data Area. */
- /* Declaration for callback: void CallBack(fAddr, fSize) */
- {
- register sHeaderPtr s;
- register bHeaderPtr b;
- register unsigned int mark;
- register unsigned int size;
- register int isBig;
-
-
- for (s = (sHeaderPtr) firstAllocated; (char *) s < TailMin;) {
- mark = (s->sSize & ~CLRMAGIC);
- size = (s->sSize & CLRMAGIC);
-
- if (isBig = (size == 0)) {
- /* It is a big block */
- b = (bHeaderPtr) (s);
- size = (b->bSize & CLRMAGIC);
- }
- if (mark == SETMAGIC) {
- /* Skip normal data areas */
- } else if (mark == EMSETMAGIC) {
- /* Call back for Emerald data areas */
- (*fHandlerPtr)(isBig ? (int) (b+1) : (int) (s+1), size);
- } else if (mark == 0) {
- /* Skip unallocated data areas */
- } else {
- ErrMsg("error: allocation invariant broken at 0x%06x\m",
- s);
- ErrMsg("firstAllocated: 0x%06x, mark: 0x%02x\n", firstAllocated,
- mark);
- abort();
- }
- s = (sHeaderPtr) ( (char *) s + size +
- (isBig ? sizeof(bHeader) : sizeof(sHeader)));
- }
- }
-
- /**********************************************************************/
- /* emallocnil */
- /**********************************************************************/
-
- char *emallocnil(fReqBytes)
- int fReqBytes;
- /* Same as emalloc but nil out the area except for the first two words */
- {
- register char *q;
- register int *x, *last;
- q = emalloc(fReqBytes);
- last = (int *) (q + fReqBytes - fReqBytes % 4);
- for (x = ((int *) q) + 2; x < last; x++) {
- *x = (int) EMNIL;
- }
- return ((char *) q);
- }
-
- /**********************************************************************/
- /* EmallocInit */
- /**********************************************************************/
-
- void EmallocInit()
- {
- KMDSetSnap(EmallocDump);
- KMDSetTrace(Emalloc);
- KMDTrace("Emalloc", 5, "Emalloc\n");
- }
-
- #endif NOEMALLOC
-
-