diff options
Diffstat (limited to 'generic/tclAlloc.c')
-rw-r--r-- | generic/tclAlloc.c | 509 |
1 files changed, 268 insertions, 241 deletions
diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c index 5022618..7647b4d 100644 --- a/generic/tclAlloc.c +++ b/generic/tclAlloc.c @@ -1,10 +1,10 @@ -/* +/* * tclAlloc.c -- * - * This is a very fast storage allocator. It allocates blocks of a - * small number of different sizes, and keeps free lists of each size. - * Blocks that don't exactly fit are passed up to the next larger size. - * Blocks over a certain size are directly allocated from the system. + * This is a very fast storage allocator. It allocates blocks of a small + * number of different sizes, and keeps free lists of each size. Blocks + * that don't exactly fit are passed up to the next larger size. Blocks + * over a certain size are directly allocated from the system. * * Copyright (c) 1983 Regents of the University of California. * Copyright (c) 1996-1997 Sun Microsystems, Inc. @@ -12,8 +12,8 @@ * * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* @@ -21,10 +21,8 @@ * that has significantly reduced lock contention. */ -#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC) || defined(TCL_MEM_DEBUG) - #include "tclInt.h" -#include "tclPort.h" +#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC) #if USE_TCLALLOC @@ -35,58 +33,49 @@ #endif /* - * We should really make use of AC_CHECK_TYPE(caddr_t) - * here, but it can wait until Tcl uses config.h properly. - */ -#if defined(MAC_TCL) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) -typedef unsigned long caddr_t; -#endif - -/* - * Alignment for allocated memory. + * We should really make use of AC_CHECK_TYPE(caddr_t) here, but it can wait + * until Tcl uses config.h properly. */ -#if defined(__APPLE__) -#define ALLOCALIGN 16 -#else -#define ALLOCALIGN 8 +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) +typedef unsigned long caddr_t; #endif /* - * The overhead on a block is at least 8 bytes. When free, this space - * contains a pointer to the next free block, and the bottom two bits must - * be zero. When in use, the first byte is set to MAGIC, and the second - * byte is the size index. The remaining bytes are for alignment. - * If range checking is enabled then a second word holds the size of the - * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC). - * The order of elements is critical: ov_magic must overlay the low order - * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern. + * The overhead on a block is at least 8 bytes. When free, this space contains + * a pointer to the next free block, and the bottom two bits must be zero. + * When in use, the first byte is set to MAGIC, and the second byte is the + * size index. The remaining bytes are for alignment. If range checking is + * enabled then a second word holds the size of the requested block, less 1, + * rounded up to a multiple of sizeof(RMAGIC). The order of elements is + * critical: ov.magic must overlay the low order bits of ov.next, and ov.magic + * can not be a valid ov.next bit pattern. */ union overhead { - union overhead *ov_next; /* when free */ - unsigned char ov_padding[ALLOCALIGN];/* align struct to ALLOCALIGN bytes */ + union overhead *next; /* when free */ + unsigned char padding[TCL_ALLOCALIGN]; /* align struct to TCL_ALLOCALIGN bytes */ struct { - unsigned char ovu_magic0; /* magic number */ - unsigned char ovu_index; /* bucket # */ - unsigned char ovu_unused; /* unused */ - unsigned char ovu_magic1; /* other magic number */ + unsigned char magic0; /* magic number */ + unsigned char index; /* bucket # */ + unsigned char unused; /* unused */ + unsigned char magic1; /* other magic number */ #ifdef RCHECK - unsigned short ovu_rmagic; /* range magic number */ - unsigned long ovu_size; /* actual block size */ - unsigned short ovu_unused2; /* padding to 8-byte align */ + unsigned short rmagic; /* range magic number */ + unsigned long size; /* actual block size */ + unsigned short unused2; /* padding to 8-byte align */ #endif } ovu; -#define ov_magic0 ovu.ovu_magic0 -#define ov_magic1 ovu.ovu_magic1 -#define ov_index ovu.ovu_index -#define ov_rmagic ovu.ovu_rmagic -#define ov_size ovu.ovu_size +#define overMagic0 ovu.magic0 +#define overMagic1 ovu.magic1 +#define bucketIndex ovu.index +#define rangeCheckMagic ovu.rmagic +#define realBlockSize ovu.size }; -#define MAGIC 0xef /* magic # on accounting info */ -#define RMAGIC 0x5555 /* magic # on range info */ +#define MAGIC 0xef /* magic # on accounting info */ +#define RMAGIC 0x5555 /* magic # on range info */ #ifdef RCHECK #define RSLOP sizeof (unsigned short) @@ -97,38 +86,45 @@ union overhead { #define OVERHEAD (sizeof(union overhead) + RSLOP) /* - * nextf[i] is the pointer to the next free block of size 2^(i+3). The + * Macro to make it easier to refer to the end-of-block guard magic. + */ + +#define BLOCK_END(overPtr) \ + (*(unsigned short *)((caddr_t)((overPtr) + 1) + (overPtr)->realBlockSize)) + +/* + * nextf[i] is the pointer to the next free block of size 2^(i+3). The * smallest allocatable block is MINBLOCK bytes. The overhead information * precedes the data area returned to the user. */ -#define MINBLOCK ((sizeof(union overhead) + (ALLOCALIGN-1)) & ~(ALLOCALIGN-1)) +#define MINBLOCK ((sizeof(union overhead) + (TCL_ALLOCALIGN-1)) & ~(TCL_ALLOCALIGN-1)) #define NBUCKETS (13 - (MINBLOCK >> 4)) #define MAXMALLOC (1<<(NBUCKETS+2)) -static union overhead *nextf[NBUCKETS]; +static union overhead *nextf[NBUCKETS]; -/* - * The following structure is used to keep track of all system memory - * currently owned by Tcl. When finalizing, all this memory will - * be returned to the system. +/* + * The following structure is used to keep track of all system memory + * currently owned by Tcl. When finalizing, all this memory will be returned + * to the system. */ struct block { struct block *nextPtr; /* Linked list. */ - struct block *prevPtr; /* Linked list for big blocks, ensures 8-byte + struct block *prevPtr; /* Linked list for big blocks, ensures 8-byte * alignment for suballocated blocks. */ }; -static struct block *blockList; /* Tracks the suballocated blocks. */ -static struct block bigBlocks = { /* Big blocks aren't suballocated. */ +static struct block *blockList; /* Tracks the suballocated blocks. */ +static struct block bigBlocks={ /* Big blocks aren't suballocated. */ &bigBlocks, &bigBlocks }; /* - * The allocator is protected by a special mutex that must be - * explicitly initialized. Futhermore, because Tcl_Alloc may be - * used before anything else in Tcl, we make this module self-initializing - * after all with the allocInit variable. + * The allocator is protected by a special mutex that must be explicitly + * initialized. Futhermore, because Tcl_Alloc may be used before anything else + * in Tcl, we make this module self-initializing after all with the allocInit + * variable. */ #ifdef TCL_THREADS @@ -136,21 +132,20 @@ static Tcl_Mutex *allocMutexPtr; #endif static int allocInit = 0; - #ifdef MSTATS /* - * nmalloc[i] is the difference between the number of mallocs and frees - * for a given block size. + * numMallocs[i] is the difference between the number of mallocs and frees for + * a given block size. */ -static unsigned int nmalloc[NBUCKETS+1]; +static unsigned int numMallocs[NBUCKETS+1]; #include <stdio.h> #endif #if defined(DEBUG) || defined(RCHECK) -#define ASSERT(p) if (!(p)) panic(# p) -#define RANGE_ASSERT(p) if (!(p)) panic(# p) +#define ASSERT(p) if (!(p)) Tcl_Panic(# p) +#define RANGE_ASSERT(p) if (!(p)) Tcl_Panic(# p) #else #define ASSERT(p) #define RANGE_ASSERT(p) @@ -160,8 +155,7 @@ static unsigned int nmalloc[NBUCKETS+1]; * Prototypes for functions used only in this file. */ -static void MoreCore _ANSI_ARGS_((int bucket)); - +static void MoreCore(int bucket); /* *------------------------------------------------------------------------- @@ -180,7 +174,7 @@ static void MoreCore _ANSI_ARGS_((int bucket)); */ void -TclInitAlloc() +TclInitAlloc(void) { if (!allocInit) { allocInit = 1; @@ -195,27 +189,26 @@ TclInitAlloc() * * TclFinalizeAllocSubsystem -- * - * Release all resources being used by this subsystem, including - * aggressively freeing all memory allocated by TclpAlloc() that - * has not yet been released with TclpFree(). - * - * After this function is called, all memory allocated with - * TclpAlloc() should be considered unusable. + * Release all resources being used by this subsystem, including + * aggressively freeing all memory allocated by TclpAlloc() that has not + * yet been released with TclpFree(). + * + * After this function is called, all memory allocated with TclpAlloc() + * should be considered unusable. * * Results: * None. * * Side effects: - * This subsystem is self-initializing, since memory can be - * allocated before Tcl is formally initialized. After this call, - * this subsystem has been reset to its initial state and is - * usable again. + * This subsystem is self-initializing, since memory can be allocated + * before Tcl is formally initialized. After this call, this subsystem + * has been reset to its initial state and is usable again. * *------------------------------------------------------------------------- */ void -TclFinalizeAllocSubsystem() +TclFinalizeAllocSubsystem(void) { unsigned int i; struct block *blockPtr, *nextPtr; @@ -235,14 +228,14 @@ TclFinalizeAllocSubsystem() bigBlocks.nextPtr = &bigBlocks; bigBlocks.prevPtr = &bigBlocks; - for (i = 0; i < NBUCKETS; i++) { + for (i=0 ; i<NBUCKETS ; i++) { nextf[i] = NULL; #ifdef MSTATS - nmalloc[i] = 0; + numMallocs[i] = 0; #endif } #ifdef MSTATS - nmalloc[i] = 0; + numMallocs[i] = 0; #endif Tcl_MutexUnlock(allocMutexPtr); } @@ -264,30 +257,32 @@ TclFinalizeAllocSubsystem() */ char * -TclpAlloc(nbytes) - unsigned int nbytes; /* Number of bytes to allocate. */ +TclpAlloc( + unsigned int numBytes) /* Number of bytes to allocate. */ { - register union overhead *op; + register union overhead *overPtr; register long bucket; - register unsigned amt; + register unsigned amount; struct block *bigBlockPtr = NULL; if (!allocInit) { /* - * We have to make the "self initializing" because Tcl_Alloc - * may be used before any other part of Tcl. E.g., see - * main() for tclsh! + * We have to make the "self initializing" because Tcl_Alloc may be + * used before any other part of Tcl. E.g., see main() for tclsh! */ + TclInitAlloc(); } Tcl_MutexLock(allocMutexPtr); + /* - * First the simple case: we simple allocate big blocks directly + * First the simple case: we simple allocate big blocks directly. */ - if (nbytes >= MAXMALLOC - OVERHEAD) { - if (nbytes <= UINT_MAX - OVERHEAD - sizeof(struct block)) { - bigBlockPtr = (struct block *) TclpSysAlloc((unsigned) - (sizeof(struct block) + OVERHEAD + nbytes), 0); + + if (numBytes >= MAXMALLOC - OVERHEAD) { + if (numBytes <= UINT_MAX - OVERHEAD -sizeof(struct block)) { + bigBlockPtr = (struct block *) TclpSysAlloc((unsigned) + (sizeof(struct block) + OVERHEAD + numBytes), 0); } if (bigBlockPtr == NULL) { Tcl_MutexUnlock(allocMutexPtr); @@ -298,74 +293,83 @@ TclpAlloc(nbytes) bigBlockPtr->prevPtr = &bigBlocks; bigBlockPtr->nextPtr->prevPtr = bigBlockPtr; - op = (union overhead *) (bigBlockPtr + 1); - op->ov_magic0 = op->ov_magic1 = MAGIC; - op->ov_index = 0xff; + overPtr = (union overhead *) (bigBlockPtr + 1); + overPtr->overMagic0 = overPtr->overMagic1 = MAGIC; + overPtr->bucketIndex = 0xff; #ifdef MSTATS - nmalloc[NBUCKETS]++; + numMallocs[NBUCKETS]++; #endif + #ifdef RCHECK /* - * Record allocated size of block and - * bound space with magic numbers. + * Record allocated size of block and bound space with magic numbers. */ - op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); - op->ov_rmagic = RMAGIC; - *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; + + overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1); + overPtr->rangeCheckMagic = RMAGIC; + BLOCK_END(overPtr) = RMAGIC; #endif + Tcl_MutexUnlock(allocMutexPtr); - return (void *)(op+1); + return (void *)(overPtr+1); } + /* - * Convert amount of memory requested into closest block size - * stored in hash buckets which satisfies request. - * Account for space used per block for accounting. + * Convert amount of memory requested into closest block size stored in + * hash buckets which satisfies request. Account for space used per block + * for accounting. */ - amt = MINBLOCK; /* size of first bucket */ + amount = MINBLOCK; /* size of first bucket */ bucket = MINBLOCK >> 4; - while (nbytes + OVERHEAD > amt) { - amt <<= 1; - if (amt == 0) { + while (numBytes + OVERHEAD > amount) { + amount <<= 1; + if (amount == 0) { Tcl_MutexUnlock(allocMutexPtr); - return (NULL); + return NULL; } bucket++; } - ASSERT( bucket < NBUCKETS ); + ASSERT(bucket < NBUCKETS); /* - * If nothing in hash bucket right now, - * request more memory from the system. + * If nothing in hash bucket right now, request more memory from the + * system. */ - if ((op = nextf[bucket]) == NULL) { + + if ((overPtr = nextf[bucket]) == NULL) { MoreCore(bucket); - if ((op = nextf[bucket]) == NULL) { + if ((overPtr = nextf[bucket]) == NULL) { Tcl_MutexUnlock(allocMutexPtr); - return (NULL); + return NULL; } } + /* * Remove from linked list */ - nextf[bucket] = op->ov_next; - op->ov_magic0 = op->ov_magic1 = MAGIC; - op->ov_index = (unsigned char) bucket; + + nextf[bucket] = overPtr->next; + overPtr->overMagic0 = overPtr->overMagic1 = MAGIC; + overPtr->bucketIndex = (unsigned char) bucket; + #ifdef MSTATS - nmalloc[bucket]++; + numMallocs[bucket]++; #endif + #ifdef RCHECK /* - * Record allocated size of block and - * bound space with magic numbers. + * Record allocated size of block and bound space with magic numbers. */ - op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); - op->ov_rmagic = RMAGIC; - *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; + + overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1); + overPtr->rangeCheckMagic = RMAGIC; + BLOCK_END(overPtr) = RMAGIC; #endif + Tcl_MutexUnlock(allocMutexPtr); - return ((char *)(op + 1)); + return ((char *)(overPtr + 1)); } /* @@ -387,28 +391,29 @@ TclpAlloc(nbytes) */ static void -MoreCore(bucket) - int bucket; /* What bucket to allocat to. */ +MoreCore( + int bucket) /* What bucket to allocat to. */ { - register union overhead *op; - register long sz; /* size of desired block */ - long amt; /* amount to allocate */ - int nblks; /* how many blocks we get */ + register union overhead *overPtr; + register long size; /* size of desired block */ + long amount; /* amount to allocate */ + int numBlocks; /* how many blocks we get */ struct block *blockPtr; /* - * sbrk_size <= 0 only for big, FLUFFY, requests (about - * 2^30 bytes on a VAX, I think) or for a negative arg. + * sbrk_size <= 0 only for big, FLUFFY, requests (about 2^30 bytes on a + * VAX, I think) or for a negative arg. */ - sz = 1 << (bucket + 3); - ASSERT(sz > 0); - amt = MAXMALLOC; - nblks = amt / sz; - ASSERT(nblks*sz == amt); + size = 1 << (bucket + 3); + ASSERT(size > 0); - blockPtr = (struct block *) TclpSysAlloc((unsigned) - (sizeof(struct block) + amt), 1); + amount = MAXMALLOC; + numBlocks = amount / size; + ASSERT(numBlocks*size == amount); + + blockPtr = (struct block *) TclpSysAlloc((unsigned) + (sizeof(struct block) + amount), 1); /* no more room! */ if (blockPtr == NULL) { return; @@ -416,18 +421,18 @@ MoreCore(bucket) blockPtr->nextPtr = blockList; blockList = blockPtr; - op = (union overhead *) (blockPtr + 1); - + overPtr = (union overhead *) (blockPtr + 1); + /* - * Add new memory allocated to that on - * free list for this hash bucket. + * Add new memory allocated to that on free list for this hash bucket. */ - nextf[bucket] = op; - while (--nblks > 0) { - op->ov_next = (union overhead *)((caddr_t)op + sz); - op = (union overhead *)((caddr_t)op + sz); + + nextf[bucket] = overPtr; + while (--numBlocks > 0) { + overPtr->next = (union overhead *)((caddr_t)overPtr + size); + overPtr = (union overhead *)((caddr_t)overPtr + size); } - op->ov_next = (union overhead *)NULL; + overPtr->next = NULL; } /* @@ -447,47 +452,51 @@ MoreCore(bucket) */ void -TclpFree(cp) - char *cp; /* Pointer to memory to free. */ -{ +TclpFree( + char *oldPtr) /* Pointer to memory to free. */ +{ register long size; - register union overhead *op; + register union overhead *overPtr; struct block *bigBlockPtr; - if (cp == NULL) { + if (oldPtr == NULL) { return; } Tcl_MutexLock(allocMutexPtr); - op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); + overPtr = (union overhead *)((caddr_t)oldPtr - sizeof (union overhead)); - ASSERT(op->ov_magic0 == MAGIC); /* make sure it was in use */ - ASSERT(op->ov_magic1 == MAGIC); - if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) { + ASSERT(overPtr->overMagic0 == MAGIC); /* make sure it was in use */ + ASSERT(overPtr->overMagic1 == MAGIC); + if (overPtr->overMagic0 != MAGIC || overPtr->overMagic1 != MAGIC) { Tcl_MutexUnlock(allocMutexPtr); return; } - RANGE_ASSERT(op->ov_rmagic == RMAGIC); - RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); - size = op->ov_index; - if ( size == 0xff ) { + RANGE_ASSERT(overPtr->rangeCheckMagic == RMAGIC); + RANGE_ASSERT(BLOCK_END(overPtr) == RMAGIC); + size = overPtr->bucketIndex; + if (size == 0xff) { #ifdef MSTATS - nmalloc[NBUCKETS]--; + numMallocs[NBUCKETS]--; #endif - bigBlockPtr = (struct block *) op - 1; + + bigBlockPtr = (struct block *) overPtr - 1; bigBlockPtr->prevPtr->nextPtr = bigBlockPtr->nextPtr; bigBlockPtr->nextPtr->prevPtr = bigBlockPtr->prevPtr; TclpSysFree(bigBlockPtr); + Tcl_MutexUnlock(allocMutexPtr); return; } ASSERT(size < NBUCKETS); - op->ov_next = nextf[size]; /* also clobbers ov_magic */ - nextf[size] = op; + overPtr->next = nextf[size]; /* also clobbers overMagic */ + nextf[size] = overPtr; + #ifdef MSTATS - nmalloc[size]--; + numMallocs[size]--; #endif + Tcl_MutexUnlock(allocMutexPtr); } @@ -508,34 +517,34 @@ TclpFree(cp) */ char * -TclpRealloc(cp, nbytes) - char *cp; /* Pointer to alloced block. */ - unsigned int nbytes; /* New size of memory. */ -{ +TclpRealloc( + char *oldPtr, /* Pointer to alloced block. */ + unsigned int numBytes) /* New size of memory. */ +{ int i; - union overhead *op; + union overhead *overPtr; struct block *bigBlockPtr; int expensive; - unsigned long maxsize; + unsigned long maxSize; - if (cp == NULL) { - return (TclpAlloc(nbytes)); + if (oldPtr == NULL) { + return TclpAlloc(numBytes); } Tcl_MutexLock(allocMutexPtr); - op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); + overPtr = (union overhead *)((caddr_t)oldPtr - sizeof (union overhead)); - ASSERT(op->ov_magic0 == MAGIC); /* make sure it was in use */ - ASSERT(op->ov_magic1 == MAGIC); - if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) { + ASSERT(overPtr->overMagic0 == MAGIC); /* make sure it was in use */ + ASSERT(overPtr->overMagic1 == MAGIC); + if (overPtr->overMagic0 != MAGIC || overPtr->overMagic1 != MAGIC) { Tcl_MutexUnlock(allocMutexPtr); return NULL; } - RANGE_ASSERT(op->ov_rmagic == RMAGIC); - RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); - i = op->ov_index; + RANGE_ASSERT(overPtr->rangeCheckMagic == RMAGIC); + RANGE_ASSERT(BLOCK_END(overPtr) == RMAGIC); + i = overPtr->bucketIndex; /* * If the block isn't in a bin, just realloc it. @@ -543,11 +552,11 @@ TclpRealloc(cp, nbytes) if (i == 0xff) { struct block *prevPtr, *nextPtr; - bigBlockPtr = (struct block *) op - 1; + bigBlockPtr = (struct block *) overPtr - 1; prevPtr = bigBlockPtr->prevPtr; nextPtr = bigBlockPtr->nextPtr; - bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr, - sizeof(struct block) + OVERHEAD + nbytes); + bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr, + sizeof(struct block) + OVERHEAD + numBytes); if (bigBlockPtr == NULL) { Tcl_MutexUnlock(allocMutexPtr); return NULL; @@ -555,63 +564,69 @@ TclpRealloc(cp, nbytes) if (prevPtr->nextPtr != bigBlockPtr) { /* - * If the block has moved, splice the new block into the list where - * the old block used to be. + * If the block has moved, splice the new block into the list + * where the old block used to be. */ prevPtr->nextPtr = bigBlockPtr; nextPtr->prevPtr = bigBlockPtr; } - op = (union overhead *) (bigBlockPtr + 1); + overPtr = (union overhead *) (bigBlockPtr + 1); + #ifdef MSTATS - nmalloc[NBUCKETS]++; + numMallocs[NBUCKETS]++; #endif + #ifdef RCHECK /* * Record allocated size of block and update magic number bounds. */ - op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); - *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; + overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1); + BLOCK_END(overPtr) = RMAGIC; #endif + Tcl_MutexUnlock(allocMutexPtr); - return (char *)(op+1); + return (char *)(overPtr+1); } - maxsize = 1 << (i+3); + maxSize = 1 << (i+3); expensive = 0; - if ( nbytes + OVERHEAD > maxsize ) { + if (numBytes+OVERHEAD > maxSize) { expensive = 1; - } else if ( i > 0 && nbytes + OVERHEAD < (maxsize/2) ) { + } else if (i>0 && numBytes+OVERHEAD < maxSize/2) { expensive = 1; } if (expensive) { - void *newp; + void *newPtr; Tcl_MutexUnlock(allocMutexPtr); - newp = TclpAlloc(nbytes); - if ( newp == NULL ) { + newPtr = TclpAlloc(numBytes); + if (newPtr == NULL) { return NULL; } - maxsize -= OVERHEAD; - if ( maxsize < nbytes ) - nbytes = maxsize; - memcpy((VOID *) newp, (VOID *) cp, (size_t) nbytes); - TclpFree(cp); - return newp; + maxSize -= OVERHEAD; + if (maxSize < numBytes) { + numBytes = maxSize; + } + memcpy(newPtr, oldPtr, (size_t) numBytes); + TclpFree(oldPtr); + return newPtr; } - + /* * Ok, we don't have to copy, it fits as-is */ + #ifdef RCHECK - op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); - *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; + overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1); + BLOCK_END(overPtr) = RMAGIC; #endif + Tcl_MutexUnlock(allocMutexPtr); - return(cp); + return(oldPtr); } /* @@ -619,9 +634,9 @@ TclpRealloc(cp, nbytes) * * mstats -- * - * Prints two lines of numbers, one showing the length of the - * free list for each size category, the second showing the - * number of mallocs - frees for each size category. + * Prints two lines of numbers, one showing the length of the free list + * for each size category, the second showing the number of mallocs - + * frees for each size category. * * Results: * None. @@ -634,35 +649,39 @@ TclpRealloc(cp, nbytes) #ifdef MSTATS void -mstats(s) - char *s; /* Where to write info. */ +mstats( + char *s) /* Where to write info. */ { register int i, j; - register union overhead *p; - int totfree = 0, - totused = 0; + register union overhead *overPtr; + int totalFree = 0, totalUsed = 0; Tcl_MutexLock(allocMutexPtr); + fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s); for (i = 0; i < NBUCKETS; i++) { - for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) + for (j=0, overPtr=nextf[i]; overPtr; overPtr=overPtr->next, j++) { fprintf(stderr, " %d", j); - totfree += j * (1 << (i + 3)); + } + totalFree += j * (1 << (i + 3)); } + fprintf(stderr, "\nused:\t"); for (i = 0; i < NBUCKETS; i++) { - fprintf(stderr, " %d", nmalloc[i]); - totused += nmalloc[i] * (1 << (i + 3)); + fprintf(stderr, " %d", numMallocs[i]); + totalUsed += numMallocs[i] * (1 << (i + 3)); } + fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n", - totused, totfree); - fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n", - MAXMALLOC, nmalloc[NBUCKETS]); + totalUsed, totalFree); + fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n", + MAXMALLOC, numMallocs[NBUCKETS]); + Tcl_MutexUnlock(allocMutexPtr); } #endif -#else /* !USE_TCLALLOC */ +#else /* !USE_TCLALLOC */ /* *---------------------------------------------------------------------- @@ -681,10 +700,10 @@ mstats(s) */ char * -TclpAlloc(nbytes) - unsigned int nbytes; /* Number of bytes to allocate. */ +TclpAlloc( + unsigned int numBytes) /* Number of bytes to allocate. */ { - return (char*) malloc(nbytes); + return (char*) malloc(numBytes); } /* @@ -704,10 +723,10 @@ TclpAlloc(nbytes) */ void -TclpFree(cp) - char *cp; /* Pointer to memory to free. */ -{ - free(cp); +TclpFree( + char *oldPtr) /* Pointer to memory to free. */ +{ + free(oldPtr); return; } @@ -728,12 +747,20 @@ TclpFree(cp) */ char * -TclpRealloc(cp, nbytes) - char *cp; /* Pointer to alloced block. */ - unsigned int nbytes; /* New size of memory. */ -{ - return (char*) realloc(cp, nbytes); +TclpRealloc( + char *oldPtr, /* Pointer to alloced block. */ + unsigned int numBytes) /* New size of memory. */ +{ + return (char*) realloc(oldPtr, numBytes); } #endif /* !USE_TCLALLOC */ #endif /* !TCL_THREADS */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |