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