aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorGareth Rees2013-05-20 20:45:26 +0100
committerGareth Rees2013-05-20 20:45:26 +0100
commit2849a0bd33b8aa80910cb31cbdc25b9177fa9b8b (patch)
tree5085f58d805f2570c572bd9148c3059e1a97aedf /mps/code
parentdf1a8a3807db2d085e668aa625a0734d79e46eec (diff)
downloademacs-2849a0bd33b8aa80910cb31cbdc25b9177fa9b8b.tar.gz
emacs-2849a0bd33b8aa80910cb31cbdc25b9177fa9b8b.zip
Make the cbs module more abstract by removing cbsblock from the public interface. avoid re-entrancy problems by removing the callback interface. public interfaces like cbsiteratemethod now operate in terms of address ranges rather than cbsblocks.
The functions CBSInsert, CBSDelete and CBSFind* now additionally return an "old" address range which gives the former base and limit of the block that has just been updated. This gives clients enough information to update their caches if need be. Update CBS test and design accordingly. Copied from Perforce Change: 182014 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/cbs.c222
-rw-r--r--mps/code/cbs.h49
-rw-r--r--mps/code/cbstest.c241
3 files changed, 73 insertions, 439 deletions
diff --git a/mps/code/cbs.c b/mps/code/cbs.c
index f40d075b27e..7b17d295f32 100644
--- a/mps/code/cbs.c
+++ b/mps/code/cbs.c
@@ -21,6 +21,24 @@
21SRCID(cbs, "$Id$"); 21SRCID(cbs, "$Id$");
22 22
23 23
24typedef struct CBSBlockStruct *CBSBlock;
25typedef struct CBSBlockStruct {
26 SplayNodeStruct splayNode;
27 Addr base;
28 Addr limit;
29 Size maxSize; /* accurate maximum block size of sub-tree */
30} CBSBlockStruct;
31
32
33extern Bool CBSBlockCheck(CBSBlock block);
34/* CBSBlockBase -- See <design/cbs/#function.cbs.block.base> */
35#define CBSBlockBase(block) ((block)->base)
36/* CBSBlockLimit -- See <design/cbs/#function.cbs.block.limit> */
37#define CBSBlockLimit(block) ((block)->limit)
38#define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit)
39extern Size (CBSBlockSize)(CBSBlock block);
40
41
24#define cbsOfSplayTree(tree) PARENT(CBSStruct, splayTree, (tree)) 42#define cbsOfSplayTree(tree) PARENT(CBSStruct, splayTree, (tree))
25#define cbsBlockOfSplayNode(node) PARENT(CBSBlockStruct, splayNode, (node)) 43#define cbsBlockOfSplayNode(node) PARENT(CBSBlockStruct, splayNode, (node))
26#define splayTreeOfCBS(tree) (&((cbs)->splayTree)) 44#define splayTreeOfCBS(tree) (&((cbs)->splayTree))
@@ -65,10 +83,6 @@ Bool CBSCheck(CBS cbs)
65 CHECKD(Pool, cbs->blockPool); 83 CHECKD(Pool, cbs->blockPool);
66 CHECKL(BoolCheck(cbs->fastFind)); 84 CHECKL(BoolCheck(cbs->fastFind));
67 CHECKL(BoolCheck(cbs->inCBS)); 85 CHECKL(BoolCheck(cbs->inCBS));
68 CHECKL(cbs->new == NULL || FUNCHECK(cbs->new));
69 CHECKL(cbs->delete == NULL || FUNCHECK(cbs->delete));
70 CHECKL(cbs->grow == NULL || FUNCHECK(cbs->grow));
71 CHECKL(cbs->shrink == NULL || FUNCHECK(cbs->shrink));
72 /* No MeterCheck */ 86 /* No MeterCheck */
73 87
74 return TRUE; 88 return TRUE;
@@ -206,17 +220,11 @@ static void cbsUpdateNode(SplayTree tree, SplayNode node,
206 * See <design/cbs/#function.cbs.init>. 220 * See <design/cbs/#function.cbs.init>.
207 */ 221 */
208 222
209Res CBSInit(Arena arena, CBS cbs, void *owner, 223Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, Bool fastFind)
210 CBSChangeSizeMethod new, CBSChangeSizeMethod delete,
211 CBSChangeSizeMethod grow, CBSChangeSizeMethod shrink,
212 Size minSize, Align alignment,
213 Bool fastFind)
214{ 224{
215 Res res; 225 Res res;
216 226
217 AVERT(Arena, arena); 227 AVERT(Arena, arena);
218 AVER(new == NULL || FUNCHECK(new));
219 AVER(delete == NULL || FUNCHECK(delete));
220 228
221 SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare, 229 SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare,
222 fastFind ? &cbsUpdateNode : NULL); 230 fastFind ? &cbsUpdateNode : NULL);
@@ -226,11 +234,6 @@ Res CBSInit(Arena arena, CBS cbs, void *owner,
226 return res; 234 return res;
227 cbs->splayTreeSize = 0; 235 cbs->splayTreeSize = 0;
228 236
229 cbs->new = new;
230 cbs->delete = delete;
231 cbs->grow = grow;
232 cbs->shrink = shrink;
233 cbs->minSize = minSize;
234 cbs->fastFind = fastFind; 237 cbs->fastFind = fastFind;
235 cbs->alignment = alignment; 238 cbs->alignment = alignment;
236 cbs->inCBS = TRUE; 239 cbs->inCBS = TRUE;
@@ -292,9 +295,6 @@ static void cbsBlockDelete(CBS cbs, CBSBlock block)
292 /* make invalid */ 295 /* make invalid */
293 block->limit = block->base; 296 block->limit = block->base;
294 297
295 if (cbs->delete != NULL && oldSize >= cbs->minSize)
296 (*(cbs->delete))(cbs, block, oldSize, (Size)0);
297
298 PoolFree(cbs->blockPool, (Addr)block, sizeof(CBSBlockStruct)); 298 PoolFree(cbs->blockPool, (Addr)block, sizeof(CBSBlockStruct));
299 299
300 return; 300 return;
@@ -315,11 +315,6 @@ static void cbsBlockShrink(CBS cbs, CBSBlock block, Size oldSize)
315 keyOfCBSBlock(block)); 315 keyOfCBSBlock(block));
316 AVER(CBSBlockSize(block) <= block->maxSize); 316 AVER(CBSBlockSize(block) <= block->maxSize);
317 } 317 }
318
319 if (cbs->delete != NULL && oldSize >= cbs->minSize && newSize < cbs->minSize)
320 (*(cbs->delete))(cbs, block, oldSize, newSize);
321 else if (cbs->shrink != NULL && newSize >= cbs->minSize)
322 (*(cbs->shrink))(cbs, block, oldSize, newSize);
323} 318}
324 319
325static void cbsBlockGrow(CBS cbs, CBSBlock block, Size oldSize) 320static void cbsBlockGrow(CBS cbs, CBSBlock block, Size oldSize)
@@ -337,11 +332,6 @@ static void cbsBlockGrow(CBS cbs, CBSBlock block, Size oldSize)
337 keyOfCBSBlock(block)); 332 keyOfCBSBlock(block));
338 AVER(CBSBlockSize(block) <= block->maxSize); 333 AVER(CBSBlockSize(block) <= block->maxSize);
339 } 334 }
340
341 if (cbs->new != NULL && oldSize < cbs->minSize && newSize >= cbs->minSize)
342 (*(cbs->new))(cbs, block, oldSize, newSize);
343 else if (cbs->grow != NULL && oldSize >= cbs->minSize)
344 (*(cbs->grow))(cbs, block, oldSize, newSize);
345} 335}
346 336
347static Res cbsBlockNew(CBS cbs, Addr base, Addr limit) 337static Res cbsBlockNew(CBS cbs, Addr base, Addr limit)
@@ -373,9 +363,6 @@ static Res cbsBlockNew(CBS cbs, Addr base, Addr limit)
373 AVER(res == ResOK); 363 AVER(res == ResOK);
374 STATISTIC(++cbs->splayTreeSize); 364 STATISTIC(++cbs->splayTreeSize);
375 365
376 if (cbs->new != NULL && newSize >= cbs->minSize)
377 (*(cbs->new))(cbs, block, (Size)0, newSize);
378
379 return ResOK; 366 return ResOK;
380 367
381failPoolAlloc: 368failPoolAlloc:
@@ -485,12 +472,14 @@ fail:
485 * See <design/cbs/#functions.cbs.insert>. 472 * See <design/cbs/#functions.cbs.insert>.
486 */ 473 */
487 474
488Res CBSInsertReturningRange(Addr *baseReturn, Addr *limitReturn, 475Res CBSInsert(Addr *baseReturn, Addr *limitReturn,
489 CBS cbs, Addr base, Addr limit) 476 CBS cbs, Addr base, Addr limit)
490{ 477{
491 Addr newBase, newLimit; 478 Addr newBase, newLimit;
492 Res res; 479 Res res;
493 480
481 AVER(baseReturn != NULL);
482 AVER(limitReturn != NULL);
494 AVERT(CBS, cbs); 483 AVERT(CBS, cbs);
495 CBSEnter(cbs); 484 CBSEnter(cbs);
496 485
@@ -511,24 +500,11 @@ Res CBSInsertReturningRange(Addr *baseReturn, Addr *limitReturn,
511 return res; 500 return res;
512} 501}
513 502
514Res CBSInsert(CBS cbs, Addr base, Addr limit)
515{
516 Res res;
517 Addr newBase, newLimit;
518
519 /* all parameters checked by CBSInsertReturningRange */
520 /* CBSEnter/Leave done by CBSInsertReturningRange */
521
522 res = CBSInsertReturningRange(&newBase, &newLimit,
523 cbs, base, limit);
524
525 return res;
526}
527
528 503
529/* cbsDeleteFrom* -- delete blocks from different parts of the CBS */ 504/* cbsDeleteFrom* -- delete blocks from different parts of the CBS */
530 505
531static Res cbsDeleteFromTree(CBS cbs, Addr base, Addr limit) 506static Res cbsDeleteFromTree(Addr *baseReturn, Addr *limitReturn,
507 CBS cbs, Addr base, Addr limit)
532{ 508{
533 Res res; 509 Res res;
534 CBSBlock cbsBlock; 510 CBSBlock cbsBlock;
@@ -548,6 +524,9 @@ static Res cbsDeleteFromTree(CBS cbs, Addr base, Addr limit)
548 goto failLimitCheck; 524 goto failLimitCheck;
549 } 525 }
550 526
527 *baseReturn = cbsBlock->base;
528 *limitReturn = cbsBlock->limit;
529
551 if (base == cbsBlock->base) { 530 if (base == cbsBlock->base) {
552 if (limit == cbsBlock->limit) { /* entire block */ 531 if (limit == cbsBlock->limit) { /* entire block */
553 cbsBlockDelete(cbs, cbsBlock); 532 cbsBlockDelete(cbs, cbsBlock);
@@ -609,7 +588,8 @@ failSplayTreeSearch:
609 * See <design/cbs/#function.cbs.delete>. 588 * See <design/cbs/#function.cbs.delete>.
610 */ 589 */
611 590
612Res CBSDelete(CBS cbs, Addr base, Addr limit) 591Res CBSDelete(Addr *baseReturn, Addr *limitReturn,
592 CBS cbs, Addr base, Addr limit)
613{ 593{
614 Res res; 594 Res res;
615 595
@@ -621,14 +601,14 @@ Res CBSDelete(CBS cbs, Addr base, Addr limit)
621 AVER(AddrIsAligned(base, cbs->alignment)); 601 AVER(AddrIsAligned(base, cbs->alignment));
622 AVER(AddrIsAligned(limit, cbs->alignment)); 602 AVER(AddrIsAligned(limit, cbs->alignment));
623 603
624 res = cbsDeleteFromTree(cbs, base, limit); 604 res = cbsDeleteFromTree(baseReturn, limitReturn, cbs, base, limit);
625 605
626 CBSLeave(cbs); 606 CBSLeave(cbs);
627 return res; 607 return res;
628} 608}
629 609
630 610
631Res CBSBlockDescribe(CBSBlock block, mps_lib_FILE *stream) 611static Res CBSBlockDescribe(CBSBlock block, mps_lib_FILE *stream)
632{ 612{
633 Res res; 613 Res res;
634 614
@@ -678,7 +658,7 @@ static void cbsIterateInternal(CBS cbs, CBSIterateMethod iterate, void *closureP
678 splayNode = SplayTreeFirst(splayTree, NULL); 658 splayNode = SplayTreeFirst(splayTree, NULL);
679 while(splayNode != NULL) { 659 while(splayNode != NULL) {
680 cbsBlock = cbsBlockOfSplayNode(splayNode); 660 cbsBlock = cbsBlockOfSplayNode(splayNode);
681 if (!(*iterate)(cbs, cbsBlock, closureP)) { 661 if (!(*iterate)(cbs, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock), closureP)) {
682 break; 662 break;
683 } 663 }
684 METER_ACC(cbs->splaySearch, cbs->splayTreeSize); 664 METER_ACC(cbs->splaySearch, cbs->splayTreeSize);
@@ -700,110 +680,6 @@ void CBSIterate(CBS cbs, CBSIterateMethod iterate, void *closureP)
700} 680}
701 681
702 682
703/* CBSIterateLarge -- Iterate only large blocks
704 *
705 * This function iterates only blocks that are larger than or equal
706 * to the minimum size.
707 */
708
709typedef struct CBSIterateLargeClosureStruct {
710 void *p;
711 CBSIterateMethod f;
712} CBSIterateLargeClosureStruct, *CBSIterateLargeClosure;
713
714static Bool cbsIterateLargeAction(CBS cbs, CBSBlock block, void *p)
715{
716 Bool b = TRUE;
717 CBSIterateLargeClosure closure;
718
719 closure = (CBSIterateLargeClosure)p;
720 AVER(closure != NULL);
721
722 if (CBSBlockSize(block) >= cbs->minSize)
723 b = (closure->f)(cbs, block, closure->p);
724
725 return b;
726}
727
728
729void CBSIterateLarge(CBS cbs, CBSIterateMethod iterate, void *closureP)
730{
731 CBSIterateLargeClosureStruct closure;
732
733 AVERT(CBS, cbs);
734 CBSEnter(cbs);
735
736 AVER(FUNCHECK(iterate));
737
738 closure.p = closureP;
739 closure.f = iterate;
740 cbsIterateInternal(cbs, &cbsIterateLargeAction, (void *)&closure);
741
742 CBSLeave(cbs);
743 return;
744}
745
746
747/* CBSSetMinSize -- Set minimum interesting size for cbs
748 *
749 * This function may invoke the shrink and grow methods as
750 * appropriate. See <design/cbs/#function.cbs.set.min-size>.
751 */
752
753typedef struct {
754 Size old;
755 Size new;
756} CBSSetMinSizeClosureStruct, *CBSSetMinSizeClosure;
757
758static Bool cbsSetMinSizeGrow(CBS cbs, CBSBlock block, void *p)
759{
760 CBSSetMinSizeClosure closure;
761 Size size;
762
763 closure = (CBSSetMinSizeClosure)p;
764 AVER(closure->old > closure->new);
765 size = CBSBlockSize(block);
766 if (size < closure->old && size >= closure->new)
767 (*cbs->new)(cbs, block, size, size);
768
769 return TRUE;
770}
771
772static Bool cbsSetMinSizeShrink(CBS cbs, CBSBlock block, void *p)
773{
774 CBSSetMinSizeClosure closure;
775 Size size;
776
777 closure = (CBSSetMinSizeClosure)p;
778 AVER(closure->old < closure->new);
779 size = CBSBlockSize(block);
780 if (size >= closure->old && size < closure->new)
781 (*cbs->delete)(cbs, block, size, size);
782
783 return TRUE;
784}
785
786void CBSSetMinSize(CBS cbs, Size minSize)
787{
788 CBSSetMinSizeClosureStruct closure;
789
790 AVERT(CBS, cbs);
791 CBSEnter(cbs);
792
793 closure.old = cbs->minSize;
794 closure.new = minSize;
795
796 if (minSize < cbs->minSize)
797 cbsIterateInternal(cbs, &cbsSetMinSizeGrow, (void *)&closure);
798 else if (minSize > cbs->minSize)
799 cbsIterateInternal(cbs, &cbsSetMinSizeShrink, (void *)&closure);
800
801 cbs->minSize = minSize;
802
803 CBSLeave(cbs);
804}
805
806
807/* CBSFindDeleteCheck -- check method for a CBSFindDelete value */ 683/* CBSFindDeleteCheck -- check method for a CBSFindDelete value */
808 684
809static Bool CBSFindDeleteCheck(CBSFindDelete findDelete) 685static Bool CBSFindDeleteCheck(CBSFindDelete findDelete)
@@ -817,13 +693,11 @@ static Bool CBSFindDeleteCheck(CBSFindDelete findDelete)
817} 693}
818 694
819 695
820/* cbsFindDeleteRange -- delete approriate range of block found */ 696/* cbsFindDeleteRange -- delete appropriate range of block found */
821
822typedef Res (*cbsDeleteMethod)(CBS cbs, Addr base, Addr limit);
823 697
824static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn, 698static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn,
699 Addr *oldBaseReturn, Addr *oldLimitReturn,
825 CBS cbs, Addr base, Addr limit, Size size, 700 CBS cbs, Addr base, Addr limit, Size size,
826 cbsDeleteMethod delete,
827 CBSFindDelete findDelete) 701 CBSFindDelete findDelete)
828{ 702{
829 Bool callDelete = TRUE; 703 Bool callDelete = TRUE;
@@ -834,7 +708,6 @@ static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn,
834 AVER(base < limit); 708 AVER(base < limit);
835 AVER(size > 0); 709 AVER(size > 0);
836 AVER(AddrOffset(base, limit) >= size); 710 AVER(AddrOffset(base, limit) >= size);
837 AVER(FUNCHECK(delete));
838 AVERT(CBSFindDelete, findDelete); 711 AVERT(CBSFindDelete, findDelete);
839 712
840 switch(findDelete) { 713 switch(findDelete) {
@@ -862,7 +735,7 @@ static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn,
862 735
863 if (callDelete) { 736 if (callDelete) {
864 Res res; 737 Res res;
865 res = (*delete)(cbs, base, limit); 738 res = cbsDeleteFromTree(oldBaseReturn, oldLimitReturn, cbs, base, limit);
866 AVER(res == ResOK); 739 AVER(res == ResOK);
867 } 740 }
868 741
@@ -874,11 +747,11 @@ static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn,
874/* CBSFindFirst -- find the first block of at least the given size */ 747/* CBSFindFirst -- find the first block of at least the given size */
875 748
876Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, 749Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
750 Addr *oldBaseReturn, Addr *oldLimitReturn,
877 CBS cbs, Size size, CBSFindDelete findDelete) 751 CBS cbs, Size size, CBSFindDelete findDelete)
878{ 752{
879 Bool found; 753 Bool found;
880 Addr base = (Addr)0, limit = (Addr)0; /* only defined when found is TRUE */ 754 Addr base = (Addr)0, limit = (Addr)0; /* only defined when found is TRUE */
881 cbsDeleteMethod deleteMethod = NULL;
882 755
883 AVERT(CBS, cbs); 756 AVERT(CBS, cbs);
884 CBSEnter(cbs); 757 CBSEnter(cbs);
@@ -904,14 +777,13 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
904 AVER(CBSBlockSize(block) >= size); 777 AVER(CBSBlockSize(block) >= size);
905 base = CBSBlockBase(block); 778 base = CBSBlockBase(block);
906 limit = CBSBlockLimit(block); 779 limit = CBSBlockLimit(block);
907 deleteMethod = &cbsDeleteFromTree;
908 } 780 }
909 } 781 }
910 782
911 if (found) { 783 if (found) {
912 AVER(AddrOffset(base, limit) >= size); 784 AVER(AddrOffset(base, limit) >= size);
913 cbsFindDeleteRange(baseReturn, limitReturn, cbs, base, limit, size, 785 cbsFindDeleteRange(baseReturn, limitReturn, oldBaseReturn, oldLimitReturn,
914 deleteMethod, findDelete); 786 cbs, base, limit, size, findDelete);
915 } 787 }
916 788
917 CBSLeave(cbs); 789 CBSLeave(cbs);
@@ -922,11 +794,11 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
922/* CBSFindLast -- find the last block of at least the given size */ 794/* CBSFindLast -- find the last block of at least the given size */
923 795
924Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, 796Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
797 Addr *oldBaseReturn, Addr *oldLimitReturn,
925 CBS cbs, Size size, CBSFindDelete findDelete) 798 CBS cbs, Size size, CBSFindDelete findDelete)
926{ 799{
927 Bool found; 800 Bool found;
928 Addr base = (Addr)0, limit = (Addr)0; /* only defined in found is TRUE */ 801 Addr base = (Addr)0, limit = (Addr)0; /* only defined in found is TRUE */
929 cbsDeleteMethod deleteMethod = NULL;
930 802
931 AVERT(CBS, cbs); 803 AVERT(CBS, cbs);
932 CBSEnter(cbs); 804 CBSEnter(cbs);
@@ -951,14 +823,13 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
951 AVER(CBSBlockSize(block) >= size); 823 AVER(CBSBlockSize(block) >= size);
952 base = CBSBlockBase(block); 824 base = CBSBlockBase(block);
953 limit = CBSBlockLimit(block); 825 limit = CBSBlockLimit(block);
954 deleteMethod = &cbsDeleteFromTree;
955 } 826 }
956 } 827 }
957 828
958 if (found) { 829 if (found) {
959 AVER(AddrOffset(base, limit) >= size); 830 AVER(AddrOffset(base, limit) >= size);
960 cbsFindDeleteRange(baseReturn, limitReturn, cbs, base, limit, size, 831 cbsFindDeleteRange(baseReturn, limitReturn, oldBaseReturn, oldLimitReturn,
961 deleteMethod, findDelete); 832 cbs, base, limit, size, findDelete);
962 } 833 }
963 834
964 CBSLeave(cbs); 835 CBSLeave(cbs);
@@ -969,11 +840,11 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
969/* CBSFindLargest -- find the largest block in the CBS */ 840/* CBSFindLargest -- find the largest block in the CBS */
970 841
971Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, 842Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn,
843 Addr *oldBaseReturn, Addr *oldLimitReturn,
972 CBS cbs, CBSFindDelete findDelete) 844 CBS cbs, CBSFindDelete findDelete)
973{ 845{
974 Bool found = FALSE; 846 Bool found = FALSE;
975 Addr base = (Addr)0, limit = (Addr)0; /* only defined when found is TRUE */ 847 Addr base = (Addr)0, limit = (Addr)0; /* only defined when found is TRUE */
976 cbsDeleteMethod deleteMethod = NULL;
977 Size size = 0; /* suppress bogus warning from MSVC */ 848 Size size = 0; /* suppress bogus warning from MSVC */
978 849
979 AVERT(CBS, cbs); 850 AVERT(CBS, cbs);
@@ -1002,13 +873,12 @@ Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn,
1002 AVER(CBSBlockSize(block) >= size); 873 AVER(CBSBlockSize(block) >= size);
1003 base = CBSBlockBase(block); 874 base = CBSBlockBase(block);
1004 limit = CBSBlockLimit(block); 875 limit = CBSBlockLimit(block);
1005 deleteMethod = &cbsDeleteFromTree;
1006 } 876 }
1007 } 877 }
1008 878
1009 if (found) { 879 if (found) {
1010 cbsFindDeleteRange(baseReturn, limitReturn, cbs, base, limit, size, 880 cbsFindDeleteRange(baseReturn, limitReturn, oldBaseReturn, oldLimitReturn,
1011 deleteMethod, findDelete); 881 cbs, base, limit, size, findDelete);
1012 } 882 }
1013 883
1014 CBSLeave(cbs); 884 CBSLeave(cbs);
@@ -1031,8 +901,6 @@ Res CBSDescribe(CBS cbs, mps_lib_FILE *stream)
1031 res = WriteF(stream, 901 res = WriteF(stream,
1032 "CBS $P {\n", (WriteFP)cbs, 902 "CBS $P {\n", (WriteFP)cbs,
1033 " blockPool: $P\n", (WriteFP)cbs->blockPool, 903 " blockPool: $P\n", (WriteFP)cbs->blockPool,
1034 " new: $F ", (WriteFF)cbs->new,
1035 " delete: $F \n", (WriteFF)cbs->delete,
1036 NULL); 904 NULL);
1037 if (res != ResOK) return res; 905 if (res != ResOK) return res;
1038 906
diff --git a/mps/code/cbs.h b/mps/code/cbs.h
index ddbda2343f3..7662c9978ed 100644
--- a/mps/code/cbs.h
+++ b/mps/code/cbs.h
@@ -15,10 +15,7 @@
15 15
16 16
17typedef struct CBSStruct *CBS; 17typedef struct CBSStruct *CBS;
18typedef struct CBSBlockStruct *CBSBlock; 18typedef Bool (*CBSIterateMethod)(CBS cbs, Addr base, Addr limit, void *closureP);
19typedef void (*CBSChangeSizeMethod)(CBS cbs, CBSBlock block,
20 Size oldSize, Size newSize);
21typedef Bool (*CBSIterateMethod)(CBS cbs, CBSBlock block, void *closureP);
22 19
23 20
24#define CBSSig ((Sig)0x519CB599) /* SIGnature CBS */ 21#define CBSSig ((Sig)0x519CB599) /* SIGnature CBS */
@@ -27,11 +24,6 @@ typedef struct CBSStruct {
27 SplayTreeStruct splayTree; 24 SplayTreeStruct splayTree;
28 Count splayTreeSize; 25 Count splayTreeSize;
29 Pool blockPool; 26 Pool blockPool;
30 CBSChangeSizeMethod new;
31 CBSChangeSizeMethod delete;
32 CBSChangeSizeMethod grow;
33 CBSChangeSizeMethod shrink;
34 Size minSize;
35 Align alignment; 27 Align alignment;
36 Bool fastFind; 28 Bool fastFind;
37 Bool inCBS; /* prevent reentrance */ 29 Bool inCBS; /* prevent reentrance */
@@ -40,44 +32,19 @@ typedef struct CBSStruct {
40 Sig sig; /* sig at end because embeded */ 32 Sig sig; /* sig at end because embeded */
41} CBSStruct; 33} CBSStruct;
42 34
43typedef struct CBSBlockStruct {
44 SplayNodeStruct splayNode;
45 Addr base;
46 Addr limit;
47 Size maxSize; /* accurate maximum block size of sub-tree */
48} CBSBlockStruct;
49
50
51extern Bool CBSCheck(CBS cbs); 35extern Bool CBSCheck(CBS cbs);
52extern Bool CBSBlockCheck(CBSBlock block);
53 36
54extern Res CBSInit(Arena arena, CBS cbs, void *owner, 37extern Res CBSInit(Arena arena, CBS cbs, void *owner,
55 CBSChangeSizeMethod new, 38 Align alignment, Bool fastFind);
56 CBSChangeSizeMethod delete,
57 CBSChangeSizeMethod grow,
58 CBSChangeSizeMethod shrink,
59 Size minSize,
60 Align alignment,
61 Bool fastFind);
62extern void CBSFinish(CBS cbs); 39extern void CBSFinish(CBS cbs);
63 40
64extern Res CBSInsert(CBS cbs, Addr base, Addr limit); 41extern Res CBSInsert(Addr *baseReturn, Addr *limitReturn,
65extern Res CBSInsertReturningRange(Addr *baseReturn, Addr *limitReturn, 42 CBS cbs, Addr base, Addr limit);
66 CBS cbs, Addr base, Addr limit); 43extern Res CBSDelete(Addr *baseReturn, Addr *limitReturn,
67extern Res CBSDelete(CBS cbs, Addr base, Addr limit); 44 CBS cbs, Addr base, Addr limit);
68extern void CBSIterate(CBS cbs, CBSIterateMethod iterate, void *closureP); 45extern void CBSIterate(CBS cbs, CBSIterateMethod iterate, void *closureP);
69extern void CBSIterateLarge(CBS cbs, CBSIterateMethod iterate, void *closureP);
70extern void CBSSetMinSize(CBS cbs, Size minSize);
71 46
72extern Res CBSDescribe(CBS cbs, mps_lib_FILE *stream); 47extern Res CBSDescribe(CBS cbs, mps_lib_FILE *stream);
73extern Res CBSBlockDescribe(CBSBlock block, mps_lib_FILE *stream);
74
75/* CBSBlockBase -- See <design/cbs/#function.cbs.block.base> */
76#define CBSBlockBase(block) ((block)->base)
77/* CBSBlockLimit -- See <design/cbs/#function.cbs.block.limit> */
78#define CBSBlockLimit(block) ((block)->limit)
79#define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit)
80extern Size (CBSBlockSize)(CBSBlock block);
81 48
82typedef unsigned CBSFindDelete; 49typedef unsigned CBSFindDelete;
83enum { 50enum {
@@ -88,11 +55,13 @@ enum {
88}; 55};
89 56
90extern Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, 57extern Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
58 Addr *oldBaseReturn, Addr *oldLimitReturn,
91 CBS cbs, Size size, CBSFindDelete findDelete); 59 CBS cbs, Size size, CBSFindDelete findDelete);
92extern Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, 60extern Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
61 Addr *oldBaseReturn, Addr *oldLimitReturn,
93 CBS cbs, Size size, CBSFindDelete findDelete); 62 CBS cbs, Size size, CBSFindDelete findDelete);
94
95extern Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, 63extern Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn,
64 Addr *oldBaseReturn, Addr *oldLimitReturn,
96 CBS cbs, CBSFindDelete findDelete); 65 CBS cbs, CBSFindDelete findDelete);
97 66
98 67
diff --git a/mps/code/cbstest.c b/mps/code/cbstest.c
index adb976081e2..3b72e875c28 100644
--- a/mps/code/cbstest.c
+++ b/mps/code/cbstest.c
@@ -20,28 +20,11 @@ SRCID(cbstest, "$Id$");
20 20
21#define ArraySize ((Size)123456) 21#define ArraySize ((Size)123456)
22#define NOperations ((Size)125000) 22#define NOperations ((Size)125000)
23#define MinSize ((Size)120) /* Arbitrary size */
24#define Alignment ((Align)sizeof(void *)) 23#define Alignment ((Align)sizeof(void *))
25 24
26 25
27static Count NAllocateTried, NAllocateSucceeded, NDeallocateTried, 26static Count NAllocateTried, NAllocateSucceeded, NDeallocateTried,
28 NDeallocateSucceeded, NNewBlocks, NDeleteBlocks, NGrowBlocks, 27 NDeallocateSucceeded;
29 NShrinkBlocks;
30
31
32/* Used to predict which callbacks will be called, and with which values. */
33/* At most one callback of each type will be called. */
34typedef struct CallbackPredictionStruct {
35 Bool shouldBeCalled;
36 Size oldSize;
37 Addr base;
38 Addr limit;
39} CallbackPredictionStruct, *CallbackPrediction;
40
41static CallbackPredictionStruct CallbackNew;
42static CallbackPredictionStruct CallbackDelete;
43static CallbackPredictionStruct CallbackGrow;
44static CallbackPredictionStruct CallbackShrink;
45 28
46 29
47typedef struct CheckCBSClosureStruct { 30typedef struct CheckCBSClosureStruct {
@@ -64,89 +47,14 @@ static Index (indexOfAddr)(Addr block, Addr a)
64} 47}
65 48
66 49
67/* This function encapsulates the common tests for the callbacks. */ 50static Bool checkCBSAction(CBS cbs, Addr base, Addr limit, void *p)
68
69static void testCallback(CBS cbs, CBSBlock cbsBlock,
70 Size oldSize, Size newSize,
71 CallbackPrediction prediction)
72{
73 Insist(CBSCheck(cbs));
74 Insist(CBSBlockCheck(cbsBlock));
75 Insist(prediction->shouldBeCalled);
76 Insist(oldSize == prediction->oldSize);
77
78 if (newSize == 0) {
79 Insist(prediction->base == 0);
80 Insist(prediction->limit == 0);
81 } else {
82 Insist(CBSBlockSize(cbsBlock) == newSize);
83 Insist(newSize == AddrOffset(prediction->base, prediction->limit));
84 Insist(CBSBlockBase(cbsBlock) == prediction->base);
85 Insist(CBSBlockLimit(cbsBlock) == prediction->limit);
86 }
87
88 prediction->shouldBeCalled = FALSE;
89}
90
91
92static void cbsNewCallback(CBS cbs, CBSBlock cbsBlock,
93 Size oldSize, Size newSize)
94{ 51{
95 testCallback(cbs, cbsBlock, oldSize, newSize, &CallbackNew);
96 Insist(oldSize < cbs->minSize);
97 Insist(newSize >= cbs->minSize);
98
99 NNewBlocks++;
100}
101
102
103static void cbsDeleteCallback(CBS cbs, CBSBlock cbsBlock,
104 Size oldSize, Size newSize)
105{
106 testCallback(cbs, cbsBlock, oldSize, newSize, &CallbackDelete);
107 Insist(oldSize >= cbs->minSize);
108 Insist(newSize < cbs->minSize);
109
110 NDeleteBlocks++;
111}
112
113
114static void cbsGrowCallback(CBS cbs, CBSBlock cbsBlock,
115 Size oldSize, Size newSize)
116{
117 testCallback(cbs, cbsBlock, oldSize, newSize, &CallbackGrow);
118 Insist(oldSize >= cbs->minSize);
119 Insist(newSize >= cbs->minSize);
120 Insist(oldSize < newSize);
121
122 NGrowBlocks++;
123}
124
125
126static void cbsShrinkCallback(CBS cbs, CBSBlock cbsBlock,
127 Size oldSize, Size newSize)
128{
129 testCallback(cbs, cbsBlock, oldSize, newSize, &CallbackShrink);
130 Insist(oldSize >= cbs->minSize);
131 Insist(newSize >= cbs->minSize);
132 Insist(oldSize > newSize);
133
134 NShrinkBlocks++;
135}
136
137
138static Bool checkCBSAction(CBS cbs, CBSBlock cbsBlock, void *p)
139{
140 Addr base, limit;
141 CheckCBSClosure closure = (CheckCBSClosure)p; 52 CheckCBSClosure closure = (CheckCBSClosure)p;
142 53
143 /* Don't need to check cbs every time */ 54 /* Don't need to check cbs every time */
144 UNUSED(cbs); 55 UNUSED(cbs);
145 Insist(closure != NULL); 56 Insist(closure != NULL);
146 57
147 base = CBSBlockBase(cbsBlock);
148 limit = CBSBlockLimit(cbsBlock);
149
150 if (base > closure->oldLimit) { 58 if (base > closure->oldLimit) {
151 Insist(BTIsSetRange(closure->allocTable, 59 Insist(BTIsSetRange(closure->allocTable,
152 indexOfAddr(closure->base, closure->oldLimit), 60 indexOfAddr(closure->base, closure->oldLimit),
@@ -285,46 +193,14 @@ static void randomRange(Addr *baseReturn, Addr *limitReturn,
285} 193}
286 194
287 195
288/* Set callback expectations */
289
290static void clearExpectations(void)
291{
292 CallbackNew.shouldBeCalled = FALSE;
293 CallbackDelete.shouldBeCalled = FALSE;
294 CallbackGrow.shouldBeCalled = FALSE;
295 CallbackShrink.shouldBeCalled = FALSE;
296}
297
298static void expectCallback(CallbackPrediction prediction,
299 Size oldSize, Addr base, Addr limit)
300{
301 Insist(prediction->shouldBeCalled == FALSE);
302 Insist(base == (Addr)0 || limit > base);
303 Insist(oldSize != (Size)0 || base != (Addr)0);
304 Insist(base != (Addr)0 || limit == (Addr)0);
305
306 prediction->shouldBeCalled = TRUE;
307 prediction->oldSize = oldSize;
308 prediction->base = base;
309 prediction->limit = limit;
310}
311
312
313static void checkExpectations(void)
314{
315 Insist(!CallbackNew.shouldBeCalled);
316 Insist(!CallbackDelete.shouldBeCalled);
317 Insist(!CallbackGrow.shouldBeCalled);
318 Insist(!CallbackShrink.shouldBeCalled);
319}
320
321
322static void allocate(CBS cbs, Addr block, BT allocTable, 196static void allocate(CBS cbs, Addr block, BT allocTable,
323 Addr base, Addr limit) 197 Addr base, Addr limit)
324{ 198{
325 Res res; 199 Res res;
326 Index ib, il; /* Indexed for base and limit */ 200 Index ib, il; /* Indexed for base and limit */
327 Bool isFree; 201 Bool isFree;
202 Addr oldBase, oldLimit;
203 Addr outerBase, outerLimit; /* interval containing [ib, il) */
328 204
329 ib = indexOfAddr(block, base); 205 ib = indexOfAddr(block, base);
330 il = indexOfAddr(block, limit); 206 il = indexOfAddr(block, limit);
@@ -339,7 +215,6 @@ static void allocate(CBS cbs, Addr block, BT allocTable,
339 NAllocateTried++; 215 NAllocateTried++;
340 216
341 if (isFree) { 217 if (isFree) {
342 Addr outerBase, outerLimit; /* interval containing [ib, il) */
343 Size left, right, total; /* Sizes of block and two fragments */ 218 Size left, right, total; /* Sizes of block and two fragments */
344 219
345 outerBase = 220 outerBase =
@@ -350,39 +225,9 @@ static void allocate(CBS cbs, Addr block, BT allocTable,
350 left = AddrOffset(outerBase, base); 225 left = AddrOffset(outerBase, base);
351 right = AddrOffset(limit, outerLimit); 226 right = AddrOffset(limit, outerLimit);
352 total = AddrOffset(outerBase, outerLimit); 227 total = AddrOffset(outerBase, outerLimit);
353
354 /* based on detailed knowledge of CBS behaviour */
355 checkExpectations();
356 if (total >= MinSize && left < MinSize && right < MinSize) {
357 if (left == (Size)0 && right == (Size)0) {
358 expectCallback(&CallbackDelete, total, (Addr)0, (Addr)0);
359 } else if (left >= right) {
360 expectCallback(&CallbackDelete, total, outerBase, base);
361 } else {
362 expectCallback(&CallbackDelete, total, limit, outerLimit);
363 }
364 } else if (left >= MinSize && right >= MinSize) {
365 if (left >= right) {
366 expectCallback(&CallbackShrink, total, outerBase, base);
367 expectCallback(&CallbackNew, (Size)0, limit, outerLimit);
368 } else {
369 expectCallback(&CallbackNew, (Size)0, outerBase, base);
370 expectCallback(&CallbackShrink, total, limit, outerLimit);
371 }
372 } else if (total >= MinSize) {
373 if (left >= right) {
374 Insist(left >= MinSize);
375 Insist(right < MinSize);
376 expectCallback(&CallbackShrink, total, outerBase, base);
377 } else {
378 Insist(left < MinSize);
379 Insist(right >= MinSize);
380 expectCallback(&CallbackShrink, total, limit, outerLimit);
381 }
382 }
383 } 228 }
384 229
385 res = CBSDelete(cbs, base, limit); 230 res = CBSDelete(&oldBase, &oldLimit, cbs, base, limit);
386 231
387 if (!isFree) { 232 if (!isFree) {
388 die_expect((mps_res_t)res, MPS_RES_FAIL, 233 die_expect((mps_res_t)res, MPS_RES_FAIL,
@@ -390,9 +235,10 @@ static void allocate(CBS cbs, Addr block, BT allocTable,
390 } else { /* isFree */ 235 } else { /* isFree */
391 die_expect((mps_res_t)res, MPS_RES_OK, 236 die_expect((mps_res_t)res, MPS_RES_OK,
392 "failed to delete free block"); 237 "failed to delete free block");
238 Insist(oldBase == outerBase);
239 Insist(oldLimit == outerLimit);
393 NAllocateSucceeded++; 240 NAllocateSucceeded++;
394 BTSetRange(allocTable, ib, il); 241 BTSetRange(allocTable, ib, il);
395 checkExpectations();
396 } 242 }
397} 243}
398 244
@@ -439,36 +285,9 @@ static void deallocate(CBS cbs, Addr block, BT allocTable,
439 left = AddrOffset(outerBase, base); 285 left = AddrOffset(outerBase, base);
440 right = AddrOffset(limit, outerLimit); 286 right = AddrOffset(limit, outerLimit);
441 total = AddrOffset(outerBase, outerLimit); 287 total = AddrOffset(outerBase, outerLimit);
442
443 /* based on detailed knowledge of CBS behaviour */
444 checkExpectations();
445 if (total >= MinSize && left < MinSize && right < MinSize) {
446 if (left >= right)
447 expectCallback(&CallbackNew, left, outerBase, outerLimit);
448 else
449 expectCallback(&CallbackNew, right, outerBase, outerLimit);
450 } else if (left >= MinSize && right >= MinSize) {
451 if (left >= right) {
452 expectCallback(&CallbackDelete, right, (Addr)0, (Addr)0);
453 expectCallback(&CallbackGrow, left, outerBase, outerLimit);
454 } else {
455 expectCallback(&CallbackDelete, left, (Addr)0, (Addr)0);
456 expectCallback(&CallbackGrow, right, outerBase, outerLimit);
457 }
458 } else if (total >= MinSize) {
459 if (left >= right) {
460 Insist(left >= MinSize);
461 Insist(right < MinSize);
462 expectCallback(&CallbackGrow, left, outerBase, outerLimit);
463 } else {
464 Insist(left < MinSize);
465 Insist(right >= MinSize);
466 expectCallback(&CallbackGrow, right, outerBase, outerLimit);
467 }
468 }
469 } 288 }
470 289
471 res = CBSInsertReturningRange(&freeBase, &freeLimit, cbs, base, limit); 290 res = CBSInsert(&freeBase, &freeLimit, cbs, base, limit);
472 291
473 if (!isAllocated) { 292 if (!isAllocated) {
474 die_expect((mps_res_t)res, MPS_RES_FAIL, 293 die_expect((mps_res_t)res, MPS_RES_FAIL,
@@ -479,7 +298,6 @@ static void deallocate(CBS cbs, Addr block, BT allocTable,
479 298
480 NDeallocateSucceeded++; 299 NDeallocateSucceeded++;
481 BTResRange(allocTable, ib, il); 300 BTResRange(allocTable, ib, il);
482 checkExpectations();
483 Insist(freeBase == outerBase); 301 Insist(freeBase == outerBase);
484 Insist(freeLimit == outerLimit); 302 Insist(freeLimit == outerLimit);
485 } 303 }
@@ -492,18 +310,17 @@ static void find(CBS cbs, void *block, BT alloc, Size size, Bool high,
492 Bool expected, found; 310 Bool expected, found;
493 Index expectedBase, expectedLimit; 311 Index expectedBase, expectedLimit;
494 Addr foundBase, foundLimit, remainderBase, remainderLimit; 312 Addr foundBase, foundLimit, remainderBase, remainderLimit;
313 Addr oldBase, oldLimit, origBase, origLimit;
495 Size oldSize, newSize; 314 Size oldSize, newSize;
496 315
497 checkExpectations();
498
499 expected = (high ? BTFindLongResRangeHigh : BTFindLongResRange) 316 expected = (high ? BTFindLongResRangeHigh : BTFindLongResRange)
500 (&expectedBase, &expectedLimit, alloc, 317 (&expectedBase, &expectedLimit, alloc,
501 (Index)0, (Index)ArraySize, (Count)size); 318 (Index)0, (Index)ArraySize, (Count)size);
502 319
503 if (expected) { 320 if (expected) {
504 oldSize = (expectedLimit - expectedBase) * Alignment; 321 oldSize = (expectedLimit - expectedBase) * Alignment;
505 remainderBase = addrOfIndex(block, expectedBase); 322 remainderBase = origBase = addrOfIndex(block, expectedBase);
506 remainderLimit = addrOfIndex(block, expectedLimit); 323 remainderLimit = origLimit = addrOfIndex(block, expectedLimit);
507 324
508 switch(findDelete) { 325 switch(findDelete) {
509 case CBSFindDeleteNONE: { 326 case CBSFindDeleteNONE: {
@@ -524,32 +341,24 @@ static void find(CBS cbs, void *block, BT alloc, Size size, Bool high,
524 341
525 if (findDelete != CBSFindDeleteNONE) { 342 if (findDelete != CBSFindDeleteNONE) {
526 newSize = AddrOffset(remainderBase, remainderLimit); 343 newSize = AddrOffset(remainderBase, remainderLimit);
527
528 if (oldSize >= MinSize) {
529 if (newSize == 0)
530 expectCallback(&CallbackDelete, oldSize, (Addr)0, (Addr)0);
531 else if (newSize < MinSize)
532 expectCallback(&CallbackDelete, oldSize,
533 remainderBase, remainderLimit);
534 else
535 expectCallback(&CallbackShrink, oldSize,
536 remainderBase, remainderLimit);
537 }
538 } 344 }
539 } 345 }
540 346
541 found = (high ? CBSFindLast : CBSFindFirst) 347 found = (high ? CBSFindLast : CBSFindFirst)
542 (&foundBase, &foundLimit, cbs, size * Alignment, findDelete); 348 (&foundBase, &foundLimit, &oldBase, &oldLimit,
349 cbs, size * Alignment, findDelete);
543 350
544 Insist(found == expected); 351 Insist(found == expected);
545 352
546 if (found) { 353 if (found) {
547 Insist(expectedBase == indexOfAddr(block, foundBase)); 354 Insist(expectedBase == indexOfAddr(block, foundBase));
548 Insist(expectedLimit == indexOfAddr(block, foundLimit)); 355 Insist(expectedLimit == indexOfAddr(block, foundLimit));
549 checkExpectations();
550 356
551 if (findDelete != CBSFindDeleteNONE) 357 if (findDelete != CBSFindDeleteNONE) {
358 Insist(oldBase == origBase);
359 Insist(oldLimit == origLimit);
552 BTSetRange(alloc, expectedBase, expectedLimit); 360 BTSetRange(alloc, expectedBase, expectedLimit);
361 }
553 } 362 }
554 363
555 return; 364 return;
@@ -576,10 +385,7 @@ extern int main(int argc, char *argv[])
576 randomize(argc, argv); 385 randomize(argc, argv);
577 386
578 NAllocateTried = NAllocateSucceeded = NDeallocateTried = 387 NAllocateTried = NAllocateSucceeded = NDeallocateTried =
579 NDeallocateSucceeded = NNewBlocks = NDeleteBlocks = 388 NDeallocateSucceeded = 0;
580 NGrowBlocks = NShrinkBlocks = 0;
581
582 clearExpectations();
583 389
584 die(mps_arena_create(&mpsArena, mps_arena_class_vm(), testArenaSIZE), 390 die(mps_arena_create(&mpsArena, mps_arena_class_vm(), testArenaSIZE),
585 "mps_arena_create"); 391 "mps_arena_create");
@@ -588,10 +394,7 @@ extern int main(int argc, char *argv[])
588 die((mps_res_t)BTCreate(&allocTable, arena, ArraySize), 394 die((mps_res_t)BTCreate(&allocTable, arena, ArraySize),
589 "failed to create alloc table"); 395 "failed to create alloc table");
590 396
591 die((mps_res_t)CBSInit(arena, &cbsStruct, NULL, &cbsNewCallback, 397 die((mps_res_t)CBSInit(arena, &cbsStruct, NULL, Alignment, TRUE),
592 &cbsDeleteCallback, &cbsGrowCallback,
593 &cbsShrinkCallback, MinSize,
594 Alignment, TRUE),
595 "failed to initialise CBS"); 398 "failed to initialise CBS");
596 cbs = &cbsStruct; 399 cbs = &cbsStruct;
597 400
@@ -636,8 +439,6 @@ extern int main(int argc, char *argv[])
636 checkCBS(cbs, allocTable, dummyBlock); 439 checkCBS(cbs, allocTable, dummyBlock);
637 } 440 }
638 441
639 checkExpectations();
640
641 /* CBSDescribe prints a very long line. */ 442 /* CBSDescribe prints a very long line. */
642 /* CBSDescribe(cbs, mps_lib_get_stdout()); */ 443 /* CBSDescribe(cbs, mps_lib_get_stdout()); */
643 444
@@ -645,10 +446,6 @@ extern int main(int argc, char *argv[])
645 printf("Number of allocations succeeded: %ld\n", NAllocateSucceeded); 446 printf("Number of allocations succeeded: %ld\n", NAllocateSucceeded);
646 printf("Number of deallocations attempted: %ld\n", NDeallocateTried); 447 printf("Number of deallocations attempted: %ld\n", NDeallocateTried);
647 printf("Number of deallocations succeeded: %ld\n", NDeallocateSucceeded); 448 printf("Number of deallocations succeeded: %ld\n", NDeallocateSucceeded);
648 printf("Number of new large blocks: %ld\n", NNewBlocks);
649 printf("Number of deleted large blocks: %ld\n", NDeleteBlocks);
650 printf("Number of grown large blocks: %ld\n", NGrowBlocks);
651 printf("Number of shrunk large blocks: %ld\n", NShrinkBlocks);
652 printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); 449 printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);
653 return 0; 450 return 0;
654} 451}