home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / winnt / mpheap / tmpheap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  6.0 KB  |  225 lines

  1. /*++
  2.  
  3. Copyright (c) 1992  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     tmpheap.c
  8.  
  9. Abstract:
  10.  
  11.     Test program for the MP heap package.
  12.  
  13. Author:
  14.  
  15.     John Vert (jvert) 10-Jul-1995
  16.  
  17. Revision History:
  18.  
  19. --*/
  20. #include "windows.h"
  21. #include "stdio.h"
  22. #include "string.h"
  23. #include "stdlib.h"
  24. #include "mpheap.h"
  25.  
  26. DWORD
  27. WINAPI
  28. ThreadStartup(
  29.     LPVOID Parameter
  30.     );
  31.  
  32. LPVOID Malloc(DWORD dwBytes);
  33. VOID Free(LPVOID lpMem);
  34.  
  35. BOOL Suicide = FALSE;
  36.  
  37. HANDLE MpHeap;
  38.  
  39. LPVOID
  40. Malloc(
  41.     DWORD dwBytes
  42.     )
  43. {
  44.     return(MpHeapAlloc(MpHeap,0,dwBytes));
  45. }
  46.  
  47. VOID
  48. Free(
  49.     LPVOID lpMem
  50.     )
  51. {
  52.     MpHeapFree(MpHeap,lpMem);
  53. }
  54.  
  55. // int
  56. // _CRTAPI1
  57. main (argc, argv)
  58.     int argc;
  59.     char *argv[];
  60. {
  61.     ULONG NumThreads;
  62.     ULONG i;
  63.     HANDLE *h;
  64.     DWORD ThreadId;
  65.     DWORD Parallelism;
  66.     DWORD Seconds;
  67.     LPMPHEAP_STATISTICS HeapStats;
  68.     DWORD StatSize;
  69.     DWORD Error;
  70.  
  71.     if (argc != 4) {
  72.         fprintf(stderr, "Usage: tmpheap NumThreads HeapParallelism Seconds\n");
  73.         exit(1);
  74.     }
  75.     NumThreads = atoi(argv[1]);
  76.     Parallelism = atoi(argv[2]);
  77.     Seconds = atoi(argv[3]);
  78.  
  79.     MpHeap = MpHeapCreate(0, 0, Parallelism);
  80.     if (MpHeap == NULL) {
  81.         fprintf(stderr, "MpHeapCreate failed error %d\n",GetLastError);
  82.         exit(1);
  83.     }
  84.     h = Malloc(NumThreads * sizeof(HANDLE));
  85.     if (h==NULL) {
  86.         fprintf(stderr, "Malloc thread handle array failed\n");
  87.         exit(1);
  88.     }
  89.     for (i=0; i<NumThreads; i++) {
  90.         h[i] = CreateThread(NULL,
  91.                             0,
  92.                             ThreadStartup,
  93.                             NULL,
  94.                             0,
  95.                             &ThreadId);
  96.         if (h==NULL) {
  97.             fprintf(stderr, "CreateThread %d failed %d\n",i,GetLastError());
  98.             exit(1);
  99.         }
  100.     }
  101.  
  102.     Sleep(Seconds * 1000);
  103.     Suicide = TRUE;
  104.     WaitForMultipleObjects(NumThreads, h, TRUE, INFINITE);
  105.     StatSize = Parallelism * sizeof(MPHEAP_STATISTICS);
  106.     HeapStats = (LPMPHEAP_STATISTICS)LocalAlloc(LMEM_FIXED, StatSize);
  107.     if (HeapStats != NULL) {
  108.         Error = MpHeapGetStatistics(MpHeap,&StatSize, HeapStats);
  109.         if (Error==ERROR_SUCCESS) {
  110.             for (i=0; i<StatSize/sizeof(MPHEAP_STATISTICS);i++) {
  111.                 printf("HEAP %d\n",i);
  112.                 printf("  Allocations:      %8d\n",HeapStats[i].TotalAllocates);
  113.                 if (0 == HeapStats[i].TotalAllocates) continue;  // avoid divide by 0
  114.                 printf("  Contention :      %8d (%d%%)\n",HeapStats[i].Contention,
  115.                         100*HeapStats[i].Contention/HeapStats[i].TotalAllocates);
  116.                 printf("  Lookaside Allocs: %8d (%d%%)\n",
  117.                         HeapStats[i].LookasideAllocates,
  118.                         100*HeapStats[i].LookasideAllocates/HeapStats[i].TotalAllocates);
  119.                 printf("  Frees:            %8d\n",HeapStats[i].TotalFrees);
  120.                 printf("  Lookaside Frees:  %8d (%d%%)\n",
  121.                         HeapStats[i].LookasideFrees,
  122.                         100*HeapStats[i].LookasideFrees/HeapStats[i].TotalFrees);
  123.                 printf("  Delayed Frees:    %8d (%d%%)\n",
  124.                         HeapStats[i].DelayedFrees,
  125.                         100*HeapStats[i].DelayedFrees/HeapStats[i].TotalFrees);
  126.             }
  127.         } else {
  128.             fprintf(stderr, "MpHeapStatistics failed with error %d\n",Error);
  129.         }
  130.         MpHeapDestroy(MpHeap);
  131.         LocalFree(HeapStats);
  132.     }
  133.  
  134.     return(0);
  135. }
  136.  
  137. DWORD
  138. WINAPI
  139. ThreadStartup(
  140.     LPVOID Parameter
  141.     )
  142. {
  143.     DWORD Seed = GetCurrentThreadId();
  144.     PULONG Buffer = NULL;
  145.     DWORD BufferSize;
  146.     DWORD Delay;
  147.     DWORD i,j;
  148.     DWORD Fill;
  149.     PULONG Last = NULL;
  150.     BOOL AllocAgain;
  151.     DWORD MaxSize=0;
  152.     DWORD CurrentSize=0;
  153.     DWORD CurrentAllocs = 0;
  154.     DWORD MaxAllocs = 0;
  155.  
  156.     //
  157.     // Loop allocating/filling/freeing random chunks
  158.     // of memory.
  159.     //
  160.     Fill = GetCurrentThreadId();
  161.     while (!Suicide) {
  162.         //
  163.         // Decide whether to allocate a new chunk or free the
  164.         // last chunk.
  165.         //
  166.         AllocAgain = (BOOL)((rand() & 0xff) > 0x80);
  167.         if (AllocAgain) {
  168.             BufferSize = (rand() & 0xfff) + sizeof(PUCHAR) + sizeof(ULONG);
  169.  
  170.             CurrentAllocs++;
  171.             if (CurrentAllocs > MaxAllocs) {
  172.                 MaxAllocs = CurrentAllocs;
  173.             }
  174.             Buffer = Malloc(BufferSize);
  175.             if (Buffer == NULL) {
  176.                 fprintf(stderr,"malloc of %d returned NULL\n",BufferSize);
  177.                 return(0);
  178.             }
  179.             CurrentSize += BufferSize;
  180.             if (CurrentSize > MaxSize) {
  181.                 if ((CurrentSize >> 18) != (MaxSize >> 18)) {
  182.                     printf("Thread %x up to %d bytes %d allocs\n",
  183.                             GetCurrentThreadId(),
  184.                             CurrentSize,
  185.                             CurrentAllocs);
  186.                 }
  187.                 MaxSize = CurrentSize;
  188.             }
  189.             if ((CurrentSize > MaxSize) &&
  190.                 (CurrentSize-MaxSize > 0x10000)) {
  191.             }
  192.             for (j=0; j<BufferSize/sizeof(ULONG); j++) {
  193.                 Buffer[j] = Fill;
  194.             }
  195.             Buffer[0] = (ULONG)Last;
  196.             Buffer[1] = BufferSize;
  197.             Last = Buffer;
  198.         } else if (Buffer != NULL) {
  199.             Last = (PULONG)Buffer[0];
  200.             CurrentSize -= Buffer[1];
  201.             --CurrentAllocs;
  202.             Free(Buffer);
  203.             Buffer = Last;
  204.         }
  205.  
  206.         Delay = rand() & 0x1ff;
  207.         for (i=0; i< Delay; i++) {
  208.             Fill = GetCurrentThreadId();
  209.         }
  210.         if ((rand() & 0xffff) < (int)CurrentAllocs) {
  211.             //
  212.             // Magic number, free EVERYTHING!
  213.             //
  214.             while (Buffer != NULL) {
  215.                 Last = (PULONG)Buffer[0];
  216.                 CurrentSize -= Buffer[1];
  217.                 --CurrentAllocs;
  218.                 Free(Buffer);
  219.                 Buffer = Last;
  220.             }
  221.         }
  222.     }
  223.     return(0);
  224. }
  225.