alloc.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 11k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. /*  File: FreeStore.cpp
  3.     Description: Declaration for class FreeStore.  This class provides 
  4.         a replacement for global new and delete.  It adds value by 
  5.         recording allocations in DEBUG builds to help find memory leaks.
  6.     Revision History:
  7.     Date        Description                                          Programmer
  8.     --------    ---------------------------------------------------  ----------
  9.     06/12/96    Initial creation.                                    BrianAu
  10. */
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "precomp.hxx" // PCH
  13. #pragma hdrstop
  14. FreeStore g_FreeStore;  // Global heap FreeStore object.
  15. ///////////////////////////////////////////////////////////////////////////////
  16. /*  Function: new
  17.     Description: Replacement for global new.
  18.     Arguments:
  19.         cb - Number of bytes to allocate.
  20.     Returns:
  21.         On success, returns pointer to allocated block.
  22.         Throws OutOfMemory if block can't be allocated.
  23.     Exceptions: OutOfMemory.
  24.     Revision History:
  25.     Date        Description                                          Programmer
  26.     --------    ---------------------------------------------------  ----------
  27.     06/12/96    Initial creation.                                    BrianAu
  28. */
  29. ///////////////////////////////////////////////////////////////////////////////
  30. void * __cdecl 
  31. operator new(
  32.     unsigned int cb
  33.     ) throw(OutOfMemory)
  34. {
  35.     void *pv = g_FreeStore.Alloc(cb);
  36.     DebugMsg(DM_ALLOC, TEXT("new: %6d bytes allocated at 0x%08X"), cb, pv);
  37.     return pv;
  38. }
  39. ///////////////////////////////////////////////////////////////////////////////
  40. /*  Function: delete
  41.     Description: Replacement for global delete.
  42.     Arguments:
  43.         pv - Address of block (previously returned by "new") to deallocate.
  44.     Returns: Nothing.
  45.     Revision History:
  46.     Date        Description                                          Programmer
  47.     --------    ---------------------------------------------------  ----------
  48.     06/12/96    Initial creation.                                    BrianAu
  49. */
  50. ///////////////////////////////////////////////////////////////////////////////
  51. void __cdecl 
  52. operator delete(
  53.     void *pv
  54.     )
  55. {
  56.     DebugMsg(DM_ALLOC, TEXT("delete: block at 0x%08X"), pv);
  57.     g_FreeStore.Free(pv);
  58. }
  59. #ifdef DEBUG_ALLOC
  60. ///////////////////////////////////////////////////////////////////////////////
  61. /*  Function: FreeStore::Stats::~Stats
  62.     Description: Constructor for FreeStore statistics object.
  63.     Arguments: None.
  64.     Returns: Nothing.
  65.     Revision History:
  66.     Date        Description                                          Programmer
  67.     --------    ---------------------------------------------------  ----------
  68.     07/01/96    Initial creation.                                    BrianAu
  69. */
  70. ///////////////////////////////////////////////////////////////////////////////
  71. FreeStore::Stats::Stats(
  72.     VOID
  73.     ) : m_pBlockList(NULL),
  74.         m_cCurrentBlocks(0),
  75.         m_cCummulativeBlocks(0),
  76.         m_cCurrentBytes(0),
  77.         m_cCummulativeBytes(0),
  78.         m_hMutex(NULL)
  79. }
  80. ///////////////////////////////////////////////////////////////////////////////
  81. /*  Function: FreeStore::Stats::~Stats
  82.     Description: Destructor for FreeStore statistics.
  83.     Arguments: None.
  84.     Returns: Nothing.
  85.     Revision History:
  86.     Date        Description                                          Programmer
  87.     --------    ---------------------------------------------------  ----------
  88.     07/01/96    Initial creation.                                    BrianAu
  89. */
  90. ///////////////////////////////////////////////////////////////////////////////
  91. FreeStore::Stats::~Stats(
  92.     VOID
  93.     )
  94. {
  95.     Lock();
  96.     Block *pThis = m_pBlockList;
  97.     while(NULL != pThis)
  98.     {
  99.         m_pBlockList = pThis->m_pNext;
  100. LocalFree(pThis);
  101.         pThis = m_pBlockList;
  102. }
  103.     ReleaseLock();
  104.     if (NULL != m_hMutex)
  105.         CloseHandle(m_hMutex);
  106. }
  107. ///////////////////////////////////////////////////////////////////////////////
  108. /*  Function: FreeStore::Stats::Initialize
  109.     Description: Initializes the FreeStore statistics object.
  110.     Arguments: None.
  111.     Returns:
  112.         NO_ERROR  - Success
  113.         E_FAIL    - Couldn't create mutex.
  114.     Revision History:
  115.     Date        Description                                          Programmer
  116.     --------    ---------------------------------------------------  ----------
  117.     07/01/96    Initial creation.                                    BrianAu
  118. */
  119. ///////////////////////////////////////////////////////////////////////////////
  120. HRESULT
  121. FreeStore::Stats::Initialize(
  122.     VOID
  123.     )
  124. {
  125.     m_hMutex = CreateMutex(NULL, FALSE, NULL);
  126.     return NULL != m_hMutex ? NO_ERROR : E_FAIL;
  127. }
  128.     
  129. ///////////////////////////////////////////////////////////////////////////////
  130. /*  Function: FreeStore::Stats::Add
  131.     Description: Adds a new entry to the FreeStore's statistics pool.
  132.     Arguments:
  133.         pBlock - Address of block allocated.
  134.         cbBlock - Number of bytes in block.
  135.     Returns:
  136.         NO_ERROR      - Success
  137.         E_OUTOFMEMORY - Insufficient memory to allocate stats node.
  138.     Revision History:
  139.     Date        Description                                          Programmer
  140.     --------    ---------------------------------------------------  ----------
  141.     07/01/96    Initial creation.                                    BrianAu
  142. */
  143. ///////////////////////////////////////////////////////////////////////////////
  144. HRESULT 
  145. FreeStore::Stats::Add(
  146.     LPVOID pBlock, 
  147.     DWORD cbBlock
  148.     )
  149. {
  150.     HRESULT hResult = NO_ERROR;
  151.     Lock();
  152.     //
  153.     // Create a new node and insert at head of list.
  154.     //
  155.     Block *pInfo = (Block *)LocalAlloc(LPTR, sizeof(Block));
  156.     if (NULL != pInfo)
  157.     {
  158.         pInfo->m_pBlock  = pBlock;
  159.         pInfo->m_cbBlock = cbBlock;
  160.         pInfo->m_pNext = m_pBlockList;
  161.         m_pBlockList   = pInfo;
  162.         m_cCurrentBlocks++;
  163.         m_cCurrentBytes += cbBlock;
  164.         m_cCummulativeBlocks++;
  165.         m_cCummulativeBytes += cbBlock;
  166.         if (m_cCurrentBlocks > m_cMaxBlocks)
  167.             m_cMaxBlocks = m_cCurrentBlocks;
  168.         if (m_cCurrentBytes > m_cMaxBytes)
  169.             m_cMaxBytes = m_cCurrentBytes;
  170.     }
  171.     else
  172.         hResult = E_OUTOFMEMORY;
  173.     ReleaseLock();
  174.     return hResult;
  175. }
  176. ///////////////////////////////////////////////////////////////////////////////
  177. /*  Function: FreeStore::Stats::Delete
  178.     Description: Remove an entry from the FreeStore's statistics pool.
  179.     Arguments: 
  180.         pBlock - Address of allocated block to remove.
  181.     Returns:
  182.         NO_ERROR    - Success.
  183.         E_FAIL      - pBlock not found.
  184.     Revision History:
  185.     Date        Description                                          Programmer
  186.     --------    ---------------------------------------------------  ----------
  187.     07/01/96    Initial creation.                                    BrianAu
  188. */
  189. ///////////////////////////////////////////////////////////////////////////////
  190. HRESULT 
  191. FreeStore::Stats::Delete(
  192.     LPVOID pBlock
  193.     )
  194. {
  195.     Lock();
  196.     HRESULT hResult = NO_ERROR;
  197.     Block *pThis = m_pBlockList;
  198.     Block *pPrev = NULL;
  199.     while(NULL != pThis && pThis->m_pBlock != pBlock)
  200.     {
  201.         pPrev = pThis;
  202.         pThis = pThis->m_pNext;
  203.     }
  204.     if (NULL != pThis)
  205.     {
  206.         m_cCurrentBlocks--;
  207.         m_cCurrentBytes -= pThis->m_cbBlock;
  208.         if (pThis == m_pBlockList)
  209.             m_pBlockList = pThis->m_pNext;
  210.         else
  211.             pPrev->m_pNext = pThis->m_pNext;
  212.         LocalFree(pThis);
  213.     }
  214.     else
  215.         hResult = E_FAIL;
  216.     ReleaseLock();
  217.     return hResult;
  218. }
  219. ///////////////////////////////////////////////////////////////////////////////
  220. /*  Function: FreeStore::Stats::Realloc
  221.     Description: Change the accounting information for a block to reflect
  222.         a re-allocation of the block.
  223.     Arguments: 
  224.         pOldBlock - Address of allocated block to be reallocated.
  225.         
  226.         pNewBlock - New address of reallocated block.  May be the same as
  227.             pOldBlock.
  228.         cbNewBlock - Number of bytes in new block.
  229.     Returns:
  230.         NO_ERROR    - Success.
  231.         E_FAIL      - pBlock not found.
  232.     Revision History:
  233.     Date        Description                                          Programmer
  234.     --------    ---------------------------------------------------  ----------
  235.     07/01/96    Initial creation.                                    BrianAu
  236. */
  237. ///////////////////////////////////////////////////////////////////////////////
  238. HRESULT 
  239. FreeStore::Stats::Realloc(
  240.     LPVOID pOldBlock,
  241.     LPVOID pNewBlock,
  242.     DWORD cbNewBlock
  243.     )
  244. {
  245.     Lock();
  246.     HRESULT hResult = NO_ERROR;
  247.     Block *pThis = m_pBlockList;
  248.     Block *pPrev = NULL;
  249.     while(NULL != pThis && pThis->m_pBlock != pOldBlock)
  250.     {
  251.         pPrev = pThis;
  252.         pThis = pThis->m_pNext;
  253.     }
  254.     if (NULL != pThis)
  255.     {
  256.         m_cCurrentBlocks--;
  257.         m_cCurrentBytes += (cbNewBlock - pThis->m_cbBlock);
  258.         if (m_cCurrentBytes > m_cMaxBytes)
  259.             m_cMaxBytes = m_cCurrentBytes;
  260.         pThis->m_pBlock  = pNewBlock;
  261.         pThis->m_cbBlock = cbNewBlock;        
  262.     }
  263.     else
  264.         hResult = E_FAIL;
  265.     ReleaseLock();
  266.     return hResult;
  267. }
  268. ///////////////////////////////////////////////////////////////////////////////
  269. /*  Function: FreeStore::Stats::Dump
  270.     Description: Dumps contents of FreeStore's statistics object to the debug
  271.         terminal.  
  272.     Arguments:
  273.         bDumpAll - If TRUE, data for each node is dumped.  If FALSE, only
  274.             summary information is output.
  275.     Returns:
  276.         NO_ERROR - Always returns NO_ERROR.
  277.     Revision History:
  278.     Date        Description                                          Programmer
  279.     --------    ---------------------------------------------------  ----------
  280.     07/01/96    Initial creation.                                    BrianAu
  281. */
  282. ///////////////////////////////////////////////////////////////////////////////
  283. HRESULT 
  284. FreeStore::Stats::Dump(
  285.     BOOL bDumpAll
  286.     )
  287. {
  288.     DWORD dwDebugMask = DM_ALLOC | DM_ALLOCSUM;
  289.     Lock();
  290.     Block *pThis = m_pBlockList;
  291.     DebugMsg(dwDebugMask, 
  292.              TEXT("[blks/bytes] - Cur [%d/%d]  Cumm [%d/%d]  Max [%d/%d]"),
  293.                            m_cCurrentBlocks,
  294.                            m_cCurrentBytes,
  295.                            m_cCummulativeBlocks,
  296.                            m_cCummulativeBytes,
  297.                            m_cMaxBlocks,
  298.                            m_cMaxBytes);
  299.     if (bDumpAll && m_cCurrentBlocks > 0)
  300.     {
  301.         DebugMsg(dwDebugMask, TEXT("List of blocks currently allocated:"));
  302.         while(NULL != pThis)
  303.         {
  304.             DebugMsg(dwDebugMask, TEXT("tBlock 0x%08X, %4d bytes"), 
  305.                      pThis->m_pBlock, pThis->m_cbBlock);
  306.             pThis = pThis->m_pNext;
  307.         }
  308.     }
  309.     ReleaseLock();
  310.     return NO_ERROR;
  311. }
  312. #endif // DEBUG_ALLOC