kerneltest/e32test/heap/t_heapdl.cpp
changeset 109 b3a1d9898418
child 252 0a40b8675b23
equal deleted inserted replaced
102:ef2a444a7410 109:b3a1d9898418
       
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32test\heap\t_heapdl.cpp
       
    15 // Overview:
       
    16 // Tests RHybridHeap class.
       
    17 // API Information:
       
    18 // RHybridHeap
       
    19 // Details:
       
    20 // 
       
    21 //
       
    22 
       
    23 #include <e32test.h>
       
    24 #include <e32math.h>
       
    25 #include <e32def_private.h>
       
    26 #include "dla.h"
       
    27 #include "slab.h"
       
    28 #include "page_alloc.h"
       
    29 #include "heap_hybrid.h"
       
    30 
       
    31 const TInt KHeadSize = (TInt)RHeap::EAllocCellSize;
       
    32 
       
    33 class TestHybridHeap
       
    34   {
       
    35 public:
       
    36   static void TopSize(TInt& aTopSize, const RHybridHeap * aHybridHeap);
       
    37   static void DvSize(TInt& aDvSize, const RHybridHeap * aHybridHeap);
       
    38   static void SmallMap(TUint& aSmallMap, const RHybridHeap * aHybridHeap);
       
    39   static void TreeMap(TUint& aTreeMap, const RHybridHeap * aHybridHeap);
       
    40   static void TrimCheck(TInt& aTrimCheck, const RHybridHeap * aHybridHeap);
       
    41   static void GrowBy(TInt& aGrowBy, const RHybridHeap * aHybridHeap);
       
    42   static void PageSize(TInt& aPageSize, const RHybridHeap * aHybridHeap);
       
    43   };
       
    44 
       
    45 
       
    46 void TestHybridHeap::TopSize(TInt& aTopSize, const RHybridHeap * aHybridHeap)
       
    47   {
       
    48   aTopSize = aHybridHeap->iGlobalMallocState.iTopSize;
       
    49   }
       
    50 
       
    51 
       
    52 void TestHybridHeap::DvSize(TInt& aDvSize, const RHybridHeap * aHybridHeap)
       
    53   {
       
    54   aDvSize = aHybridHeap->iGlobalMallocState.iDvSize;
       
    55   }
       
    56 
       
    57 
       
    58 void TestHybridHeap::SmallMap(TUint& aSmallMap, const RHybridHeap * aHybridHeap)
       
    59   {
       
    60   aSmallMap = aHybridHeap->iGlobalMallocState.iSmallMap;
       
    61   }
       
    62 
       
    63 
       
    64 void TestHybridHeap::TreeMap(TUint& aTreeMap, const RHybridHeap * aHybridHeap)
       
    65   {
       
    66   aTreeMap = aHybridHeap->iGlobalMallocState.iTreeMap;
       
    67   }
       
    68 
       
    69 
       
    70 void TestHybridHeap::TrimCheck(TInt& aTrimCheck, const RHybridHeap * aHybridHeap)
       
    71   {
       
    72   aTrimCheck = aHybridHeap->iGlobalMallocState.iTrimCheck;
       
    73   }
       
    74 
       
    75 
       
    76 void TestHybridHeap::GrowBy(TInt& aGrowBy, const RHybridHeap * aHybridHeap)
       
    77   {
       
    78   aGrowBy = aHybridHeap->iGrowBy;
       
    79   }
       
    80 
       
    81 void TestHybridHeap::PageSize(TInt& aPageSize, const RHybridHeap * aHybridHeap)
       
    82   {
       
    83   aPageSize = aHybridHeap->iPageSize;
       
    84   }
       
    85 
       
    86 
       
    87 LOCAL_D RTest test(_L("T_HEAPDL"));
       
    88 
       
    89 
       
    90 class TestRHeap
       
    91   {
       
    92 public:
       
    93   void InitTests();
       
    94   void Test1(void);
       
    95   void Test2(void);
       
    96   void Test3(void);
       
    97   void Test4(void);
       
    98   void CloseTests();
       
    99 private:
       
   100   RHybridHeap* iHybridHeap;
       
   101   RHeap *iHeap;
       
   102   };
       
   103 
       
   104 
       
   105 void TestRHeap::InitTests()
       
   106   {
       
   107   // Allocate a chunk heap
       
   108   TPtrC testHeap=_L("TESTHEAP");
       
   109   iHeap=User::ChunkHeap(&testHeap,0x1800,0x16000);
       
   110         
       
   111   RHybridHeap::STestCommand cmd;
       
   112   cmd.iCommand = RHybridHeap::EHeapMetaData;
       
   113   iHeap->DebugFunction(RHeap::EHybridHeap, (TAny*)&cmd );
       
   114   iHybridHeap = (RHybridHeap*) cmd.iData;
       
   115   }
       
   116 
       
   117 
       
   118 void TestRHeap::Test1(void)
       
   119   {
       
   120   //
       
   121   //  Splitting a new cell off 'top' chunk
       
   122   //  Growing and shrinking 'top' chunk
       
   123   //  Coalesceing of adjacent free cells
       
   124   //
       
   125     
       
   126   TInt topSizeBefore, topSizeAfter, allocSize;
       
   127   TInt growBy, pageSize;
       
   128   TestHybridHeap::GrowBy(growBy,iHybridHeap);
       
   129   TestHybridHeap::PageSize(pageSize,iHybridHeap);
       
   130         
       
   131   //Splitting a new cell off 'top' chunk
       
   132   TestHybridHeap::TopSize(topSizeBefore,iHybridHeap);
       
   133   TAny* p1=iHeap->Alloc(0x256);
       
   134   TestHybridHeap::TopSize(topSizeAfter,iHybridHeap);
       
   135   test(topSizeBefore > topSizeAfter);
       
   136   iHeap->Check();
       
   137   iHeap->Free(p1);
       
   138   iHeap->Check();
       
   139     
       
   140   //Growing 'top' chunk
       
   141   test(iHeap!=NULL);
       
   142   TestHybridHeap::TopSize(topSizeBefore,iHybridHeap);
       
   143   p1=iHeap->Alloc(pageSize*2); 
       
   144   test(p1!=NULL);
       
   145   allocSize=iHeap->AllocLen(p1);
       
   146   TestHybridHeap::TopSize(topSizeAfter,iHybridHeap);
       
   147   test(topSizeBefore + growBy == topSizeAfter+allocSize+KHeadSize);
       
   148     
       
   149   //Splitting a new cell off 'top' chunk
       
   150   TAny *p2=iHeap->Alloc(pageSize/8); 
       
   151   test(p2!=NULL);
       
   152   //Splitting a new cell off 'top' chunk
       
   153   TAny *p3=iHeap->Alloc(pageSize/2); 
       
   154   test(p3!=NULL);
       
   155   //Growing 'top' chunk
       
   156   TAny *p4=iHeap->Alloc(pageSize*2); 
       
   157   test(p4!=NULL);
       
   158   //Take allocSize of p4
       
   159   allocSize=iHeap->AllocLen(p4);
       
   160     
       
   161   //Shrinking 'top' chunk
       
   162   TInt trimCheck;
       
   163   TestHybridHeap::TopSize(topSizeBefore,iHybridHeap);
       
   164   iHeap->Free(p4);
       
   165   TestHybridHeap::TopSize(topSizeAfter,iHybridHeap);
       
   166   TestHybridHeap::TrimCheck(trimCheck,iHybridHeap);
       
   167   test(topSizeAfter + trimCheck == topSizeBefore+allocSize+KHeadSize);
       
   168   iHeap->Check();
       
   169   
       
   170   //Insert chunk into treebin
       
   171   TUint treeMap,treeMap2;
       
   172   TestHybridHeap::TreeMap(treeMap,iHybridHeap);
       
   173   test(treeMap==0);
       
   174   iHeap->Free(p2);
       
   175   TestHybridHeap::TreeMap(treeMap,iHybridHeap);
       
   176   test(treeMap>0);
       
   177   iHeap->Check();
       
   178     
       
   179   //Coalesce adjacent free cells and insert chunk into treebin
       
   180   TestHybridHeap::TreeMap(treeMap,iHybridHeap);
       
   181   iHeap->Free(p1);
       
   182   TestHybridHeap::TreeMap(treeMap2,iHybridHeap);
       
   183   test(treeMap < treeMap2);
       
   184   iHeap->Check();
       
   185     
       
   186   //free last allocation
       
   187   iHeap->Free(p3);
       
   188   iHeap->Check();
       
   189   }
       
   190 
       
   191 
       
   192 void TestRHeap::Test2(void)
       
   193   {
       
   194   //
       
   195   // Allocation of exact sized cells from 'small cell' lists (smallbin)
       
   196   // Freeing of exact sized cells back to 'small cell' lists (smallbin)
       
   197   //
       
   198   TInt ArraySize=32;
       
   199   TInt cellSize=0;
       
   200   TInt topSizeBefore, topSizeAfter;
       
   201      
       
   202   TAny** ArrayOfCells;
       
   203   ArrayOfCells= new TAny*[ArraySize];
       
   204   TInt ArrayIndex;
       
   205   // Allocate exact sized small cells 8,16,32,40--->
       
   206   // and put them to the array. They are allocated from TOP chunk
       
   207   for(ArrayIndex=0; ArrayIndex<ArraySize;ArrayIndex++)
       
   208     {
       
   209     TestHybridHeap::TopSize(topSizeBefore,iHybridHeap);
       
   210     cellSize=cellSize+8;
       
   211     ArrayOfCells[ArrayIndex]=iHeap->Alloc(cellSize);
       
   212     TestHybridHeap::TopSize(topSizeAfter,iHybridHeap);
       
   213     test(topSizeBefore > topSizeAfter);
       
   214     }
       
   215   iHeap->Check();
       
   216   
       
   217   TUint smallMap, smallMap2;
       
   218   TInt dvSize, dvSize2;
       
   219   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   220   test(smallMap == 0);
       
   221   // Free some of small cells from the array. So they are inserted
       
   222   // to the smallbin
       
   223   for(ArrayIndex=2; ArrayIndex<ArraySize-1; ArrayIndex+=5)
       
   224     {
       
   225     TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   226     iHeap->Free(ArrayOfCells[ArrayIndex]);
       
   227     TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   228     test(smallMap<smallMap2);
       
   229     }
       
   230   iHeap->Check();
       
   231     
       
   232   // Allocate exact sized cells from smallbin (or Designated Victim)   
       
   233   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   234   TAny* p1=iHeap->Alloc(32);
       
   235   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   236   test(smallMap>smallMap2);
       
   237     
       
   238   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   239   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   240   TAny* p2=iHeap->Alloc(32);
       
   241   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   242   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   243   if(dvSize <= dvSize2)
       
   244     test(smallMap>smallMap2);
       
   245     
       
   246   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   247   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   248   TAny* p3=iHeap->Alloc(32);
       
   249   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   250   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   251   if(dvSize <= dvSize2)
       
   252   	test(smallMap>smallMap2);
       
   253    
       
   254   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   255   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   256   TAny* p4=iHeap->Alloc(32);
       
   257   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   258   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   259   if(dvSize <= dvSize2)
       
   260     test(smallMap>smallMap2);
       
   261    
       
   262   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   263   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   264   TAny* p5=iHeap->Alloc(48);
       
   265   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   266   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   267   if(dvSize <= dvSize2)
       
   268     test(smallMap>smallMap2);
       
   269     
       
   270   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   271   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   272   TAny* p6=iHeap->Alloc(64);
       
   273   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   274   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   275   if(dvSize <= dvSize2)
       
   276     test(smallMap>smallMap2);
       
   277    
       
   278   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   279   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   280   TAny* p7=iHeap->Alloc(80);
       
   281   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   282   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   283   if(dvSize <= dvSize2)
       
   284     test(smallMap>smallMap2);
       
   285    
       
   286   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   287   TestHybridHeap::DvSize(dvSize,iHybridHeap);
       
   288   TAny* p8=iHeap->Alloc(96);
       
   289   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   290   TestHybridHeap::DvSize(dvSize2,iHybridHeap);
       
   291   if(dvSize <= dvSize2)
       
   292     test(smallMap>smallMap2);
       
   293   iHeap->Check();
       
   294   
       
   295   // Freeing of exact sized cells back to smallbin
       
   296   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   297   iHeap->Free(p1);
       
   298   iHeap->Free(p2);
       
   299   iHeap->Free(p3);
       
   300   iHeap->Free(p4);
       
   301   iHeap->Free(p5);
       
   302   iHeap->Free(p6);
       
   303   iHeap->Free(p7);
       
   304   iHeap->Free(p8);
       
   305   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   306   test(smallMap < smallMap2);
       
   307   iHeap->Check();
       
   308   
       
   309   // Now free rest of the array with Reset
       
   310   iHeap->Reset();
       
   311   iHeap->Check();
       
   312   
       
   313   delete [] ArrayOfCells;
       
   314   }
       
   315 
       
   316 
       
   317 void TestRHeap::Test3(void)
       
   318   {
       
   319   //
       
   320   // Allocation of approximate sized cells from 'small cell' lists (smallbin)
       
   321   //
       
   322   TInt ArraySize=32;
       
   323   TInt cellSize=0;
       
   324   TAny** ArrayOfCells;
       
   325   ArrayOfCells= new TAny*[ArraySize];
       
   326   TInt ArrayIndex;
       
   327   TInt topSizeBefore, topSizeAfter;
       
   328     
       
   329   // Allocate small approximate sized cells and put
       
   330   //them to the array. They are allocated from TOP chunk
       
   331   TUint8 randomSize;
       
   332   for(ArrayIndex=0; ArrayIndex<ArraySize;ArrayIndex++)
       
   333     {
       
   334     TestHybridHeap::TopSize(topSizeBefore,iHybridHeap);
       
   335     do
       
   336       {
       
   337       randomSize= (TUint8)Math::Random();
       
   338       }
       
   339     while (randomSize>240);
       
   340        
       
   341   	cellSize=randomSize;
       
   342   	ArrayOfCells[ArrayIndex]=iHeap->Alloc(cellSize);
       
   343   	TestHybridHeap::TopSize(topSizeAfter,iHybridHeap);
       
   344   	test(topSizeBefore > topSizeAfter);
       
   345   	}
       
   346   iHeap->Check();
       
   347   
       
   348   TUint smallMap, smallMap2;
       
   349   // Free some of allocated cells from the array. So they are inserted
       
   350   // to the smallbin
       
   351   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   352   for(ArrayIndex=2; ArrayIndex<ArraySize-1; ArrayIndex+=5)
       
   353     {
       
   354     iHeap->Free(ArrayOfCells[ArrayIndex]);
       
   355     }
       
   356   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   357   test(smallMap<=smallMap2);
       
   358   iHeap->Check();
       
   359   
       
   360   // Allocate approximate sized cells from smallbin
       
   361   TInt ArraySize2=6;
       
   362   TInt cellSize2=0;    
       
   363   TAny** ArrayOfCells2;
       
   364   ArrayOfCells2= new TAny*[ArraySize2];
       
   365   TInt ArrayIndex2;
       
   366   TestHybridHeap::SmallMap(smallMap,iHybridHeap);
       
   367   for(ArrayIndex2=0; ArrayIndex2<ArraySize2;ArrayIndex2++)
       
   368     {
       
   369     TUint8 randomSize2 = (TUint8)Math::Random();
       
   370     cellSize2=(randomSize2);
       
   371     ArrayOfCells2[ArrayIndex2]=iHeap->Alloc(cellSize2);
       
   372     }
       
   373   TestHybridHeap::SmallMap(smallMap2,iHybridHeap);
       
   374   test(smallMap>=smallMap2);              
       
   375   iHeap->Check();
       
   376   
       
   377   // Freeing of approximate sized cells back to smallbin
       
   378   for(ArrayIndex2=0; ArrayIndex2<ArraySize2-1; ArrayIndex2+=1)
       
   379     {
       
   380     iHeap->Free(ArrayOfCells2[ArrayIndex2]);
       
   381     }
       
   382   iHeap->Check();
       
   383   
       
   384   // Now free rest of the array with Reset
       
   385   iHeap->Reset();
       
   386   iHeap->Check();
       
   387   
       
   388   delete [] ArrayOfCells;
       
   389   delete [] ArrayOfCells2; 
       
   390   }
       
   391 
       
   392 
       
   393 void TestRHeap::Test4(void)
       
   394   {
       
   395   //
       
   396   // Allocation of approximate sized cells from digital trees (treebin) and splitting
       
   397   // Freeing of approximate sized cells back to digital trees (treebin)
       
   398   //
       
   399   TInt ArraySize=32;
       
   400   TInt cellSize=0;
       
   401   TAny** ArrayOfCells;
       
   402   ArrayOfCells= new TAny*[ArraySize];
       
   403   TInt ArrayIndex;
       
   404         
       
   405   // Allocate approximate sized cells bigger than 256
       
   406   // and put them to the array. They are allocated from TOP chunk
       
   407   for(ArrayIndex=0; ArrayIndex<ArraySize;ArrayIndex++)
       
   408     {
       
   409     TUint8 randomSize = (TUint8)Math::Random();
       
   410     cellSize=(randomSize+256);
       
   411     ArrayOfCells[ArrayIndex]=iHeap->Alloc(cellSize);
       
   412     }
       
   413   iHeap->Check();
       
   414   
       
   415   TUint treeMap,treeMap2;    
       
   416   // Free some of allocated cells from the array. So they are inserted
       
   417   // to the treebin
       
   418   for(ArrayIndex=2; ArrayIndex<ArraySize-1; ArrayIndex+=5)
       
   419     {
       
   420     TestHybridHeap::TreeMap(treeMap,iHybridHeap);
       
   421     iHeap->Free(ArrayOfCells[ArrayIndex]);
       
   422     TestHybridHeap::TreeMap(treeMap2,iHybridHeap);
       
   423     test(treeMap <= treeMap2);
       
   424     }
       
   425   iHeap->Check();
       
   426   
       
   427   // Allocate approximate sized cells from treebin
       
   428   TInt ArraySize2=16;
       
   429   TInt cellSize2=0;    
       
   430   TAny** ArrayOfCells2;
       
   431   ArrayOfCells2= new TAny*[ArraySize2];
       
   432   TInt ArrayIndex2;
       
   433   for(ArrayIndex2=0; ArrayIndex2<ArraySize2;ArrayIndex2++)
       
   434     {
       
   435     TestHybridHeap::TreeMap(treeMap,iHybridHeap);
       
   436     TUint8 randomSize2 = (TUint8)Math::Random();
       
   437     cellSize2=(randomSize2+256);
       
   438     ArrayOfCells2[ArrayIndex2]=iHeap->Alloc(cellSize2);
       
   439     TestHybridHeap::TreeMap(treeMap2,iHybridHeap);
       
   440     test(treeMap >= treeMap2);
       
   441     }
       
   442   iHeap->Check();
       
   443   
       
   444   // Freeing of approximate sized cells back to treebin
       
   445   TestHybridHeap::TreeMap(treeMap,iHybridHeap);
       
   446   for(ArrayIndex2=0; ArrayIndex2<ArraySize2-1; ArrayIndex2+=1)
       
   447     {
       
   448     iHeap->Free(ArrayOfCells2[ArrayIndex2]);
       
   449     }
       
   450   TestHybridHeap::TreeMap(treeMap2,iHybridHeap);
       
   451   test(treeMap <= treeMap2);
       
   452   iHeap->Check();
       
   453     
       
   454   // Now free rest of the array with Reset
       
   455   iHeap->Reset();
       
   456   iHeap->Check();
       
   457     
       
   458   delete [] ArrayOfCells;
       
   459   delete [] ArrayOfCells2; 
       
   460   }
       
   461 
       
   462 
       
   463 void TestRHeap::CloseTests()
       
   464   {
       
   465   // close heap so we don't exceed chunk limit
       
   466   iHeap->Close();  
       
   467   }
       
   468 
       
   469 
       
   470 GLDEF_C TInt E32Main(void)
       
   471   {
       
   472   test.Title();
       
   473 
       
   474   __KHEAP_MARK;
       
   475 
       
   476   TestRHeap T;
       
   477   test.Start(_L("Init DL allocator tests"));
       
   478   T.InitTests();
       
   479   test.Next(_L("Test DL allocator 1"));
       
   480   T.Test1();
       
   481   test.Next(_L("Test DL allocator 2"));
       
   482   T.Test2();
       
   483   test.Next(_L("Test DL allocator 3"));
       
   484   T.Test3();
       
   485   test.Next(_L("Test DL allocator 4"));
       
   486   T.Test4();
       
   487   test.Next(_L("Close DL allocator tests"));
       
   488   T.CloseTests();
       
   489 	
       
   490   __KHEAP_CHECK(0);
       
   491   __KHEAP_MARKEND;
       
   492 
       
   493   test.End();
       
   494   return(0);
       
   495   }