home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / idlib / rvHeapArena.cpp < prev    next >
C/C++ Source or Header  |  2005-11-14  |  6KB  |  304 lines

  1. //
  2. // rvHeapArena.cpp - Heap arena object that manages a set of heaps
  3. // Date: 12/13/04
  4. // Created by: Dwight Luetscher
  5. //
  6.  
  7. #include "../idlib/precompiled.h"
  8. #pragma hdrstop
  9.  
  10. #ifdef _RV_MEM_SYS_SUPPORT
  11.  
  12. // rvHeapArena
  13. //
  14. // constructor
  15. rvHeapArena::rvHeapArena()
  16. {
  17.     // ResetValues();    do this in the Init() call instead (due to the fact that other constructors could call rvHeapArena::Init() before this constructor is called)
  18. }
  19.  
  20. // ~rvHeapArena
  21. //
  22. // destructor
  23. rvHeapArena::~rvHeapArena()
  24. {
  25.     Shutdown();
  26. }
  27.  
  28. // Init
  29. //
  30. // initializes this heap arena for use
  31. void rvHeapArena::Init( )
  32. {
  33.     if ( m_isInitialized )
  34.     {
  35.         return;
  36.     }
  37.  
  38.     ResetValues();
  39.     m_isInitialized = true;
  40.  
  41.     // create the critical section used by this heap arena
  42.     InitializeCriticalSection( &m_criticalSection );
  43. }
  44.  
  45. // Shutdown
  46. //
  47. // releases this heap arena from use (shutting down all associated heaps)
  48. void rvHeapArena::Shutdown( )
  49. {
  50.     // shutdown each heap from this arena's list
  51.     rvHeap *curHeap = m_heapList, *nextHeap;
  52.     while ( curHeap != NULL )
  53.     {
  54.         nextHeap = curHeap->GetNext();
  55.  
  56.         curHeap->Shutdown();
  57.  
  58.         curHeap = nextHeap;
  59.     }
  60.     DeleteCriticalSection( &m_criticalSection );
  61.     ResetValues();
  62. }
  63.  
  64. // ResetValues
  65. // 
  66. // resets the data members to their pre-initialized state
  67. void rvHeapArena::ResetValues( )
  68. {
  69.     memset( m_heapStack, 0, sizeof(m_heapStack) );
  70.     memset( &m_criticalSection, 0, sizeof(m_criticalSection) );
  71.     m_tos = -1;
  72.     m_heapList = NULL;
  73.     m_isInitialized = false;
  74. }
  75.  
  76. // Push
  77. //
  78. // pushes the given heap onto the top of the stack making it the active one for this arena
  79. void rvHeapArena::Push( rvHeap &newActiveHeap )
  80. {
  81.     EnterArenaCriticalSection();
  82.     assert( newActiveHeap.GetArena() == this );
  83.     assert(m_tos+1 < maxHeapStackDepth);    // stack overflow?
  84.     if (m_tos+1 < maxHeapStackDepth) 
  85.     {
  86.         m_heapStack[++m_tos] = &newActiveHeap;
  87.     }
  88.     ExitArenaCriticalSection();
  89. }
  90.  
  91. // Pop
  92. //
  93. // pops the top of the stack, restoring the previous heap as the active heap for this arena
  94. void rvHeapArena::Pop( )
  95. {
  96.     EnterArenaCriticalSection();
  97.     assert(m_tos > -1);                        // stack underflow?
  98.     if (m_tos > -1) 
  99.     {
  100.         m_tos--;
  101.     }
  102.     ExitArenaCriticalSection();
  103. }
  104.  
  105. // GetHeap
  106. //
  107. // returns: the heap that the given allocation was made from, NULL for none
  108. rvHeap *rvHeapArena::GetHeap( void *p )
  109. {
  110.     EnterArenaCriticalSection();
  111.     if ( !m_isInitialized )
  112.     {
  113.         ExitArenaCriticalSection();
  114.         return NULL;
  115.     }
  116.  
  117.     rvHeap *curHeap = m_heapList;
  118.     while ( curHeap != NULL && !curHeap->DoesAllocBelong(p) )
  119.     {
  120.         curHeap = curHeap->GetNext();
  121.     }
  122.     ExitArenaCriticalSection();
  123.  
  124.     return curHeap;
  125. }
  126.  
  127.  
  128. // Allocate
  129. // 
  130. // allocates the given amount of memory from this arena.
  131. void *rvHeapArena::Allocate( unsigned int sizeBytes, int debugTag )
  132. {
  133.     rvHeap *curHeap;
  134.  
  135.     EnterArenaCriticalSection();
  136.     assert( m_tos >= 0 && m_tos < maxHeapStackDepth );
  137.     if ( m_tos < 0 )
  138.     {
  139.         ExitArenaCriticalSection();
  140.         return NULL;
  141.     }
  142.     curHeap = m_heapStack[ m_tos ];
  143.     ExitArenaCriticalSection();
  144.  
  145.     return curHeap->Allocate( sizeBytes, debugTag );
  146. }
  147.  
  148. // Allocate16
  149. //
  150. // allocates the given amount of memory from this arena, 
  151. // aligned on a 16-byte boundary.
  152. void *rvHeapArena::Allocate16( unsigned int sizeBytes, int debugTag )
  153. {
  154.     rvHeap *curHeap;
  155.  
  156.     EnterArenaCriticalSection();
  157.     assert( m_tos >= 0 && m_tos < maxHeapStackDepth );
  158.     if ( m_tos < 0 )
  159.     {
  160.         ExitArenaCriticalSection();
  161.         return NULL;
  162.     }
  163.     curHeap = m_heapStack[ m_tos ];
  164.     ExitArenaCriticalSection();
  165.  
  166.     return curHeap->Allocate16( sizeBytes, debugTag );
  167. }
  168.  
  169. // Free
  170. // 
  171. // free memory back to this arena
  172. void rvHeapArena::Free( void *p )
  173. {
  174.     rvHeap *heap = GetHeap( p );    // arena critical section protection is in GetHeap()
  175.     if (heap != NULL)
  176.     {
  177.         heap->Free( p );
  178.     }
  179. }
  180.  
  181. // Msize
  182. //
  183. // returns: the size, in bytes, of the allocation at the given address (including header, alignment bytes, etc).
  184. int rvHeapArena::Msize( void *p )
  185. {
  186.     rvHeap *heap = GetHeap( p );    // arena critical section protection is in GetHeap()
  187.     if (heap != NULL)
  188.     {
  189.         return heap->Msize( p );
  190.     }
  191.     return 0;
  192. }
  193.  
  194. // InitHeap
  195. //
  196. // initializes the given heap to be under the care of this arena
  197. void rvHeapArena::InitHeap( rvHeap &newActiveHeap )
  198. {
  199.     assert( newActiveHeap.GetArena() == NULL );
  200.  
  201.     newActiveHeap.SetArena( this );
  202.     newActiveHeap.SetNext( m_heapList );
  203.     m_heapList = &newActiveHeap;
  204. }
  205.  
  206. // ShutdownHeap
  207. //
  208. // releases the given heap from the care of this arena
  209. void rvHeapArena::ShutdownHeap( rvHeap &activeHeap )
  210. {
  211.     int stackPos, copyPos;
  212.  
  213.     assert( activeHeap.GetArena() == this );
  214.  
  215.     activeHeap.SetArena( NULL );
  216.  
  217.     // make sure that the heap is removed from the stack
  218.     for ( stackPos = 0; stackPos <= m_tos; stackPos++ )
  219.     {
  220.         if ( m_heapStack[stackPos] == &activeHeap )
  221.         {
  222.             for ( copyPos = stackPos; copyPos < m_tos; copyPos++ )
  223.             {
  224.                 m_heapStack[copyPos] = m_heapStack[copyPos+1];
  225.             }
  226.             m_tos--;
  227.         }
  228.     }
  229.  
  230.     // remove the heap from this arena's list
  231.     rvHeap *curHeap = m_heapList, * prevHeap = NULL;
  232.     while ( curHeap != NULL )
  233.     {
  234.         if ( curHeap == &activeHeap )
  235.         {
  236.             if ( NULL == prevHeap )
  237.             {
  238.                 m_heapList = m_heapList->GetNext();
  239.             }
  240.             else 
  241.             {
  242.                 prevHeap->SetNext( curHeap->GetNext() );
  243.             }
  244.             break;
  245.         }
  246.         prevHeap = curHeap;
  247.         curHeap = curHeap->GetNext();
  248.     }
  249. }
  250.  
  251. // GetNextHeap
  252. //
  253. // returns: that follows the given one (associated with this arena), NULL for none
  254. rvHeap *rvHeapArena::GetNextHeap( rvHeap &rfPrevHeap )
  255. {
  256.     rvHeap *nextHeap;
  257.  
  258.     EnterArenaCriticalSection();
  259.     if ( rfPrevHeap.GetArena() != this )
  260.     {
  261.         nextHeap = NULL;
  262.     }
  263.     else
  264.     {
  265.         nextHeap = rfPrevHeap.GetNext();
  266.     }
  267.     ExitArenaCriticalSection();
  268.  
  269.     return nextHeap;
  270. }
  271.  
  272. // GetTagStats
  273. //
  274. // returns: the total stats for a particular tag type (across all heaps managed by this arena)
  275. void rvHeapArena::GetTagStats(int tag, int &num, int &size, int &peak)
  276. {
  277.     int curPeak;
  278.  
  279.     assert( tag < MA_MAX );
  280.  
  281.     EnterArenaCriticalSection();
  282.  
  283.     num = size = peak = 0;
  284.  
  285.     rvHeap *curHeap = m_heapList;
  286.     while ( curHeap != NULL )
  287.     {
  288.         num += curHeap->GetNumAllocationsByTag( (Mem_Alloc_Types_t) tag );
  289.         size += curHeap->GetBytesAllocatedByTag( (Mem_Alloc_Types_t) tag );
  290.  
  291.         curPeak = curHeap->GetPeekBytesAllocatedByTag( (Mem_Alloc_Types_t) tag );
  292.         if ( curPeak > peak )
  293.         {
  294.             peak = curPeak;
  295.         }
  296.  
  297.         curHeap = curHeap->GetNext();
  298.     }
  299.  
  300.     ExitArenaCriticalSection();
  301. }
  302.  
  303. #endif    // #ifdef _RV_MEM_SYS_SUPPORT
  304.