diff options
Diffstat (limited to 'generic/tclThreadAlloc.c')
| -rw-r--r-- | generic/tclThreadAlloc.c | 134 |
1 files changed, 71 insertions, 63 deletions
diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index ad1d510..106e908 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -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 @@ -97,9 +95,7 @@ typedef struct 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 { @@ -145,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) = TclpGetAllocCache(); \ - if ((cachePtr) == NULL) { \ - (cachePtr) = GetCache(); \ - } \ - } while (0) -#endif /* *---------------------------------------------------------------------- @@ -328,7 +304,10 @@ TclpAlloc( } #endif - GETCACHE(cachePtr); + cachePtr = TclpGetAllocCache(); + if (cachePtr == NULL) { + cachePtr = GetCache(); + } /* * Increment the requested size to include room for the Block structure. @@ -340,7 +319,7 @@ TclpAlloc( blockPtr = NULL; size = reqSize + sizeof(Block); #if RCHECK - size++; + ++size; #endif if (size > MAXALLOC) { bucket = NBUCKETS; @@ -351,13 +330,13 @@ TclpAlloc( } 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; } } @@ -395,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 @@ -414,8 +396,8 @@ TclpFree( cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize; blockPtr->nextBlock = cachePtr->buckets[bucket].firstPtr; cachePtr->buckets[bucket].firstPtr = 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) { @@ -467,7 +449,10 @@ 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 @@ -478,7 +463,7 @@ TclpRealloc( blockPtr = Ptr2Block(ptr); size = reqSize + sizeof(Block); #if RCHECK - size++; + ++size; #endif bucket = blockPtr->sourceBucket; if (bucket != NBUCKETS) { @@ -531,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) { - register Cache *cachePtr; + 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 @@ -573,7 +556,7 @@ TclThreadAllocObj(void) } while (--numMove >= 0) { objPtr = &newObjsPtr[numMove]; - objPtr->internalRep.otherValuePtr = cachePtr->firstObjPtr; + objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; cachePtr->firstObjPtr = objPtr; } } @@ -584,8 +567,8 @@ TclThreadAllocObj(void) */ objPtr = cachePtr->firstObjPtr; - cachePtr->firstObjPtr = objPtr->internalRep.otherValuePtr; - cachePtr->numObjects--; + cachePtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1; + --cachePtr->numObjects; return objPtr; } @@ -602,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 - * *---------------------------------------------------------------------- */ @@ -613,17 +592,19 @@ 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. */ - objPtr->internalRep.otherValuePtr = cachePtr->firstObjPtr; + objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; cachePtr->firstObjPtr = objPtr; - cachePtr->numObjects++; + ++cachePtr->numObjects; /* * If the number of free objects has exceeded the high water mark, move @@ -722,16 +703,16 @@ MoveObjs( */ while (--numMove) { - objPtr = objPtr->internalRep.otherValuePtr; + objPtr = objPtr->internalRep.twoPtrValue.ptr1; } - fromPtr->firstObjPtr = objPtr->internalRep.otherValuePtr; + 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. */ - objPtr->internalRep.otherValuePtr = toPtr->firstObjPtr; + objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr; toPtr->firstObjPtr = fromFirstObjPtr; } @@ -815,14 +796,14 @@ LockBucket( #if 0 if (Tcl_MutexTryLock(bucketInfo[bucket].lockPtr) != TCL_OK) { Tcl_MutexLock(bucketInfo[bucket].lockPtr); - cachePtr->buckets[bucket].numWaits++; - sharedPtr->buckets[bucket].numWaits++; + ++cachePtr->buckets[bucket].numWaits; + ++sharedPtr->buckets[bucket].numWaits; } #else Tcl_MutexLock(bucketInfo[bucket].lockPtr); #endif - cachePtr->buckets[bucket].numLocks++; - sharedPtr->buckets[bucket].numLocks++; + ++cachePtr->buckets[bucket].numLocks; + ++sharedPtr->buckets[bucket].numLocks; } static void @@ -961,7 +942,7 @@ GetBlocks( size = bucketInfo[n].blockSize; blockPtr = cachePtr->buckets[n].firstPtr; cachePtr->buckets[n].firstPtr = blockPtr->nextBlock; - cachePtr->buckets[n].numFree--; + --cachePtr->buckets[n].numFree; break; } } @@ -1018,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); @@ -1031,6 +1012,33 @@ TclFinalizeThreadAlloc(void) TclpFreeAllocCache(NULL); } +/* + *---------------------------------------------------------------------- + * + * TclFinalizeThreadAllocThread -- + * + * 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. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclFinalizeThreadAllocThread(void) +{ + Cache *cachePtr = TclpGetAllocCache(); + if (cachePtr != NULL) { + TclpFreeAllocCache(cachePtr); + } +} + #else /* !(TCL_THREADS && USE_THREAD_ALLOC) */ /* *---------------------------------------------------------------------- |
