7#ifdef TMEMORY_USE_DLMALLOC
10TMemoryDL* g_pMemoryDL =
TNULL;
12void TMemoryDL::OutOfMem( TMemoryDLHeap* heap,
TSIZE size )
15 TERROR(
"=========================================================================" );
16 TERROR(
"MEMORY ALLOCATION FAILED" );
17 TERROR(
"------------------------" );
18 TERROR(
"HEAP: {0}", heap->m_Name );
19 TERROR(
"------------------------" );
20 TERROR(
"failed to allocate {0} bytes (~{1}KB, ~{2}MB)", size, size >> 10, size >> 20 );
21 TERROR(
"=========================================================================" );
25void* TMemoryDL::dlheapmalloc( TMemoryDLHeap* heap,
TSIZE size )
28 if ( heap->m_Flags & TMemoryHeapFlags_AllocAsPile )
31 return TMemoryDLHeap::AllocAsPile( heap, size, 4 );
34 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) AcquireMutex();
36 void* chunk = mspace_malloc( heap->m_MSpace, size );
37 if ( chunk ==
TNULL ) TMemoryDL::OutOfMem( heap, size );
39 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) ReleaseMutex();
43void* TMemoryDL::dlheapcalloc( TMemoryDLHeap* heap,
TSIZE nitems,
TSIZE size )
46 if ( heap->m_Flags & TMemoryHeapFlags_AllocAsPile )
48 return TMemoryDLHeap::AllocAsPile( heap, nitems * size, 4 );
51 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) AcquireMutex();
53 void* chunk = mspace_calloc( heap->m_MSpace, nitems, size );
54 if ( chunk ==
TNULL ) TMemoryDL::OutOfMem( heap, size );
56 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) ReleaseMutex();
60void* TMemoryDL::dlheapmemalign( TMemoryDLHeap* heap,
TSIZE alignment,
TSIZE size )
63 if ( heap->m_Flags & TMemoryHeapFlags_AllocAsPile )
65 return TMemoryDLHeap::AllocAsPile( heap, size, 4 );
68 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) AcquireMutex();
70 void* chunk = mspace_memalign( heap->m_MSpace, alignment, size );
71 if ( chunk ==
TNULL ) TMemoryDL::OutOfMem( heap, size );
73 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) ReleaseMutex();
77void* TMemoryDL::dlheaprealloc( TMemoryDLHeap* heap,
void* mem,
TSIZE newsize )
80 TASSERT( ( heap->m_Flags & TMemoryHeapFlags_AllocAsPile ) == 0,
"Cannot realloc on pile" );
82 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) AcquireMutex();
84 void* chunk = mspace_realloc( heap->m_MSpace, mem, newsize );
85 if ( chunk ==
TNULL ) TMemoryDL::OutOfMem( heap, newsize );
87 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) ReleaseMutex();
91void TMemoryDL::dlheapfree( TMemoryDLHeap* heap,
void* mem )
93 TASSERT( ( heap->m_Flags & TMemoryHeapFlags_AllocAsPile ) == 0,
"Cannot free pile memory" );
95 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) AcquireMutex();
97 mspace_free( heap->m_MSpace, mem );
99 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) ReleaseMutex();
102void TMemoryDL::dlheapdestroy( TMemoryDLHeap* heap )
106 if ( heap->m_Flags & TMemoryHeapFlags_UseMutex ) heap->DestroyMutex();
107 destroy_mspace( heap->m_MSpace );
108 heap->m_MSpace =
TNULL;
110 if ( heap->m_SubHeapBuffer !=
TNULL )
112 GetContext().Free( heap->m_SubHeapBuffer );
113 heap->m_SubHeapBuffer =
TNULL;
118TMemoryDLHeap* TMemoryDL::dlheapcreatesubheap( TMemoryDLHeap* heap,
TSIZE size, TMemoryDLHeapFlags flags,
const char name[ HEAP_MAXNAME ] )
121 TMemoryDLHeap* subHeap =
TNULL;
122 TSIZE subHeapSize = size +
sizeof( TMemoryDLHeap );
123 void* mem = heap->Malloc( subHeapSize );
127 if ( flags & TMemoryHeapFlags_AllocAsPile )
129 subHeap =
static_cast<TMemoryDLHeap*
>( mem );
131 subHeap->m_pOwnerBlock =
this;
132 subHeap->m_Flags = flags;
133 subHeap->m_MSpace =
TNULL;
134 subHeap->m_PileData =
reinterpret_cast<char*
>( subHeap + 1 );
135 subHeap->m_PileSize = subHeapSize;
136 subHeap->SetName( name );
138 if ( flags & TMemoryHeapFlags_UseMutex )
140 subHeap->CreateMutex();
144 TUtil::MemSet( &subHeap->m_Mutex, 0,
sizeof( subHeap->m_Mutex ) );
149 subHeap = TMemoryDL::CreateHeapInPlace( mem, subHeapSize, flags, name );
153 if ( subHeap !=
TNULL )
155 subHeap->m_SubHeapBuffer =
static_cast<char*
>( mem );
159 GetContext().Free( mem );
166TMemoryDLHeap* TMemoryDL::dlheapcreateinplace(
void* ptr,
TSIZE heapSize, TMemoryDLHeapFlags flags,
const char name[ HEAP_MAXNAME ] )
168 TASSERT( heapSize > 0,
"Allocation size is zero" );
169 TASSERT( ( heapSize & 3 ) == 0,
"Allocation size is not aligned to 4" );
171 TMemoryDLHeap* heap =
static_cast<TMemoryDLHeap*
>( ptr );
174 TSIZE capacity = heapSize -
sizeof( TMemoryDLHeap );
175 heap->m_MSpace = create_mspace_with_base( heap + 1, capacity, 1 );
177 if ( heap->m_MSpace !=
TNULL )
179 heap->m_pOwnerBlock =
this;
180 heap->m_Flags = flags;
181 heap->SetName( name );
183 if ( flags & TMemoryHeapFlags_UseMutex )
200void* TMemoryDLHeap::AllocAsPile( TMemoryDLHeap* heap,
TSIZE size,
TSIZE alignment )
202 TASSERT( heap->m_Flags & TMemoryHeapFlags_AllocAsPile,
"Can't allocate as pile on a non-pile heap" );
205 heap->m_PileData =
reinterpret_cast<char*
>( ( ( (
TSIZE)heap->m_PileData + ( alignment - 1 ) ) / alignment ) * alignment );
206 TSIZE usedMemorySize = heap->m_PileData - heap->m_SubHeapBuffer;
208 if ( usedMemorySize + size > heap->m_PileSize )
210 TERROR(
"Out of memory in pile '{0}' when trying to alloc {1} bytes", heap->m_Name, size );
214 void* allocated = heap->m_PileData;
215 heap->m_PileData += size;
#define TOSHI_NAMESPACE_START
#define TOSHI_NAMESPACE_END
static void MemClear(void *ptr, TSIZE size)
static void MemSet(void *ptr, TINT value, TSIZE size)