Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | slightly faster inUse computation |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | mig-alloc-reform |
Files: | files | file ages | folders |
SHA1: |
0148c7fff1647218ef6134b861135dff |
User & Date: | mig 2011-03-24 20:23:20 |
Context
2011-03-24
| ||
22:06 | add finalization code; needed? check-in: 5a869d1e11 user: mig tags: mig-alloc-reform | |
20:23 | slightly faster inUse computation check-in: 0148c7fff1 user: mig tags: mig-alloc-reform | |
19:24 | merge trunk into feature branch check-in: 7649a6b239 user: mig tags: mig-alloc-reform | |
Changes
Changes to generic/tclAlloc.c.
︙ | ︙ | |||
126 127 128 129 130 131 132 | typedef struct Block { union { struct Block *next; /* Next in free list. */ struct { unsigned char magic1; /* First magic number. */ unsigned char bucket; /* Bucket block allocated from. */ | | | < | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | typedef struct Block { union { struct Block *next; /* Next in free list. */ struct { unsigned char magic1; /* First magic number. */ unsigned char bucket; /* Bucket block allocated from. */ unsigned char inUse; /* Block memory currently in use, see * details in TclpAlloc/Realloc. */ unsigned char magic2; /* Second magic number. */ } s; } u; long refCount; } Block; #define OFFSET ALIGN(sizeof(Block)) |
︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 | /* * The following array specifies various per-bucket limits and locks. The * values are statically initialized to avoid calculating them repeatedly. */ static struct { size_t blockSize; /* Bucket blocksize. */ #if defined(TCL_THREADS) int maxBlocks; /* Max blocks before move to share. */ int numMove; /* Num blocks to move to share. */ Tcl_Mutex *lockPtr; /* Share bucket lock. */ #endif } bucketInfo[NBUCKETS]; | > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | /* * The following array specifies various per-bucket limits and locks. The * values are statically initialized to avoid calculating them repeatedly. */ static struct { size_t blockSize; /* Bucket blocksize. */ int shift; #if defined(TCL_THREADS) int maxBlocks; /* Max blocks before move to share. */ int numMove; /* Num blocks to move to share. */ Tcl_Mutex *lockPtr; /* Share bucket lock. */ #endif } bucketInfo[NBUCKETS]; |
︙ | ︙ | |||
341 342 343 344 345 346 347 | */ #if USE_ZIPPY static void InitBucketInfo () { int i; | > | | > > > > | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | */ #if USE_ZIPPY static void InitBucketInfo () { int i; int shift = 0; for (i = 0; i < NBUCKETS; ++i) { bucketInfo[i].blockSize = MINALLOC << i; while (((bucketInfo[i].blockSize -OFFSET) >> shift) > 255) { ++shift; } bucketInfo[i].shift = shift; #if defined(TCL_THREADS) /* TODO: clearer logic? Change move to keep? */ bucketInfo[i].maxBlocks = 1 << (NBUCKETS - 1 - i); bucketInfo[i].numMove = i < NBUCKETS - 1 ? 1 << (NBUCKETS - 2 - i) : 1; bucketInfo[i].lockPtr = TclpNewAllocMutex(); #endif |
︙ | ︙ | |||
715 716 717 718 719 720 721 | { register void *ptr; blockPtr->magicNum1 = blockPtr->magicNum2 = MAGIC; if (bucket == NBUCKETS) { blockPtr->used = 255; } else { | < < < < | < < < | 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | { register void *ptr; blockPtr->magicNum1 = blockPtr->magicNum2 = MAGIC; if (bucket == NBUCKETS) { blockPtr->used = 255; } else { blockPtr->used = (reqSize >> bucketInfo[bucket].shift); } blockPtr->sourceBucket = bucket; ptr = (void *) (((char *)blockPtr) + OFFSET); blockPtr->refCount = 0; return (char *) ptr; } |
︙ | ︙ | |||
939 940 941 942 943 944 945 | /* Requested allocation exceeds memory */ return NULL; } } #endif /* | | | | > | 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | /* Requested allocation exceeds memory */ return NULL; } } #endif /* * If the block is not a system block and belongs in the same block, * simply return the existing pointer. Otherwise, if the block is a system * block and the new size would also require a system block, call * realloc() directly. */ blockPtr = Ptr2Block(ptr); if (blockPtr->refCount != 0) { Tcl_Panic("trying to realloc a preserved pointer"); } |
︙ | ︙ | |||
975 976 977 978 979 980 981 | /* * Finally, perform an expensive malloc/copy/free. */ newPtr = TclpAlloc(reqSize); if (newPtr != NULL) { size_t maxSize = bucketInfo[bucket].blockSize - OFFSET; | | > > > | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 | /* * Finally, perform an expensive malloc/copy/free. */ newPtr = TclpAlloc(reqSize); if (newPtr != NULL) { size_t maxSize = bucketInfo[bucket].blockSize - OFFSET; size_t toCopy = ((blockPtr->used + 1) << bucketInfo[bucket].shift); if (toCopy > maxSize) { toCopy = maxSize; } if (toCopy > reqSize) { toCopy = reqSize; } memcpy(newPtr, ptr, toCopy); TclpFree(ptr); } |
︙ | ︙ | |||
1419 1420 1421 1422 1423 1424 1425 | * TclEventuallyFree has already been called on this with * (freeProc != TCL_DYNAMIC) */ --blockPtr->refCount; } else { /* | | > | 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 | * TclEventuallyFree has already been called on this with * (freeProc != TCL_DYNAMIC) */ --blockPtr->refCount; } else { /* * First preserve call: add one refcount to signal that EventuallyFree * has not yet been called (role of the old '!mustFree') */ blockPtr->refCount = 2; } } /* |
︙ | ︙ |