summaryrefslogtreecommitdiffstats
path: root/generic/tclThreadAlloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclThreadAlloc.c')
-rw-r--r--generic/tclThreadAlloc.c166
1 files changed, 95 insertions, 71 deletions
diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c
index 5a1e8ca..28475f9 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 (C) 1999 America Online, Inc.
+ * Portions created by AOL are Copyright © 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 defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+#if TCL_THREADS && defined(USE_THREAD_ALLOC)
/*
* If range checking is enabled, an additional byte will be allocated to store
@@ -82,18 +82,17 @@ typedef union Block {
* and statistics information.
*/
-typedef struct Bucket {
+typedef struct {
Block *firstPtr; /* First block available */
Block *lastPtr; /* End of block list */
- long numFree; /* Number of blocks available */
+ size_t numFree; /* Number of blocks available */
/* All fields below for accounting only */
- 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 */
+ 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 */
} Bucket;
/*
@@ -107,9 +106,9 @@ 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 */
- int numObjects; /* Number of objects for thread */
+ size_t numObjects; /* Number of objects for thread */
Tcl_Obj *lastPtr; /* Last object in this cache */
- int totalAssigned; /* Total space assigned to thread */
+ size_t totalAssigned; /* Total space assigned to thread */
Bucket buckets[NBUCKETS]; /* The buckets for this thread */
} Cache;
@@ -120,8 +119,8 @@ typedef struct Cache {
static struct {
size_t blockSize; /* Bucket blocksize. */
- int maxBlocks; /* Max blocks before move to share. */
- int numMove; /* Num blocks to move to share. */
+ size_t maxBlocks; /* Max blocks before move to share. */
+ size_t numMove; /* Num blocks to move to share. */
Tcl_Mutex *lockPtr; /* Share bucket lock. */
} bucketInfo[NBUCKETS];
@@ -132,12 +131,12 @@ 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, int numMove);
+static void PutBlocks(Cache *cachePtr, int bucket, size_t numMove);
static int GetBlocks(Cache *cachePtr, int bucket);
-static Block * Ptr2Block(char *ptr);
-static char * Block2Ptr(Block *blockPtr, int bucket, unsigned int reqSize);
-static void MoveObjs(Cache *fromPtr, Cache *toPtr, int numMove);
-static void PutObjs(Cache *fromPtr, int numMove);
+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);
/*
* Local variables defined in this file and initialized at startup.
@@ -162,7 +161,7 @@ static __thread Cache *tcachePtr;
#else
# define GETCACHE(cachePtr) \
do { \
- (cachePtr) = TclpGetAllocCache(); \
+ (cachePtr) = (Cache*)TclpGetAllocCache(); \
if ((cachePtr) == NULL) { \
(cachePtr) = GetCache(); \
} \
@@ -196,20 +195,11 @@ GetCache(void)
if (listLockPtr == NULL) {
Tcl_Mutex *initLockPtr;
- unsigned int i;
initLockPtr = Tcl_GetAllocMutex();
Tcl_MutexLock(initLockPtr);
if (listLockPtr == NULL) {
- 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();
- }
+ TclInitThreadAlloc();
}
Tcl_MutexUnlock(initLockPtr);
}
@@ -218,9 +208,9 @@ GetCache(void)
* Get this thread's cache, allocating if necessary.
*/
- cachePtr = TclpGetAllocCache();
+ cachePtr = (Cache*)TclpGetAllocCache();
if (cachePtr == NULL) {
- cachePtr = TclpSysAlloc(sizeof(Cache), 0);
+ cachePtr = (Cache*)TclpSysAlloc(sizeof(Cache), 0);
if (cachePtr == NULL) {
Tcl_Panic("alloc: could not allocate new cache");
}
@@ -255,7 +245,7 @@ void
TclFreeAllocCache(
void *arg)
{
- Cache *cachePtr = arg;
+ Cache *cachePtr = (Cache*)arg;
Cache **nextPtrPtr;
unsigned int bucket;
@@ -308,7 +298,7 @@ TclFreeAllocCache(
*----------------------------------------------------------------------
*/
-char *
+void *
TclpAlloc(
unsigned int reqSize)
{
@@ -346,7 +336,7 @@ TclpAlloc(
#endif
if (size > MAXALLOC) {
bucket = NBUCKETS;
- blockPtr = TclpSysAlloc(size, 0);
+ blockPtr = (Block *)TclpSysAlloc(size, 0);
if (blockPtr != NULL) {
cachePtr->totalAssigned += reqSize;
}
@@ -387,7 +377,7 @@ TclpAlloc(
void
TclpFree(
- char *ptr)
+ void *ptr)
{
Cache *cachePtr;
Block *blockPtr;
@@ -444,9 +434,9 @@ TclpFree(
*----------------------------------------------------------------------
*/
-char *
+void *
TclpRealloc(
- char *ptr,
+ void *ptr,
unsigned int reqSize)
{
Cache *cachePtr;
@@ -500,7 +490,7 @@ TclpRealloc(
} else if (size > MAXALLOC) {
cachePtr->totalAssigned -= blockPtr->blockReqSize;
cachePtr->totalAssigned += reqSize;
- blockPtr = TclpSysRealloc(blockPtr, size);
+ blockPtr = (Block*)TclpSysRealloc(blockPtr, size);
if (blockPtr == NULL) {
return NULL;
}
@@ -557,7 +547,7 @@ TclThreadAllocObj(void)
*/
if (cachePtr->numObjects == 0) {
- int numMove;
+ size_t numMove;
Tcl_MutexLock(objLockPtr);
numMove = sharedPtr->numObjects;
@@ -572,13 +562,13 @@ TclThreadAllocObj(void)
Tcl_Obj *newObjsPtr;
cachePtr->numObjects = numMove = NOBJALLOC;
- newObjsPtr = TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0);
+ newObjsPtr = (Tcl_Obj *)TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0);
if (newObjsPtr == NULL) {
- Tcl_Panic("alloc: could not allocate %d new objects", numMove);
+ Tcl_Panic("alloc: could not allocate %ld new objects", numMove);
}
cachePtr->lastPtr = newObjsPtr + numMove - 1;
objPtr = cachePtr->firstObjPtr; /* NULL */
- while (--numMove >= 0) {
+ while (numMove-- > 0) {
newObjsPtr[numMove].internalRep.twoPtrValue.ptr1 = objPtr;
objPtr = newObjsPtr + numMove;
}
@@ -591,7 +581,7 @@ TclThreadAllocObj(void)
*/
objPtr = cachePtr->firstObjPtr;
- cachePtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
+ cachePtr->firstObjPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1;
cachePtr->numObjects--;
return objPtr;
}
@@ -680,14 +670,14 @@ Tcl_GetMemoryInfo(
Tcl_DStringAppendElement(dsPtr, buf);
}
for (n = 0; n < NBUCKETS; ++n) {
- sprintf(buf, "%lu %ld %ld %ld %ld %ld %ld",
- (unsigned long) bucketInfo[n].blockSize,
+ sprintf(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,
cachePtr->buckets[n].numFree,
cachePtr->buckets[n].numRemoves,
cachePtr->buckets[n].numInserts,
cachePtr->buckets[n].totalAssigned,
- cachePtr->buckets[n].numLocks,
- cachePtr->buckets[n].numWaits);
+ cachePtr->buckets[n].numLocks);
Tcl_DStringAppendElement(dsPtr, buf);
}
Tcl_DStringEndSublist(dsPtr);
@@ -716,7 +706,7 @@ static void
MoveObjs(
Cache *fromPtr,
Cache *toPtr,
- int numMove)
+ size_t numMove)
{
Tcl_Obj *objPtr = fromPtr->firstObjPtr;
Tcl_Obj *fromFirstObjPtr = objPtr;
@@ -729,10 +719,10 @@ MoveObjs(
* to be moved) as the first object in the 'from' cache.
*/
- while (--numMove) {
- objPtr = objPtr->internalRep.twoPtrValue.ptr1;
+ while (numMove-- > 1) {
+ objPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1;
}
- fromPtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
+ fromPtr->firstObjPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1;
/*
* Move all objects as a block - they are already linked to each other, we
@@ -763,9 +753,9 @@ MoveObjs(
static void
PutObjs(
Cache *fromPtr,
- int numMove)
+ size_t numMove)
{
- int keep = fromPtr->numObjects - numMove;
+ size_t keep = fromPtr->numObjects - numMove;
Tcl_Obj *firstPtr, *lastPtr = NULL;
fromPtr->numObjects = keep;
@@ -775,8 +765,8 @@ PutObjs(
} else {
do {
lastPtr = firstPtr;
- firstPtr = firstPtr->internalRep.twoPtrValue.ptr1;
- } while (--keep > 0);
+ firstPtr = (Tcl_Obj *)firstPtr->internalRep.twoPtrValue.ptr1;
+ } while (keep-- > 1);
lastPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
@@ -813,11 +803,11 @@ PutObjs(
*----------------------------------------------------------------------
*/
-static char *
+static void *
Block2Ptr(
Block *blockPtr,
int bucket,
- unsigned int reqSize)
+ size_t reqSize)
{
void *ptr;
@@ -828,12 +818,12 @@ Block2Ptr(
#if RCHECK
((unsigned char *)(ptr))[reqSize] = MAGIC;
#endif
- return (char *) ptr;
+ return ptr;
}
static Block *
Ptr2Block(
- char *ptr)
+ void *ptr)
{
Block *blockPtr;
@@ -881,7 +871,7 @@ LockBucket(
static void
UnlockBucket(
- Cache *cachePtr,
+ TCL_UNUSED(Cache *),
int bucket)
{
Tcl_MutexUnlock(bucketInfo[bucket].lockPtr);
@@ -907,14 +897,14 @@ static void
PutBlocks(
Cache *cachePtr,
int bucket,
- int numMove)
+ size_t numMove)
{
/*
* We have numFree. Want to shed numMove. So compute how many
* Blocks to keep.
*/
- int keep = cachePtr->buckets[bucket].numFree - numMove;
+ size_t keep = cachePtr->buckets[bucket].numFree - numMove;
Block *lastPtr = NULL, *firstPtr;
cachePtr->buckets[bucket].numFree = keep;
@@ -925,7 +915,7 @@ PutBlocks(
do {
lastPtr = firstPtr;
firstPtr = firstPtr->nextBlock;
- } while (--keep > 0);
+ } while (keep-- > 1);
lastPtr->nextBlock = NULL;
}
@@ -970,7 +960,7 @@ GetBlocks(
int bucket)
{
Block *blockPtr;
- int n;
+ size_t n;
/*
* First, atttempt to move blocks from the shared cache. Note the
@@ -1003,7 +993,7 @@ GetBlocks(
cachePtr->buckets[bucket].firstPtr = blockPtr;
sharedPtr->buckets[bucket].numFree -= n;
cachePtr->buckets[bucket].numFree = n;
- while (--n > 0) {
+ while (n-- > 1) {
blockPtr = blockPtr->nextBlock;
}
sharedPtr->buckets[bucket].firstPtr = blockPtr->nextBlock;
@@ -1024,8 +1014,8 @@ GetBlocks(
blockPtr = NULL;
n = NBUCKETS;
- size = 0; /* lint */
- while (--n > bucket) {
+ size = 0;
+ while (n-- > (size_t)bucket + 1) {
if (cachePtr->buckets[n].numFree > 0) {
size = bucketInfo[n].blockSize;
blockPtr = cachePtr->buckets[n].firstPtr;
@@ -1041,7 +1031,7 @@ GetBlocks(
if (blockPtr == NULL) {
size = MAXALLOC;
- blockPtr = TclpSysAlloc(size, 0);
+ blockPtr = (Block*)TclpSysAlloc(size, 0);
if (blockPtr == NULL) {
return 0;
}
@@ -1054,7 +1044,7 @@ GetBlocks(
n = size / bucketInfo[bucket].blockSize;
cachePtr->buckets[bucket].numFree = n;
cachePtr->buckets[bucket].firstPtr = blockPtr;
- while (--n > 0) {
+ while (n-- > 1) {
blockPtr->nextBlock = (Block *)
((char *) blockPtr + bucketInfo[bucket].blockSize);
blockPtr = blockPtr->nextBlock;
@@ -1064,6 +1054,40 @@ GetBlocks(
}
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();
+}
/*
*----------------------------------------------------------------------
@@ -1122,7 +1146,7 @@ TclFinalizeThreadAlloc(void)
void
TclFinalizeThreadAllocThread(void)
{
- Cache *cachePtr = TclpGetAllocCache();
+ Cache *cachePtr = (Cache *)TclpGetAllocCache();
if (cachePtr != NULL) {
TclpFreeAllocCache(cachePtr);
}
@@ -1147,7 +1171,7 @@ TclFinalizeThreadAllocThread(void)
void
Tcl_GetMemoryInfo(
- Tcl_DString *dsPtr)
+ TCL_UNUSED(Tcl_DString *))
{
Tcl_Panic("Tcl_GetMemoryInfo called when threaded memory allocator not in use");
}