POOLMEM.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. #include "poolmem.h"
  2.  
  3. // Tree Memory Allocation structure.
  4. typedef struct _POOLMEMORYBLOCK POOLMEMORYBLOCK, *PPOOLMEMORYBLOCK;
  5. struct _POOLMEMORYBLOCK {
  6.     DWORD                 Index;
  7.     DWORD                 Size;
  8.     PPOOLMEMORYBLOCK      NextBlock;
  9.     PPOOLMEMORYBLOCK      PrevBlock;
  10.     PBYTE                 RawMemory;  
  11. };
  12. typedef struct _POOLHEADER {
  13.     PPOOLMEMORYBLOCK PoolHead;
  14.     HANDLE           Heap;
  15. } POOLHEADER, *PPOOLHEADER;
  16. BOOL
  17. PoolMemAddMemory (
  18.     IN  POOLHANDLE  Handle,
  19.     IN  DWORD       Size
  20.     )
  21. {
  22.     PBYTE               allocedMemory;
  23.     PPOOLMEMORYBLOCK    newBlock;
  24.     PPOOLHEADER         poolHeader = (PPOOLHEADER) Handle;
  25.     DWORD               sizeNeeded;
  26.     assert(poolHeader != NULL);
  27.     //
  28.     // Determine size needed and attempt to allocate memory.
  29.     //
  30.     if (Size + sizeof(POOLMEMORYBLOCK) > POOLMEMORYBLOCKSIZE) {
  31.         sizeNeeded = Size + sizeof(POOLMEMORYBLOCK);
  32.     }
  33.     else {
  34.         sizeNeeded = POOLMEMORYBLOCKSIZE;
  35.     }
  36.     allocedMemory = HeapAlloc(poolHeader -> Heap,0,sizeNeeded);
  37.     if (allocedMemory) {
  38.         //
  39.         // Use the beginning of the alloc'ed block as the poolblock structure.
  40.         //
  41.         newBlock                = (PPOOLMEMORYBLOCK) allocedMemory;
  42.         newBlock -> Size        = sizeNeeded - sizeof(POOLMEMORYBLOCK);
  43.         newBlock -> RawMemory   = allocedMemory + sizeof(POOLMEMORYBLOCK);
  44.         newBlock -> Index       = 0;
  45.     
  46.         //
  47.         // Link the block into the list.
  48.         //
  49.         if (poolHeader -> PoolHead) {
  50.             poolHeader -> PoolHead -> PrevBlock = newBlock;
  51.         }
  52.         newBlock   -> NextBlock   = poolHeader -> PoolHead;
  53.         newBlock   -> PrevBlock   = NULL;
  54.         poolHeader -> PoolHead    = newBlock;
  55.     }
  56.     //
  57.     // Assuming allocedMemory is non-NULL, we have succeeded.
  58.     //
  59.     return allocedMemory != NULL;
  60. }
  61. POOLHANDLE
  62. WINAPI
  63. PoolMemInitPool (
  64.     )
  65. {
  66.     BOOL        ableToAddMemory;
  67.     PPOOLHEADER header = NULL;
  68.     HANDLE      procHeap;
  69.     procHeap = GetProcessHeap();
  70.     //
  71.     // Allocate the header of this pool.
  72.     //
  73.     header = HeapAlloc(procHeap,0,sizeof(POOLHEADER));
  74.     if (header) {
  75.         //
  76.         // Allocation was successful. Now, initialize the pool.
  77.         //
  78.         header -> PoolHead = NULL;
  79.         header -> Heap = procHeap;
  80.         //
  81.         // Actually add some memory to the pool.
  82.         //
  83.         ableToAddMemory = PoolMemAddMemory(header,0);
  84.         if (!ableToAddMemory) {
  85.             //
  86.             // Unable to add memory to the pool.
  87.             //
  88.             HeapFree(header -> Heap,0,header);
  89.             header = NULL;
  90.         }
  91.     }
  92.     return (POOLHANDLE) header;
  93. }
  94. VOID
  95. WINAPI
  96. PoolMemDestroyPool (
  97.     POOLHANDLE Handle
  98.     )
  99. {
  100.     PPOOLMEMORYBLOCK nextBlock;
  101.     PPOOLMEMORYBLOCK blockToFree; 
  102.     PPOOLHEADER      poolHeader;
  103.     assert(Handle != NULL);
  104.     poolHeader = (PPOOLHEADER) Handle;
  105.     //
  106.     // Walk the list, freeing as we go.
  107.     //
  108.     blockToFree = poolHeader ->  PoolHead;
  109.     while (blockToFree != NULL) {
  110.     
  111.         nextBlock = blockToFree->NextBlock;
  112.         HeapFree(poolHeader -> Heap,0,blockToFree);
  113.         blockToFree = nextBlock;
  114.     }
  115.     //
  116.     // Also, deallocate the poolheader itself.
  117.     //
  118.     HeapFree(poolHeader -> Heap,0,poolHeader);
  119. }
  120. PVOID
  121. WINAPI
  122. PoolMemGetAlignedMemory (
  123.     IN POOLHANDLE Handle,
  124.     IN DWORD      Size,
  125.     IN DWORD      AlignSize
  126.     )
  127. {
  128.     BOOL                haveEnoughMemory = TRUE;
  129.     PVOID               rMemory          = NULL;
  130.     PPOOLHEADER         poolHeader       = (PPOOLHEADER) Handle;
  131.     PPOOLMEMORYBLOCK    currentBlock;
  132.     DWORD               sizeNeeded;
  133.     DWORD               padLength;
  134.     assert(poolHeader != NULL);
  135.     currentBlock = poolHeader -> PoolHead;
  136.     // Determine if more memory is needed, attempt to add if needed.
  137.     sizeNeeded = Size;
  138.     if (currentBlock -> Size - currentBlock -> Index < sizeNeeded + AlignSize) {
  139.         haveEnoughMemory = PoolMemAddMemory(poolHeader,sizeNeeded + AlignSize);
  140.         currentBlock = poolHeader -> PoolHead;
  141.     }
  142.     // If there is enough memory available, return it.
  143.     if (haveEnoughMemory) {
  144.         if (AlignSize) {
  145.             padLength = (DWORD) currentBlock + sizeof(POOLMEMORYBLOCK) 
  146.                 + currentBlock -> Index;
  147.             currentBlock -> Index += (AlignSize - (padLength % AlignSize)) % AlignSize;
  148.         }
  149.       
  150.          
  151.         //Now, get the address of the memory to return.
  152.         rMemory = (PVOID) 
  153.             &(currentBlock->RawMemory[currentBlock -> Index]);
  154.  
  155.         currentBlock->Index += sizeNeeded;
  156.     }
  157.     return rMemory;
  158. }