| ︙ | | |
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
+
|
static void LockBucket(Cache *cachePtr, int bucket);
static void UnlockBucket(Cache *cachePtr, int bucket);
static void PutBlocks(Cache *cachePtr, int bucket, int 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);
/*
* Local variables defined in this file and initialized at startup.
*/
static Tcl_Mutex *listLockPtr;
static Tcl_Mutex *objLockPtr;
|
| ︙ | | |
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
-
-
+
-
|
}
/*
* Flush objs.
*/
if (cachePtr->numObjects > 0) {
Tcl_MutexLock(objLockPtr);
MoveObjs(cachePtr, sharedPtr, cachePtr->numObjects);
PutObjs(cachePtr, cachePtr->numObjects);
Tcl_MutexUnlock(objLockPtr);
}
/*
* Remove from pool list.
*/
Tcl_MutexLock(listLockPtr);
|
| ︙ | | |
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
|
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
|
-
-
+
-
|
/*
* If the number of free objects has exceeded the high water mark, move
* some blocks to the shared list.
*/
if (cachePtr->numObjects > NOBJHIGH) {
Tcl_MutexLock(objLockPtr);
MoveObjs(cachePtr, sharedPtr, NOBJALLOC);
PutObjs(cachePtr, NOBJALLOC);
Tcl_MutexUnlock(objLockPtr);
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_GetMemoryInfo --
|
| ︙ | | |
731
732
733
734
735
736
737
738
739
740
741
742
743
744
|
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
* Move all objects as a block - they are already linked to each other, we
* just have to update the first and last.
*/
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,
int numMove)
{
int keep = fromPtr->numObjects - numMove;
Tcl_Obj *firstPtr, *lastPtr;
fromPtr->numObjects = keep;
firstPtr = fromPtr->firstObjPtr;
if (keep == 0) {
fromPtr->firstObjPtr = NULL;
} else {
do {
lastPtr = firstPtr;
firstPtr = firstPtr->internalRep.twoPtrValue.ptr1;
} while (--keep > 0);
lastPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
/* TODO: We could avoid this walk to lastPtr if we kept a lastPtr field */
lastPtr = firstPtr;
while (lastPtr->internalRep.twoPtrValue.ptr1) {
lastPtr = lastPtr->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.
*/
Tcl_MutexLock(objLockPtr);
lastPtr->internalRep.twoPtrValue.ptr1 = sharedPtr->firstObjPtr;
sharedPtr->firstObjPtr = firstPtr;
sharedPtr->numObjects += numMove;
Tcl_MutexUnlock(objLockPtr);
}
/*
*----------------------------------------------------------------------
*
* Block2Ptr, Ptr2Block --
*
* Convert between internal blocks and user pointers.
|
| ︙ | | |
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
|
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
|
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
+
+
+
|
static void
PutBlocks(
Cache *cachePtr,
int bucket,
int numMove)
{
/*
* We have numFree. Want to shed numMove. So compute how many
* Blocks to keep.
*/
int keep = cachePtr->buckets[bucket].numFree - numMove;
register Block *lastPtr, *firstPtr;
register int n = numMove;
/*
Block *lastPtr, *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 > 0);
lastPtr->nextBlock = NULL;
}
/*
* Before acquiring the lock, walk the block list to find the last block
* to be moved.
* firstPtr now points to the first Block to return to shared.
*/
/* TODO: We could avoid this walk to lastPtr if we kept a lastPtr field */
firstPtr = lastPtr = cachePtr->buckets[bucket].firstPtr;
while (--n > 0) {
lastPtr = firstPtr;
while (lastPtr->nextBlock) {
lastPtr = lastPtr->nextBlock;
}
cachePtr->buckets[bucket].firstPtr = lastPtr->nextBlock;
cachePtr->buckets[bucket].numFree -= numMove;
/*
* lastPtr now points to the last Block to return to shared.
*/
/*
* Aquire the lock and place the list of blocks at the front of the shared
* cache bucket.
*/
LockBucket(cachePtr, bucket);
|
| ︙ | | |