Advertisement
Guest User

Untitled

a guest
Mar 18th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.70 KB | None | 0 0
  1. #include <Base/Memory/MemoryBase.h>
  2. #include <Base/Memory/ScratchAllocator.h>
  3.  
  4. class SetupMemoryHeapsUtil
  5. {
  6.     DefaultHeap         defaultHeap;
  7.     MemTraceProxyHeap   globalHeap;
  8.     MemTraceProxyHeap   processHeap;
  9.     MemTraceProxyHeap   clumpsHeap;
  10.     MemTraceProxyHeap   stringsHeap;
  11. public:
  12.     SetupMemoryHeapsUtil();
  13.     ~SetupMemoryHeapsUtil();
  14. };
  15. class SetupScratchHeap : SetupMemoryHeapsUtil
  16. {
  17.     ScratchAllocator  scratchHeap;
  18.     ThreadSafeProxyHeap threadSafeWrapper;
  19.     AHeap * oldScratchHeap;
  20. public:
  21.     SetupScratchHeap( AHeap & _allocator, U32 sizeMiB );
  22.     ~SetupScratchHeap();
  23. };
  24.  
  25. /// A proxy allocator that simply draws upon another allocator.
  26. /// http://bitsquid.blogspot.ru/2010/09/custom-memory-allocation-in-c.html
  27. struct ProxyAllocator : AHeap, TLinkedList< ProxyAllocator >
  28. {
  29.     AHeap & m_allocator;
  30.     const char * m_name;
  31.  
  32.     LONG    m_currently_allocated;  // doesn't take alignment into account
  33.     LONG    m_peak_memory_usage;    // ditto
  34.     LONG    m_total_allocations;
  35.     LONG    m_total_frees;
  36.  
  37.     static ProxyAllocator::Head s_all;
  38.  
  39. public:
  40.     ProxyAllocator( const char* _name, AHeap & _allocator )
  41.         : m_allocator( _allocator ), m_name( _name )
  42.     {
  43.         _next = s_all;
  44.         s_all = this;
  45.     }
  46.     ~ProxyAllocator()
  47.     {
  48.         mxASSERT(m_currently_allocated == 0);
  49.     }
  50.     virtual void* Allocate( U32 _bytes, U32 _alignment ) override;
  51.     virtual void Deallocate( void* _memory ) override;
  52.     virtual U32 allocated_size( const void* _memory ) const override;
  53. };
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62. SetupMemoryHeapsUtil::SetupMemoryHeapsUtil()
  63.     : globalHeap( "global", defaultHeap )
  64.     , processHeap( "process", defaultHeap )
  65.     , clumpsHeap( "clumps", defaultHeap )
  66.     , stringsHeap( "strings", defaultHeap )
  67. {
  68.     Memory_Initialize();
  69.  
  70.     for( int iHeap = 0; iHeap < g_heaps.num(); iHeap++ ) {
  71.         g_heaps[ iHeap ] = &defaultHeap;
  72.     }
  73.     g_heaps[ HeapClumps ] = &clumpsHeap;
  74.     g_heaps[ HeapString ] = &stringsHeap;
  75.     //g_heaps[ HeapTemporary ] = &scratchHeap;
  76.     g_heaps[ HeapProcess ] = &processHeap;
  77. }
  78.  
  79. SetupMemoryHeapsUtil::~SetupMemoryHeapsUtil()
  80. {
  81.     Memory_Shutdown();
  82. }
  83.  
  84. SetupScratchHeap::SetupScratchHeap( AHeap & _allocator, U32 sizeMiB )
  85.     : scratchHeap( _allocator, mxMiB(sizeMiB), "scratch" )
  86.     , threadSafeWrapper( scratchHeap )
  87. {
  88.     threadSafeWrapper.Initialize();
  89.     oldScratchHeap = g_heaps[ HeapTemporary ];
  90.     g_heaps[ HeapTemporary ] = &threadSafeWrapper;
  91. }
  92. SetupScratchHeap::~SetupScratchHeap()
  93. {
  94.     g_heaps[ HeapTemporary ] = oldScratchHeap;
  95.     threadSafeWrapper.Shutdown();
  96. }
  97.  
  98. //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  99.  
  100. /*static*/ ProxyAllocator::Head ProxyAllocator::s_all = nil;
  101.  
  102. void* ProxyAllocator::Allocate( U32 _bytes, U32 _alignment ) {
  103.     void * ptr = m_allocator.Allocate( _bytes, _alignment );
  104.     if( ptr ) {
  105.         U32 real_size = m_allocator.allocated_size( ptr );
  106.         mxASSERT( real_size != SIZE_NOT_TRACKED );
  107.         InterlockedIncrement( &m_total_allocations );
  108.         LONG allocated_now = _InterlockedExchangeAdd( &m_currently_allocated, real_size );
  109.         // interlocked max(a,b); NOTE: creates deadlocks on platforms without priority inversion
  110.         LONG old_value, new_value;
  111.         do {
  112.             old_value = m_peak_memory_usage;
  113.             new_value = largest( old_value, allocated_now );
  114.         } while(
  115.             _InterlockedCompareExchange( &m_peak_memory_usage, new_value, old_value )
  116.             != old_value
  117.         );
  118.     }
  119.     return ptr;
  120. }
  121. void ProxyAllocator::Deallocate( void* _memory ) {
  122.     if( !_memory ) {
  123.         return;
  124.     }
  125.     U32 size = m_allocator.allocated_size( _memory );
  126.     mxASSERT( size != SIZE_NOT_TRACKED );
  127.  
  128.     _InterlockedExchangeAdd( &m_currently_allocated, -LONG(size) );
  129.     InterlockedIncrement( &m_total_frees );
  130.  
  131.     m_allocator.Deallocate( _memory );
  132. }
  133. U32 ProxyAllocator::allocated_size( const void* _memory ) const {
  134.     return m_allocator.allocated_size( _memory );
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement