summaryrefslogtreecommitdiffstats
path: root/generic/tclThreadAlloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclThreadAlloc.c')
-rw-r--r--generic/tclThreadAlloc.c403
1 files changed, 145 insertions, 258 deletions
diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c
index df4d2e3..106e908 100644
--- a/generic/tclThreadAlloc.c
+++ b/generic/tclThreadAlloc.c
@@ -6,14 +6,14 @@
* fixed size blocks from block caches.
*
* The Initial Developer of the Original Code is America Online, Inc.
- * Portions created by AOL are Copyright © 1999 America Online, Inc.
+ * Portions created by AOL are Copyright (C) 1999 America Online, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclInt.h"
-#if TCL_THREADS && defined(USE_THREAD_ALLOC)
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
/*
* If range checking is enabled, an additional byte will be allocated to store
@@ -35,9 +35,7 @@
*/
#define NOBJALLOC 800
-
-/* Actual definition moved to tclInt.h */
-#define NOBJHIGH ALLOC_NOBJHIGH
+#define NOBJHIGH 1200
/*
* The following union stores accounting information for each block including
@@ -82,33 +80,30 @@ typedef union Block {
* and statistics information.
*/
-typedef struct {
+typedef struct Bucket {
Block *firstPtr; /* First block available */
- Block *lastPtr; /* End of block list */
- size_t numFree; /* Number of blocks available */
+ long numFree; /* Number of blocks available */
/* All fields below for accounting only */
- size_t numRemoves; /* Number of removes from bucket */
- size_t numInserts; /* Number of inserts into bucket */
- size_t numLocks; /* Number of locks acquired */
- size_t totalAssigned; /* Total space assigned to bucket */
+ long numRemoves; /* Number of removes from bucket */
+ long numInserts; /* Number of inserts into bucket */
+ long numWaits; /* Number of waits to acquire a lock */
+ long numLocks; /* Number of locks acquired */
+ long totalAssigned; /* Total space assigned to bucket */
} Bucket;
/*
* The following structure defines a cache of buckets and objs, of which there
- * will be (at most) one per thread. Any changes need to be reflected in the
- * struct AllocCache defined in tclInt.h, possibly also in the initialisation
- * code in Tcl_CreateInterp().
+ * will be (at most) one per thread.
*/
typedef struct Cache {
struct Cache *nextPtr; /* Linked list of cache entries */
Tcl_ThreadId owner; /* Which thread's cache is this? */
Tcl_Obj *firstObjPtr; /* List of free objects for thread */
- size_t numObjects; /* Number of objects for thread */
- Tcl_Obj *lastPtr; /* Last object in this cache */
- size_t totalAssigned; /* Total space assigned to thread */
+ int numObjects; /* Number of objects for thread */
+ int totalAssigned; /* Total space assigned to thread */
Bucket buckets[NBUCKETS]; /* The buckets for this thread */
} Cache;
@@ -119,8 +114,8 @@ typedef struct Cache {
static struct {
size_t blockSize; /* Bucket blocksize. */
- size_t maxBlocks; /* Max blocks before move to share. */
- size_t numMove; /* Num blocks to move to share. */
+ int maxBlocks; /* Max blocks before move to share. */
+ int numMove; /* Num blocks to move to share. */
Tcl_Mutex *lockPtr; /* Share bucket lock. */
} bucketInfo[NBUCKETS];
@@ -131,12 +126,11 @@ static struct {
static Cache * GetCache(void);
static void LockBucket(Cache *cachePtr, int bucket);
static void UnlockBucket(Cache *cachePtr, int bucket);
-static void PutBlocks(Cache *cachePtr, int bucket, size_t numMove);
+static void PutBlocks(Cache *cachePtr, int bucket, int numMove);
static int GetBlocks(Cache *cachePtr, int bucket);
-static Block * Ptr2Block(void *ptr);
-static void * Block2Ptr(Block *blockPtr, int bucket, size_t reqSize);
-static void MoveObjs(Cache *fromPtr, Cache *toPtr, size_t numMove);
-static void PutObjs(Cache *fromPtr, size_t numMove);
+static Block * Ptr2Block(char *ptr);
+static char * Block2Ptr(Block *blockPtr, int bucket, unsigned int reqSize);
+static void MoveObjs(Cache *fromPtr, Cache *toPtr, int numMove);
/*
* Local variables defined in this file and initialized at startup.
@@ -147,26 +141,6 @@ static Tcl_Mutex *objLockPtr;
static Cache sharedCache;
static Cache *sharedPtr = &sharedCache;
static Cache *firstCachePtr = &sharedCache;
-
-#if defined(HAVE_FAST_TSD)
-static __thread Cache *tcachePtr;
-
-# define GETCACHE(cachePtr) \
- do { \
- if (!tcachePtr) { \
- tcachePtr = GetCache(); \
- } \
- (cachePtr) = tcachePtr; \
- } while (0)
-#else
-# define GETCACHE(cachePtr) \
- do { \
- (cachePtr) = (Cache*)TclpGetAllocCache(); \
- if ((cachePtr) == NULL) { \
- (cachePtr) = GetCache(); \
- } \
- } while (0)
-#endif
/*
*----------------------------------------------------------------------
@@ -195,11 +169,20 @@ GetCache(void)
if (listLockPtr == NULL) {
Tcl_Mutex *initLockPtr;
+ unsigned int i;
initLockPtr = Tcl_GetAllocMutex();
Tcl_MutexLock(initLockPtr);
if (listLockPtr == NULL) {
- TclInitThreadAlloc();
+ listLockPtr = TclpNewAllocMutex();
+ objLockPtr = TclpNewAllocMutex();
+ for (i = 0; i < NBUCKETS; ++i) {
+ bucketInfo[i].blockSize = MINALLOC << i;
+ bucketInfo[i].maxBlocks = 1 << (NBUCKETS - 1 - i);
+ bucketInfo[i].numMove = i < NBUCKETS - 1 ?
+ 1 << (NBUCKETS - 2 - i) : 1;
+ bucketInfo[i].lockPtr = TclpNewAllocMutex();
+ }
}
Tcl_MutexUnlock(initLockPtr);
}
@@ -208,13 +191,12 @@ GetCache(void)
* Get this thread's cache, allocating if necessary.
*/
- cachePtr = (Cache*)TclpGetAllocCache();
+ cachePtr = TclpGetAllocCache();
if (cachePtr == NULL) {
- cachePtr = (Cache*)TclpSysAlloc(sizeof(Cache), 0);
+ cachePtr = calloc(1, sizeof(Cache));
if (cachePtr == NULL) {
Tcl_Panic("alloc: could not allocate new cache");
}
- memset(cachePtr, 0, sizeof(Cache));
Tcl_MutexLock(listLockPtr);
cachePtr->nextPtr = firstCachePtr;
firstCachePtr = cachePtr;
@@ -245,9 +227,9 @@ void
TclFreeAllocCache(
void *arg)
{
- Cache *cachePtr = (Cache*)arg;
+ Cache *cachePtr = arg;
Cache **nextPtrPtr;
- unsigned int bucket;
+ register unsigned int bucket;
/*
* Flush blocks.
@@ -264,7 +246,9 @@ TclFreeAllocCache(
*/
if (cachePtr->numObjects > 0) {
- PutObjs(cachePtr, cachePtr->numObjects);
+ Tcl_MutexLock(objLockPtr);
+ MoveObjs(cachePtr, sharedPtr, cachePtr->numObjects);
+ Tcl_MutexUnlock(objLockPtr);
}
/*
@@ -279,7 +263,7 @@ TclFreeAllocCache(
*nextPtrPtr = cachePtr->nextPtr;
cachePtr->nextPtr = NULL;
Tcl_MutexUnlock(listLockPtr);
- TclpSysFree(cachePtr);
+ free(cachePtr);
}
/*
@@ -298,13 +282,13 @@ TclFreeAllocCache(
*----------------------------------------------------------------------
*/
-void *
+char *
TclpAlloc(
unsigned int reqSize)
{
Cache *cachePtr;
Block *blockPtr;
- int bucket;
+ register int bucket;
size_t size;
#ifndef __LP64__
@@ -320,11 +304,14 @@ TclpAlloc(
}
#endif
- GETCACHE(cachePtr);
+ cachePtr = TclpGetAllocCache();
+ if (cachePtr == NULL) {
+ cachePtr = GetCache();
+ }
/*
* Increment the requested size to include room for the Block structure.
- * Call TclpSysAlloc() directly if the required amount is greater than the
+ * Call malloc() directly if the required amount is greater than the
* largest block, otherwise pop the smallest block large enough,
* allocating more blocks if necessary.
*/
@@ -332,24 +319,24 @@ TclpAlloc(
blockPtr = NULL;
size = reqSize + sizeof(Block);
#if RCHECK
- size++;
+ ++size;
#endif
if (size > MAXALLOC) {
bucket = NBUCKETS;
- blockPtr = (Block *)TclpSysAlloc(size, 0);
+ blockPtr = malloc(size);
if (blockPtr != NULL) {
cachePtr->totalAssigned += reqSize;
}
} else {
bucket = 0;
while (bucketInfo[bucket].blockSize < size) {
- bucket++;
+ ++bucket;
}
if (cachePtr->buckets[bucket].numFree || GetBlocks(cachePtr, bucket)) {
blockPtr = cachePtr->buckets[bucket].firstPtr;
cachePtr->buckets[bucket].firstPtr = blockPtr->nextBlock;
- cachePtr->buckets[bucket].numFree--;
- cachePtr->buckets[bucket].numRemoves++;
+ --cachePtr->buckets[bucket].numFree;
+ ++cachePtr->buckets[bucket].numRemoves;
cachePtr->buckets[bucket].totalAssigned += reqSize;
}
}
@@ -377,7 +364,7 @@ TclpAlloc(
void
TclpFree(
- void *ptr)
+ char *ptr)
{
Cache *cachePtr;
Block *blockPtr;
@@ -387,7 +374,10 @@ TclpFree(
return;
}
- GETCACHE(cachePtr);
+ cachePtr = TclpGetAllocCache();
+ if (cachePtr == NULL) {
+ cachePtr = GetCache();
+ }
/*
* Get the block back from the user pointer and call system free directly
@@ -399,18 +389,15 @@ TclpFree(
bucket = blockPtr->sourceBucket;
if (bucket == NBUCKETS) {
cachePtr->totalAssigned -= blockPtr->blockReqSize;
- TclpSysFree(blockPtr);
+ free(blockPtr);
return;
}
cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize;
blockPtr->nextBlock = cachePtr->buckets[bucket].firstPtr;
cachePtr->buckets[bucket].firstPtr = blockPtr;
- if (cachePtr->buckets[bucket].numFree == 0) {
- cachePtr->buckets[bucket].lastPtr = blockPtr;
- }
- cachePtr->buckets[bucket].numFree++;
- cachePtr->buckets[bucket].numInserts++;
+ ++cachePtr->buckets[bucket].numFree;
+ ++cachePtr->buckets[bucket].numInserts;
if (cachePtr != sharedPtr &&
cachePtr->buckets[bucket].numFree > bucketInfo[bucket].maxBlocks) {
@@ -434,9 +421,9 @@ TclpFree(
*----------------------------------------------------------------------
*/
-void *
+char *
TclpRealloc(
- void *ptr,
+ char *ptr,
unsigned int reqSize)
{
Cache *cachePtr;
@@ -462,18 +449,21 @@ TclpRealloc(
}
#endif
- GETCACHE(cachePtr);
+ cachePtr = TclpGetAllocCache();
+ if (cachePtr == NULL) {
+ cachePtr = GetCache();
+ }
/*
* If the block is not a system block and fits in place, simply return the
* existing pointer. Otherwise, if the block is a system block and the new
- * size would also require a system block, call TclpSysRealloc() directly.
+ * size would also require a system block, call realloc() directly.
*/
blockPtr = Ptr2Block(ptr);
size = reqSize + sizeof(Block);
#if RCHECK
- size++;
+ ++size;
#endif
bucket = blockPtr->sourceBucket;
if (bucket != NBUCKETS) {
@@ -490,7 +480,7 @@ TclpRealloc(
} else if (size > MAXALLOC) {
cachePtr->totalAssigned -= blockPtr->blockReqSize;
cachePtr->totalAssigned += reqSize;
- blockPtr = (Block*)TclpSysRealloc(blockPtr, size);
+ blockPtr = realloc(blockPtr, size);
if (blockPtr == NULL) {
return NULL;
}
@@ -526,20 +516,18 @@ TclpRealloc(
* May move Tcl_Obj's from shared cached or allocate new Tcl_Obj's if
* list is empty.
*
- * Note:
- * If this code is updated, the changes need to be reflected in the macro
- * TclAllocObjStorageEx() defined in tclInt.h
- *
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclThreadAllocObj(void)
{
- Cache *cachePtr;
- Tcl_Obj *objPtr;
+ register Cache *cachePtr = TclpGetAllocCache();
+ register Tcl_Obj *objPtr;
- GETCACHE(cachePtr);
+ if (cachePtr == NULL) {
+ cachePtr = GetCache();
+ }
/*
* Get this thread's obj list structure and move or allocate new objs if
@@ -547,7 +535,7 @@ TclThreadAllocObj(void)
*/
if (cachePtr->numObjects == 0) {
- size_t numMove;
+ register int numMove;
Tcl_MutexLock(objLockPtr);
numMove = sharedPtr->numObjects;
@@ -562,17 +550,15 @@ TclThreadAllocObj(void)
Tcl_Obj *newObjsPtr;
cachePtr->numObjects = numMove = NOBJALLOC;
- newObjsPtr = (Tcl_Obj *)TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0);
+ newObjsPtr = malloc(sizeof(Tcl_Obj) * numMove);
if (newObjsPtr == NULL) {
- Tcl_Panic("alloc: could not allocate %" TCL_Z_MODIFIER "u new objects", numMove);
+ Tcl_Panic("alloc: could not allocate %d new objects", numMove);
}
- cachePtr->lastPtr = newObjsPtr + numMove - 1;
- objPtr = cachePtr->firstObjPtr; /* NULL */
- while (numMove-- > 0) {
- newObjsPtr[numMove].internalRep.twoPtrValue.ptr1 = objPtr;
- objPtr = newObjsPtr + numMove;
+ while (--numMove >= 0) {
+ objPtr = &newObjsPtr[numMove];
+ objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr;
+ cachePtr->firstObjPtr = objPtr;
}
- cachePtr->firstObjPtr = newObjsPtr;
}
}
@@ -581,8 +567,8 @@ TclThreadAllocObj(void)
*/
objPtr = cachePtr->firstObjPtr;
- cachePtr->firstObjPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1;
- cachePtr->numObjects--;
+ cachePtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
+ --cachePtr->numObjects;
return objPtr;
}
@@ -599,10 +585,6 @@ TclThreadAllocObj(void)
* Side effects:
* May move free Tcl_Obj's to shared list upon hitting high water mark.
*
- * Note:
- * If this code is updated, the changes need to be reflected in the macro
- * TclAllocObjStorageEx() defined in tclInt.h
- *
*----------------------------------------------------------------------
*/
@@ -610,9 +592,11 @@ void
TclThreadFreeObj(
Tcl_Obj *objPtr)
{
- Cache *cachePtr;
+ Cache *cachePtr = TclpGetAllocCache();
- GETCACHE(cachePtr);
+ if (cachePtr == NULL) {
+ cachePtr = GetCache();
+ }
/*
* Get this thread's list and push on the free Tcl_Obj.
@@ -620,10 +604,7 @@ TclThreadFreeObj(
objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr;
cachePtr->firstObjPtr = objPtr;
- if (cachePtr->numObjects == 0) {
- cachePtr->lastPtr = objPtr;
- }
- cachePtr->numObjects++;
+ ++cachePtr->numObjects;
/*
* If the number of free objects has exceeded the high water mark, move
@@ -631,7 +612,9 @@ TclThreadFreeObj(
*/
if (cachePtr->numObjects > NOBJHIGH) {
- PutObjs(cachePtr, NOBJALLOC);
+ Tcl_MutexLock(objLockPtr);
+ MoveObjs(cachePtr, sharedPtr, NOBJALLOC);
+ Tcl_MutexUnlock(objLockPtr);
}
}
@@ -666,18 +649,18 @@ Tcl_GetMemoryInfo(
if (cachePtr == sharedPtr) {
Tcl_DStringAppendElement(dsPtr, "shared");
} else {
- snprintf(buf, sizeof(buf), "thread%p", cachePtr->owner);
+ sprintf(buf, "thread%p", cachePtr->owner);
Tcl_DStringAppendElement(dsPtr, buf);
}
for (n = 0; n < NBUCKETS; ++n) {
- snprintf(buf, sizeof(buf), "%" TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u %"
- TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u",
- bucketInfo[n].blockSize,
+ sprintf(buf, "%lu %ld %ld %ld %ld %ld %ld",
+ (unsigned long) bucketInfo[n].blockSize,
cachePtr->buckets[n].numFree,
cachePtr->buckets[n].numRemoves,
cachePtr->buckets[n].numInserts,
cachePtr->buckets[n].totalAssigned,
- cachePtr->buckets[n].numLocks);
+ cachePtr->buckets[n].numLocks,
+ cachePtr->buckets[n].numWaits);
Tcl_DStringAppendElement(dsPtr, buf);
}
Tcl_DStringEndSublist(dsPtr);
@@ -706,9 +689,9 @@ static void
MoveObjs(
Cache *fromPtr,
Cache *toPtr,
- size_t numMove)
+ int numMove)
{
- Tcl_Obj *objPtr = fromPtr->firstObjPtr;
+ register Tcl_Obj *objPtr = fromPtr->firstObjPtr;
Tcl_Obj *fromFirstObjPtr = objPtr;
toPtr->numObjects += numMove;
@@ -719,77 +702,23 @@ MoveObjs(
* to be moved) as the first object in the 'from' cache.
*/
- while (numMove-- > 1) {
- objPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1;
+ while (--numMove) {
+ objPtr = objPtr->internalRep.twoPtrValue.ptr1;
}
- fromPtr->firstObjPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1;
+ fromPtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
/*
* Move all objects as a block - they are already linked to each other, we
* just have to update the first and last.
*/
- toPtr->lastPtr = objPtr;
- objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr; /* NULL */
+ objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr;
toPtr->firstObjPtr = fromFirstObjPtr;
}
/*
*----------------------------------------------------------------------
*
- * PutObjs --
- *
- * Move Tcl_Obj's from thread cache to shared cache.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-PutObjs(
- Cache *fromPtr,
- size_t numMove)
-{
- size_t keep = fromPtr->numObjects - numMove;
- Tcl_Obj *firstPtr, *lastPtr = NULL;
-
- fromPtr->numObjects = keep;
- firstPtr = fromPtr->firstObjPtr;
- if (keep == 0) {
- fromPtr->firstObjPtr = NULL;
- } else {
- do {
- lastPtr = firstPtr;
- firstPtr = (Tcl_Obj *)firstPtr->internalRep.twoPtrValue.ptr1;
- } while (keep-- > 1);
- lastPtr->internalRep.twoPtrValue.ptr1 = NULL;
- }
-
- /*
- * Move all objects as a block - they are already linked to each other, we
- * just have to update the first and last.
- */
-
- Tcl_MutexLock(objLockPtr);
- fromPtr->lastPtr->internalRep.twoPtrValue.ptr1 = sharedPtr->firstObjPtr;
- sharedPtr->firstObjPtr = firstPtr;
- if (sharedPtr->numObjects == 0) {
- sharedPtr->lastPtr = fromPtr->lastPtr;
- }
- sharedPtr->numObjects += numMove;
- Tcl_MutexUnlock(objLockPtr);
-
- fromPtr->lastPtr = lastPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Block2Ptr, Ptr2Block --
*
* Convert between internal blocks and user pointers.
@@ -803,13 +732,13 @@ PutObjs(
*----------------------------------------------------------------------
*/
-static void *
+static char *
Block2Ptr(
Block *blockPtr,
int bucket,
- size_t reqSize)
+ unsigned int reqSize)
{
- void *ptr;
+ register void *ptr;
blockPtr->magicNum1 = blockPtr->magicNum2 = MAGIC;
blockPtr->sourceBucket = bucket;
@@ -818,14 +747,14 @@ Block2Ptr(
#if RCHECK
((unsigned char *)(ptr))[reqSize] = MAGIC;
#endif
- return ptr;
+ return (char *) ptr;
}
static Block *
Ptr2Block(
- void *ptr)
+ char *ptr)
{
- Block *blockPtr;
+ register Block *blockPtr;
blockPtr = (((Block *) ptr) - 1);
if (blockPtr->magicNum1 != MAGIC || blockPtr->magicNum2 != MAGIC) {
@@ -864,14 +793,22 @@ LockBucket(
Cache *cachePtr,
int bucket)
{
+#if 0
+ if (Tcl_MutexTryLock(bucketInfo[bucket].lockPtr) != TCL_OK) {
+ Tcl_MutexLock(bucketInfo[bucket].lockPtr);
+ ++cachePtr->buckets[bucket].numWaits;
+ ++sharedPtr->buckets[bucket].numWaits;
+ }
+#else
Tcl_MutexLock(bucketInfo[bucket].lockPtr);
- cachePtr->buckets[bucket].numLocks++;
- sharedPtr->buckets[bucket].numLocks++;
+#endif
+ ++cachePtr->buckets[bucket].numLocks;
+ ++sharedPtr->buckets[bucket].numLocks;
}
static void
UnlockBucket(
- TCL_UNUSED(Cache *),
+ Cache *cachePtr,
int bucket)
{
Tcl_MutexUnlock(bucketInfo[bucket].lockPtr);
@@ -897,27 +834,22 @@ static void
PutBlocks(
Cache *cachePtr,
int bucket,
- size_t numMove)
+ int numMove)
{
+ register Block *lastPtr, *firstPtr;
+ register int n = numMove;
+
/*
- * We have numFree. Want to shed numMove. So compute how many
- * Blocks to keep.
+ * Before acquiring the lock, walk the block list to find the last block
+ * to be moved.
*/
- size_t keep = cachePtr->buckets[bucket].numFree - numMove;
- Block *lastPtr = NULL, *firstPtr;
-
- cachePtr->buckets[bucket].numFree = keep;
- firstPtr = cachePtr->buckets[bucket].firstPtr;
- if (keep == 0) {
- cachePtr->buckets[bucket].firstPtr = NULL;
- } else {
- do {
- lastPtr = firstPtr;
- firstPtr = firstPtr->nextBlock;
- } while (keep-- > 1);
- lastPtr->nextBlock = NULL;
+ firstPtr = lastPtr = cachePtr->buckets[bucket].firstPtr;
+ while (--n > 0) {
+ lastPtr = lastPtr->nextBlock;
}
+ cachePtr->buckets[bucket].firstPtr = lastPtr->nextBlock;
+ cachePtr->buckets[bucket].numFree -= numMove;
/*
* Aquire the lock and place the list of blocks at the front of the shared
@@ -925,17 +857,10 @@ PutBlocks(
*/
LockBucket(cachePtr, bucket);
- cachePtr->buckets[bucket].lastPtr->nextBlock
- = sharedPtr->buckets[bucket].firstPtr;
+ lastPtr->nextBlock = sharedPtr->buckets[bucket].firstPtr;
sharedPtr->buckets[bucket].firstPtr = firstPtr;
- if (sharedPtr->buckets[bucket].numFree == 0) {
- sharedPtr->buckets[bucket].lastPtr
- = cachePtr->buckets[bucket].lastPtr;
- }
sharedPtr->buckets[bucket].numFree += numMove;
UnlockBucket(cachePtr, bucket);
-
- cachePtr->buckets[bucket].lastPtr = lastPtr;
}
/*
@@ -959,11 +884,11 @@ GetBlocks(
Cache *cachePtr,
int bucket)
{
- Block *blockPtr;
- size_t n;
+ register Block *blockPtr;
+ register int n;
/*
- * First, attempt to move blocks from the shared cache. Note the
+ * First, atttempt to move blocks from the shared cache. Note the
* potentially dirty read of numFree before acquiring the lock which is a
* slight performance enhancement. The value is verified after the lock is
* actually acquired.
@@ -982,8 +907,6 @@ GetBlocks(
if (n >= sharedPtr->buckets[bucket].numFree) {
cachePtr->buckets[bucket].firstPtr =
sharedPtr->buckets[bucket].firstPtr;
- cachePtr->buckets[bucket].lastPtr =
- sharedPtr->buckets[bucket].lastPtr;
cachePtr->buckets[bucket].numFree =
sharedPtr->buckets[bucket].numFree;
sharedPtr->buckets[bucket].firstPtr = NULL;
@@ -993,11 +916,10 @@ GetBlocks(
cachePtr->buckets[bucket].firstPtr = blockPtr;
sharedPtr->buckets[bucket].numFree -= n;
cachePtr->buckets[bucket].numFree = n;
- while (n-- > 1) {
+ while (--n > 0) {
blockPtr = blockPtr->nextBlock;
}
sharedPtr->buckets[bucket].firstPtr = blockPtr->nextBlock;
- cachePtr->buckets[bucket].lastPtr = blockPtr;
blockPtr->nextBlock = NULL;
}
}
@@ -1005,7 +927,7 @@ GetBlocks(
}
if (cachePtr->buckets[bucket].numFree == 0) {
- size_t size;
+ register size_t size;
/*
* If no blocks could be moved from shared, first look for a larger
@@ -1014,13 +936,13 @@ GetBlocks(
blockPtr = NULL;
n = NBUCKETS;
- size = 0;
- while (n-- > (size_t)bucket + 1) {
+ size = 0; /* lint */
+ while (--n > bucket) {
if (cachePtr->buckets[n].numFree > 0) {
size = bucketInfo[n].blockSize;
blockPtr = cachePtr->buckets[n].firstPtr;
cachePtr->buckets[n].firstPtr = blockPtr->nextBlock;
- cachePtr->buckets[n].numFree--;
+ --cachePtr->buckets[n].numFree;
break;
}
}
@@ -1031,7 +953,7 @@ GetBlocks(
if (blockPtr == NULL) {
size = MAXALLOC;
- blockPtr = (Block*)TclpSysAlloc(size, 0);
+ blockPtr = malloc(size);
if (blockPtr == NULL) {
return 0;
}
@@ -1044,50 +966,15 @@ GetBlocks(
n = size / bucketInfo[bucket].blockSize;
cachePtr->buckets[bucket].numFree = n;
cachePtr->buckets[bucket].firstPtr = blockPtr;
- while (n-- > 1) {
+ while (--n > 0) {
blockPtr->nextBlock = (Block *)
((char *) blockPtr + bucketInfo[bucket].blockSize);
blockPtr = blockPtr->nextBlock;
}
- cachePtr->buckets[bucket].lastPtr = blockPtr;
blockPtr->nextBlock = NULL;
}
return 1;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclInitThreadAlloc --
- *
- * Initializes the allocator cache-maintenance structures.
- * It is done early and protected during the Tcl_InitSubsystems().
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TclInitThreadAlloc(void)
-{
- unsigned int i;
-
- listLockPtr = TclpNewAllocMutex();
- objLockPtr = TclpNewAllocMutex();
- for (i = 0; i < NBUCKETS; ++i) {
- bucketInfo[i].blockSize = MINALLOC << i;
- bucketInfo[i].maxBlocks = ((size_t)1) << (NBUCKETS - 1 - i);
- bucketInfo[i].numMove = i < NBUCKETS - 1 ?
- (size_t)1 << (NBUCKETS - 2 - i) : 1;
- bucketInfo[i].lockPtr = TclpNewAllocMutex();
- }
- TclpInitAllocCache();
-}
/*
*----------------------------------------------------------------------
@@ -1112,8 +999,8 @@ TclFinalizeThreadAlloc(void)
unsigned int i;
for (i = 0; i < NBUCKETS; ++i) {
- TclpFreeAllocMutex(bucketInfo[i].lockPtr);
- bucketInfo[i].lockPtr = NULL;
+ TclpFreeAllocMutex(bucketInfo[i].lockPtr);
+ bucketInfo[i].lockPtr = NULL;
}
TclpFreeAllocMutex(objLockPtr);
@@ -1130,9 +1017,9 @@ TclFinalizeThreadAlloc(void)
*
* TclFinalizeThreadAllocThread --
*
- * This procedure is used to destroy single thread private resources
- * defined in this file. Called either during Tcl_FinalizeThread() or
- * Tcl_Finalize().
+ * This procedure is used to destroy single thread private resources used
+ * in this file.
+ * Called in TclpFinalizeThreadData when a thread exits (Tcl_FinalizeThread).
*
* Results:
* None.
@@ -1146,7 +1033,7 @@ TclFinalizeThreadAlloc(void)
void
TclFinalizeThreadAllocThread(void)
{
- Cache *cachePtr = (Cache *)TclpGetAllocCache();
+ Cache *cachePtr = TclpGetAllocCache();
if (cachePtr != NULL) {
TclpFreeAllocCache(cachePtr);
}
@@ -1171,7 +1058,7 @@ TclFinalizeThreadAllocThread(void)
void
Tcl_GetMemoryInfo(
- TCL_UNUSED(Tcl_DString *))
+ Tcl_DString *dsPtr)
{
Tcl_Panic("Tcl_GetMemoryInfo called when threaded memory allocator not in use");
}