summaryrefslogtreecommitdiff
path: root/external/vpc/public/tier1/memstack.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /external/vpc/public/tier1/memstack.h
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'external/vpc/public/tier1/memstack.h')
-rw-r--r--external/vpc/public/tier1/memstack.h348
1 files changed, 348 insertions, 0 deletions
diff --git a/external/vpc/public/tier1/memstack.h b/external/vpc/public/tier1/memstack.h
new file mode 100644
index 0000000..f1846d2
--- /dev/null
+++ b/external/vpc/public/tier1/memstack.h
@@ -0,0 +1,348 @@
+//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
+//
+// Purpose: A fast stack memory allocator that uses virtual memory if available
+//
+//===========================================================================//
+
+#ifndef MEMSTACK_H
+#define MEMSTACK_H
+
+#if defined( _WIN32 )
+#pragma once
+#endif
+
+#include "tier1/utlvector.h"
+
+#if defined( _WIN32 ) || defined( _PS3 )
+#define MEMSTACK_VIRTUAL_MEMORY_AVAILABLE
+#endif
+
+//-----------------------------------------------------------------------------
+
+typedef unsigned MemoryStackMark_t;
+
+class CMemoryStack
+{
+public:
+ CMemoryStack();
+ ~CMemoryStack();
+
+ bool Init( const char *pszAllocOwner, unsigned maxSize = 0, unsigned commitSize = 0, unsigned initialCommit = 0, unsigned alignment = 16 );
+#ifdef _GAMECONSOLE
+ bool InitPhysical( const char *pszAllocOwner, uint size, uint nBaseAddrAlignment, uint alignment = 16, uint32 nAdditionalFlags = 0 );
+#endif
+ void Term();
+
+ int GetSize();
+ int GetMaxSize();
+ int GetUsed();
+
+ void *Alloc( unsigned bytes, bool bClear = false ) RESTRICT;
+
+ MemoryStackMark_t GetCurrentAllocPoint();
+ void FreeToAllocPoint( MemoryStackMark_t mark, bool bDecommit = true );
+ void FreeAll( bool bDecommit = true );
+
+ void Access( void **ppRegion, unsigned *pBytes );
+
+ void PrintContents();
+
+ void *GetBase();
+ const void *GetBase() const { return const_cast<CMemoryStack *>(this)->GetBase(); }
+
+ bool CommitSize( int );
+
+ void SetAllocOwner( const char *pszAllocOwner );
+
+private:
+ bool CommitTo( byte * ) RESTRICT;
+ void RegisterAllocation();
+ void RegisterDeallocation( bool bShouldSpew );
+
+ byte *m_pNextAlloc;
+ byte *m_pCommitLimit;
+ byte *m_pAllocLimit;
+
+ byte *m_pBase;
+ bool m_bRegisteredAllocation;
+ bool m_bPhysical;
+ char *m_pszAllocOwner;
+
+ unsigned m_maxSize;
+ unsigned m_alignment;
+#ifdef MEMSTACK_VIRTUAL_MEMORY_AVAILABLE
+ unsigned m_commitSize;
+ unsigned m_minCommit;
+#endif
+#if defined( MEMSTACK_VIRTUAL_MEMORY_AVAILABLE ) && defined( _PS3 )
+ IVirtualMemorySection *m_pVirtualMemorySection;
+#endif
+};
+
+//-------------------------------------
+
+FORCEINLINE void *CMemoryStack::Alloc( unsigned bytes, bool bClear ) RESTRICT
+{
+ Assert( m_pBase );
+
+ bytes = MAX( bytes, m_alignment );
+ bytes = AlignValue( bytes, m_alignment );
+
+ void *pResult = m_pNextAlloc;
+ byte *pNextAlloc = m_pNextAlloc + bytes;
+
+ if ( pNextAlloc > m_pCommitLimit )
+ {
+ if ( !CommitTo( pNextAlloc ) )
+ {
+ return NULL;
+ }
+ }
+
+ if ( bClear )
+ {
+ memset( pResult, 0, bytes );
+ }
+
+ m_pNextAlloc = pNextAlloc;
+
+ return pResult;
+}
+
+//-------------------------------------
+
+inline bool CMemoryStack::CommitSize( int nBytes )
+{
+ if ( GetSize() != nBytes )
+ {
+ return CommitTo( m_pBase + nBytes );
+ }
+ return true;
+}
+
+//-------------------------------------
+
+inline int CMemoryStack::GetMaxSize()
+{
+ return m_maxSize;
+}
+
+//-------------------------------------
+
+inline int CMemoryStack::GetUsed()
+{
+ return ( m_pNextAlloc - m_pBase );
+}
+
+//-------------------------------------
+
+inline void *CMemoryStack::GetBase()
+{
+ return m_pBase;
+}
+
+//-------------------------------------
+
+inline MemoryStackMark_t CMemoryStack::GetCurrentAllocPoint()
+{
+ return ( m_pNextAlloc - m_pBase );
+}
+
+
+//-----------------------------------------------------------------------------
+// The CUtlMemoryStack class:
+// A fixed memory class
+//-----------------------------------------------------------------------------
+template< typename T, typename I, size_t MAX_SIZE, size_t COMMIT_SIZE = 0, size_t INITIAL_COMMIT = 0 >
+class CUtlMemoryStack
+{
+public:
+ // constructor, destructor
+ CUtlMemoryStack( int nGrowSize = 0, int nInitSize = 0 ) { m_MemoryStack.Init( "CUtlMemoryStack", MAX_SIZE * sizeof(T), COMMIT_SIZE * sizeof(T), INITIAL_COMMIT * sizeof(T), 4 ); COMPILE_TIME_ASSERT( sizeof(T) % 4 == 0 ); }
+ CUtlMemoryStack( T* pMemory, int numElements ) { Assert( 0 ); }
+
+ // Can we use this index?
+ bool IsIdxValid( I i ) const { long x=i; return (x >= 0) && (x < m_nAllocated); }
+
+ // Specify the invalid ('null') index that we'll only return on failure
+ static const I INVALID_INDEX = ( I )-1; // For use with COMPILE_TIME_ASSERT
+ static I InvalidIndex() { return INVALID_INDEX; }
+
+ class Iterator_t
+ {
+ Iterator_t( I i ) : index( i ) {}
+ I index;
+ friend class CUtlMemoryStack<T,I,MAX_SIZE, COMMIT_SIZE, INITIAL_COMMIT>;
+ public:
+ bool operator==( const Iterator_t it ) const { return index == it.index; }
+ bool operator!=( const Iterator_t it ) const { return index != it.index; }
+ };
+ Iterator_t First() const { return Iterator_t( m_nAllocated ? 0 : InvalidIndex() ); }
+ Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( it.index < m_nAllocated ? it.index + 1 : InvalidIndex() ); }
+ I GetIndex( const Iterator_t &it ) const { return it.index; }
+ bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; }
+ bool IsValidIterator( const Iterator_t &it ) const { long x=it.index; return x >= 0 && x < m_nAllocated; }
+ Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); }
+
+ // Gets the base address
+ T* Base() { return (T*)m_MemoryStack.GetBase(); }
+ const T* Base() const { return (const T*)m_MemoryStack.GetBase(); }
+
+ // element access
+ T& operator[]( I i ) { Assert( IsIdxValid(i) ); return Base()[i]; }
+ const T& operator[]( I i ) const { Assert( IsIdxValid(i) ); return Base()[i]; }
+ T& Element( I i ) { Assert( IsIdxValid(i) ); return Base()[i]; }
+ const T& Element( I i ) const { Assert( IsIdxValid(i) ); return Base()[i]; }
+
+ // Attaches the buffer to external memory....
+ void SetExternalBuffer( T* pMemory, int numElements ) { Assert( 0 ); }
+
+ // Size
+ int NumAllocated() const { return m_nAllocated; }
+ int Count() const { return m_nAllocated; }
+
+ // Grows the memory, so that at least allocated + num elements are allocated
+ void Grow( int num = 1 ) { Assert( num > 0 ); m_nAllocated += num; m_MemoryStack.Alloc( num * sizeof(T) ); }
+
+ // Makes sure we've got at least this much memory
+ void EnsureCapacity( int num ) { Assert( num <= MAX_SIZE ); if ( m_nAllocated < num ) Grow( num - m_nAllocated ); }
+
+ // Memory deallocation
+ void Purge() { m_MemoryStack.FreeAll(); m_nAllocated = 0; }
+
+ // is the memory externally allocated?
+ bool IsExternallyAllocated() const { return false; }
+
+ // Set the size by which the memory grows
+ void SetGrowSize( int size ) { Assert( 0 ); }
+
+ // Identify the owner of this memory stack's memory
+ void SetAllocOwner( const char *pszAllocOwner ) { m_MemoryStack.SetAllocOwner( pszAllocOwner ); }
+
+private:
+ CMemoryStack m_MemoryStack;
+ int m_nAllocated;
+};
+
+
+#ifdef _X360
+//-----------------------------------------------------------------------------
+// A memory stack used for allocating physical memory on the 360
+// Usage pattern anticipates we usually never go over the initial allocation
+// When we do so, we're ok with slightly slower allocation
+//-----------------------------------------------------------------------------
+class CPhysicalMemoryStack
+{
+public:
+ CPhysicalMemoryStack();
+ ~CPhysicalMemoryStack();
+
+ // The physical memory stack is allocated in chunks. We will initially
+ // allocate nInitChunkCount chunks, which will always be in memory.
+ // When FreeAll() is called, it will free down to the initial chunk count
+ // but not below it.
+ bool Init( size_t nChunkSizeInBytes, size_t nAlignment, int nInitialChunkCount, uint32 nAdditionalFlags );
+ void Term();
+
+ size_t GetSize() const;
+ size_t GetPeakUsed() const;
+ size_t GetUsed() const;
+ size_t GetFramePeakUsed() const;
+
+ MemoryStackMark_t GetCurrentAllocPoint() const;
+ void FreeToAllocPoint( MemoryStackMark_t mark, bool bUnused = true ); // bUnused is for interface compat with CMemoryStack
+ void *Alloc( size_t nSizeInBytes, bool bClear = false ) RESTRICT;
+ void FreeAll( bool bUnused = true ); // bUnused is for interface compat with CMemoryStack
+
+ void PrintContents();
+
+private:
+ void *AllocFromOverflow( size_t nSizeInBytes );
+
+ struct PhysicalChunk_t
+ {
+ uint8 *m_pBase;
+ uint8 *m_pNextAlloc;
+ uint8 *m_pAllocLimit;
+ };
+
+ PhysicalChunk_t m_InitialChunk;
+ CUtlVector< PhysicalChunk_t > m_ExtraChunks;
+ size_t m_nUsage;
+ size_t m_nFramePeakUsage;
+ size_t m_nPeakUsage;
+ size_t m_nAlignment;
+ size_t m_nChunkSizeInBytes;
+ int m_nFirstAvailableChunk;
+ int m_nAdditionalFlags;
+ PhysicalChunk_t *m_pLastAllocedChunk;
+};
+
+//-------------------------------------
+
+FORCEINLINE void *CPhysicalMemoryStack::Alloc( size_t nSizeInBytes, bool bClear ) RESTRICT
+{
+ if ( nSizeInBytes )
+ {
+ nSizeInBytes = AlignValue( nSizeInBytes, m_nAlignment );
+ }
+ else
+ {
+ nSizeInBytes = m_nAlignment;
+ }
+
+ // Can't do an allocation bigger than the chunk size
+ Assert( nSizeInBytes <= m_nChunkSizeInBytes );
+
+ void *pResult = m_InitialChunk.m_pNextAlloc;
+ uint8 *pNextAlloc = m_InitialChunk.m_pNextAlloc + nSizeInBytes;
+ if ( pNextAlloc <= m_InitialChunk.m_pAllocLimit )
+ {
+ m_InitialChunk.m_pNextAlloc = pNextAlloc;
+ m_pLastAllocedChunk = &m_InitialChunk;
+ }
+ else
+ {
+ pResult = AllocFromOverflow( nSizeInBytes );
+ }
+
+ m_nUsage += nSizeInBytes;
+ m_nFramePeakUsage = MAX( m_nUsage, m_nFramePeakUsage );
+ m_nPeakUsage = MAX( m_nUsage, m_nPeakUsage );
+
+ if ( bClear )
+ {
+ memset( pResult, 0, nSizeInBytes );
+ }
+
+ return pResult;
+}
+
+//-------------------------------------
+
+inline size_t CPhysicalMemoryStack::GetPeakUsed() const
+{
+ return m_nPeakUsage;
+}
+
+//-------------------------------------
+
+inline size_t CPhysicalMemoryStack::GetUsed() const
+{
+ return m_nUsage;
+}
+
+inline size_t CPhysicalMemoryStack::GetFramePeakUsed() const
+{
+ return m_nFramePeakUsage;
+}
+
+inline MemoryStackMark_t CPhysicalMemoryStack::GetCurrentAllocPoint() const
+{
+ Assert( m_pLastAllocedChunk );
+ return ( m_pLastAllocedChunk->m_pNextAlloc - m_pLastAllocedChunk->m_pBase );
+}
+
+#endif // _X360
+
+#endif // MEMSTACK_H