Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
5.9 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999.
  5. //
  6. // File: tmem.cxx
  7. //
  8. // Contents: tmem - test mem allocators for big tables.
  9. //
  10. //--------------------------------------------------------------------------
  11. #include "pch.cxx"
  12. #pragma hdrstop
  13. DECLARE_INFOLEVEL(tb)
  14. #include "tblalloc.hxx"
  15. BYTE MemPool[4096];
  16. //BYTE* PoolPtrs[409];
  17. //ULONG PoolOffs[409];
  18. BOOL fInMemPool = TRUE;
  19. //
  20. // ReportHeap - report heap blocks
  21. //
  22. void ReportHeap(
  23. void* pBlock,
  24. USHORT cbSize,
  25. USHORT fFree
  26. ) {
  27. BYTE* pbBlock = (BYTE*) pBlock;
  28. printf("%08x %d%s\n", pbBlock, cbSize, fFree? " FREE": "");
  29. if (fInMemPool &&
  30. (pbBlock < &MemPool[0] ||
  31. pbBlock + cbSize > &MemPool[ sizeof MemPool ])) {
  32. printf("\007***\tpBlock outside mem pool\t***\007");
  33. }
  34. }
  35. //
  36. // FreeBlocks -- free some of the allocated blocks
  37. //
  38. void FreeBlocks(
  39. BYTE* apbPtrs[],
  40. unsigned cPtrs,
  41. int fVerbose,
  42. CWindowDataAllocator& Alloc
  43. ) {
  44. unsigned i;
  45. // Free every third allocated block
  46. for (i = 2; i < cPtrs; i += 3) {
  47. if (apbPtrs[i]) {
  48. Alloc.Free((void*)apbPtrs[i]);
  49. apbPtrs[i] = 0;
  50. }
  51. }
  52. if (fVerbose) {
  53. printf("\nAfter freeing every third allocation\n");
  54. Alloc.WalkHeap(ReportHeap);
  55. }
  56. // Free every other allocated block, will cause some coalescing
  57. for (i = 0; i < cPtrs; i += 2) {
  58. if (apbPtrs[i]) {
  59. Alloc.Free((void*)apbPtrs[i]);
  60. apbPtrs[i] = 0;
  61. }
  62. }
  63. if (fVerbose) {
  64. printf("\nAfter freeing every other allocation\n");
  65. Alloc.WalkHeap(ReportHeap);
  66. }
  67. // Finally, Free every fourth allocated block, will cause more coalescing
  68. for (i = 3; i < cPtrs; i += 4) {
  69. if (apbPtrs[i]) {
  70. Alloc.Free((void*)apbPtrs[i]);
  71. apbPtrs[i] = 0;
  72. }
  73. }
  74. if (fVerbose) {
  75. printf("\nAfter freeing every other allocation\n");
  76. Alloc.WalkHeap(ReportHeap);
  77. }
  78. }
  79. __cdecl main(int argc, char** argv)
  80. {
  81. BYTE* pMem = MemPool;
  82. int fVerbose = 0;
  83. unsigned i;
  84. for (i=1; i<(unsigned)argc; i++) {
  85. if (argv[i][0] == '-' &&
  86. tolower(argv[i][1]) == 'v')
  87. fVerbose++;
  88. else {
  89. printf("Usage: %s [-v]\n", argv[0]);
  90. }
  91. }
  92. // Test the simple allocator with forward allocation.
  93. memset(pMem, 0xD5, sizeof MemPool);
  94. CVarBufferAllocator Alloc1(pMem, sizeof MemPool);
  95. BYTE* pbuf;
  96. BOOL fBreak = FALSE;
  97. for (i=0; i<0xFFFFFFFF && !fBreak; i++)
  98. {
  99. TRY
  100. {
  101. pbuf = 0;
  102. pbuf = (BYTE *)Alloc1.Allocate(10);
  103. }
  104. CATCH (CException, e)
  105. {
  106. if (e.GetErrorCode() == E_OUTOFMEMORY)
  107. fBreak = TRUE;
  108. else
  109. RETHROW();
  110. }
  111. END_CATCH
  112. if (pbuf)
  113. memset(pbuf, '0' + i%10, 10);
  114. }
  115. Win4Assert(i == sizeof MemPool/10);
  116. for (i=0; i<sizeof MemPool - (sizeof MemPool % 10); i++) {
  117. Win4Assert(MemPool[i] == ((i/10) % 10 + '0'));
  118. }
  119. #if 0
  120. // Test the simple allocator with top-down allocation.
  121. memset(pMem, 0xD5, sizeof MemPool);
  122. CVarBufferAllocator Alloc2(pMem, sizeof MemPool, TRUE);
  123. for (i=0; pbuf = (BYTE *)Alloc2.Allocate(10); i++) {
  124. memset(pbuf, '0' + i%10, 10);
  125. }
  126. Win4Assert(i == sizeof MemPool/10);
  127. for (i=0; i<sizeof MemPool; i++) {
  128. if (i < (sizeof MemPool % 10)) {
  129. Win4Assert(MemPool[i] == 0xD5);
  130. } else {
  131. Win4Assert(MemPool[i] ==
  132. ((((sizeof MemPool - 1) - i)/10) % 10 + '0'));
  133. }
  134. }
  135. #endif //0
  136. // Test the heap allocator
  137. memset(pMem, 0, sizeof MemPool);
  138. BYTE **paPoolPtrs = (BYTE**)&MemPool;
  139. unsigned cPoolPtrs = sizeof MemPool / sizeof (BYTE *);
  140. CWindowDataAllocator Alloc3;
  141. fInMemPool = FALSE;
  142. for (i=0; pbuf = (BYTE *)Alloc3.Allocate(10); i++) {
  143. if (i == cPoolPtrs)
  144. break;
  145. paPoolPtrs[i] = pbuf;
  146. memset(pbuf, '0' + i%10, 10);
  147. }
  148. Win4Assert(i == cPoolPtrs);
  149. for (i=0; i<sizeof MemPool; i++) {
  150. Win4Assert(paPoolPtrs[i/10][i%10] == ((i/10) % 10 + '0'));
  151. }
  152. if (fVerbose) {
  153. printf("Grow forward allocation\n");
  154. Alloc3.WalkHeap(ReportHeap);
  155. }
  156. FreeBlocks(paPoolPtrs, cPoolPtrs, fVerbose, Alloc3);
  157. // Test the fixed/variable allocator
  158. memset(pMem, 0, sizeof MemPool);
  159. Win4Assert(sizeof (BYTE*) == sizeof (ULONG));
  160. paPoolPtrs = (BYTE **)&MemPool;
  161. cPoolPtrs = (sizeof MemPool / sizeof (BYTE *)) / 2;
  162. ULONG *paPoolOffs = (ULONG *)&paPoolPtrs[cPoolPtrs];
  163. memset(paPoolPtrs, 0, sizeof (BYTE *) * cPoolPtrs);
  164. memset(paPoolOffs, 0, sizeof (BYTE *) * cPoolPtrs);
  165. CFixedVarAllocator Alloc4(TRUE, TRUE, 10);
  166. // for (i=0; i<sizeof MemPool; i++) {
  167. // Alloc4.SetLimit(i);
  168. // Win4Assert(Alloc4.Limit() == i);
  169. // }
  170. //
  171. // Alloc4.SetLimit(1000);
  172. for (i=0; (pbuf = (BYTE *)Alloc4.Allocate(10)) && i < cPoolPtrs; i++) {
  173. memset(pbuf, '0' + i%10, 10);
  174. paPoolOffs[i] = Alloc4.PointerToOffset(pbuf);
  175. pbuf = (BYTE*)Alloc4.AllocFixed();
  176. memset(pbuf, '9' - i%10, 10);
  177. }
  178. Win4Assert(i == cPoolPtrs);
  179. CWindowDataAllocator* pVAlloc = Alloc4.VarAllocator();
  180. if (fVerbose && pVAlloc) {
  181. printf("\nFixed/Var allocation\n");
  182. pVAlloc->WalkHeap(ReportHeap);
  183. }
  184. if (pVAlloc) {
  185. for (i=0; i<cPoolPtrs; i++) {
  186. if (paPoolOffs[i]) {
  187. paPoolPtrs[i] = (BYTE*)Alloc4.OffsetToPointer(paPoolOffs[i]);
  188. }
  189. }
  190. FreeBlocks(paPoolPtrs, cPoolPtrs, fVerbose, *pVAlloc);
  191. }
  192. // Test the fixed/variable allocator
  193. memset(pMem, 0, sizeof MemPool);
  194. Win4Assert(sizeof (BYTE*) == sizeof (ULONG));
  195. paPoolPtrs = (BYTE **)&MemPool;
  196. cPoolPtrs = (sizeof MemPool / sizeof (BYTE *));
  197. memset(paPoolPtrs, 0, sizeof (BYTE *) * cPoolPtrs);
  198. CFixedVarAllocator Alloc5(TRUE, TRUE, 0x28);
  199. for (i=0; (pbuf = (BYTE *)Alloc5.AllocFixed()) && i < cPoolPtrs; i++) {
  200. memset(pbuf, '0' + i%10, 0x28);
  201. }
  202. Win4Assert(i == cPoolPtrs);
  203. for (i=0; i<cPoolPtrs; i++) {
  204. if (paPoolOffs[i]) {
  205. paPoolPtrs[i] = (BYTE*)Alloc5.OffsetToPointer(paPoolOffs[i]);
  206. }
  207. }
  208. return 0;
  209. }