OpenBarnyard
 
Loading...
Searching...
No Matches
TMemoryDL_Win.cpp
Go to the documentation of this file.
1#include "ToshiPCH.h"
3#include "Core/dlmalloc.h"
4
5#ifdef TMEMORY_USE_DLMALLOC
6
7/* ------------------- TSIZE and alignment properties -------------------- */
8
9/* The byte and bit size of a TSIZE */
10# define SIZE_T_SIZE ( sizeof( TSIZE ) )
11# define SIZE_T_BITSIZE ( sizeof( TSIZE ) << 3 )
12
13/* Some constants coerced to TSIZE */
14/* Annoying but necessary to avoid errors on some platforms */
15# define SIZE_T_ZERO ( (TSIZE)0 )
16# define SIZE_T_ONE ( (TSIZE)1 )
17# define SIZE_T_TWO ( (TSIZE)2 )
18# define SIZE_T_FOUR ( (TSIZE)4 )
19# define TWO_SIZE_T_SIZES ( SIZE_T_SIZE << 1 )
20# define FOUR_SIZE_T_SIZES ( SIZE_T_SIZE << 2 )
21# define SIX_SIZE_T_SIZES ( FOUR_SIZE_T_SIZES + TWO_SIZE_T_SIZES )
22# define HALF_MAX_SIZE_T ( MAX_SIZE_T / 2U )
23
24/* The bit mask value corresponding to MALLOC_ALIGNMENT */
25# define CHUNK_ALIGN_MASK ( MALLOC_ALIGNMENT - SIZE_T_ONE )
26
27/* True if address a has acceptable alignment */
28# define is_aligned( A ) ( ( (TSIZE)( ( A ) ) & ( CHUNK_ALIGN_MASK ) ) == 0 )
29
30/* the number of bytes to offset an address to align it */
31# define align_offset( A ) \
32 ( ( ( (TSIZE)(A)&CHUNK_ALIGN_MASK ) == 0 ) ? 0 : \
33 ( ( MALLOC_ALIGNMENT - ( (TSIZE)(A)&CHUNK_ALIGN_MASK ) ) & CHUNK_ALIGN_MASK ) )
34
35struct malloc_chunk
36{
37 TSIZE prev_foot; /* Size of previous chunk (if free). */
38 TSIZE head; /* Size and inuse bits. */
39 struct malloc_chunk* fd; /* double links -- used only if free. */
40 struct malloc_chunk* bk;
41};
42
43typedef struct malloc_chunk mchunk;
44typedef struct malloc_chunk* mchunkptr;
45typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */
46typedef unsigned int bindex_t; /* Described below */
47typedef unsigned int binmap_t; /* Described below */
48typedef unsigned int flag_t; /* The type of various bit flag sets */
49
50/* ------------------- Chunks sizes and alignments ----------------------- */
51
52# define MCHUNK_SIZE ( sizeof( mchunk ) )
53
54# if FOOTERS
55# define CHUNK_OVERHEAD ( TWO_SIZE_T_SIZES )
56# else /* FOOTERS */
57# define CHUNK_OVERHEAD ( SIZE_T_SIZE )
58# endif /* FOOTERS */
59
60/* MMapped chunks need a second word of overhead ... */
61# define MMAP_CHUNK_OVERHEAD ( TWO_SIZE_T_SIZES )
62/* ... and additional padding for fake next-chunk at foot */
63# define MMAP_FOOT_PAD ( FOUR_SIZE_T_SIZES )
64
65/* The smallest size we can malloc is an aligned minimal chunk */
66# define MIN_CHUNK_SIZE \
67 ( ( MCHUNK_SIZE + CHUNK_ALIGN_MASK ) & ~CHUNK_ALIGN_MASK )
68
69/* conversion from malloc headers to user pointers, and back */
70# define chunk2mem( p ) ( (void*)( (char*)( p ) + TWO_SIZE_T_SIZES ) )
71# define mem2chunk( mem ) ( (mchunkptr)( (char*)(mem)-TWO_SIZE_T_SIZES ) )
72/* chunk associated with aligned address A */
73# define align_as_chunk( A ) ( mchunkptr )( ( A ) + align_offset( chunk2mem( A ) ) )
74
75/* ------------------ Operations on head and foot fields ----------------- */
76
77/*
78 The head field of a chunk is or'ed with PINUSE_BIT when previous
79 adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
80 use, unless mmapped, in which case both bits are cleared.
81
82 FLAG4_BIT is not used by this malloc, but might be useful in extensions.
83*/
84
85# define PINUSE_BIT ( SIZE_T_ONE )
86# define CINUSE_BIT ( SIZE_T_TWO )
87# define FLAG4_BIT ( SIZE_T_FOUR )
88# define INUSE_BITS ( PINUSE_BIT | CINUSE_BIT )
89# define FLAG_BITS ( PINUSE_BIT | CINUSE_BIT | FLAG4_BIT )
90
91# define chunksize( p ) ( ( p )->head & ~( FLAG_BITS ) )
92
94
95void TMemoryDL::Shutdown()
96{
97 dlheapdestroy( g_pMemoryDL->m_GlobalHeap );
98 g_pMemoryDL->m_GlobalHeap = TNULL;
99
100 if ( g_pMemoryDL->m_Context.s_Heap )
101 {
102 HeapFree( g_pMemoryDL->m_Context.s_Sysheap, NULL, g_pMemoryDL->m_Context.s_Heap );
103 }
104
105 if ( TMemoryDL::GetFlags() & Flags_Standard )
106 {
107 // Reset callbacks so no external libraries can malloc or free anything
108 g_pMemoryDL->m_Context.s_cbMalloc = []( TMemoryDL* pMemModule, TSIZE size ) -> void* {
109 return TNULL;
110 };
111 g_pMemoryDL->m_Context.s_cbCalloc = []( TMemoryDL* pMemModule, TSIZE nitems, TSIZE size ) -> void* {
112 return TNULL;
113 };
114 g_pMemoryDL->m_Context.s_cbRealloc = []( TMemoryDL* pMemModule, void* ptr, TSIZE size ) -> void* {
115 return TNULL;
116 };
117 g_pMemoryDL->m_Context.s_cbMemalign = []( TMemoryDL* pMemModule, TSIZE alignment, TSIZE size ) -> void* {
118 return TNULL;
119 };
120 g_pMemoryDL->m_Context.s_cbFree = []( TMemoryDL* pMemModule, void* ptr ) -> void {
121 };
122 g_pMemoryDL->m_Context.s_cbIdk = []( TMemoryDL* pMemModule, void* ptr, TSIZE size ) -> void {
123 };
124 }
125
126 TUtil::MemSet( &g_pMemoryDL->m_Context, 0, sizeof( m_Context ) );
127}
128
129TMemoryDL::Error TMemoryDL::Init()
130{
131 // 0x006fb9d0
132 TASSERT( m_Context.s_Sysheap == NULL, "TMemoryDL is already initialized" );
133
134 m_Context.m_pMemModule = this;
135 m_Context.s_Sysheap = GetProcessHeap();
136 m_Mutex.Create();
137
138 if ( m_Context.s_Sysheap == NULL )
139 {
140 return Error_Heap;
141 }
142
143 // Check if we should use default memory management methods
144 if ( m_Flags & Flags_NativeMethods )
145 {
146 m_Context.s_cbMalloc = TMemoryDLContext::MallocNative;
147 m_Context.s_cbCalloc = TMemoryDLContext::CallocNative;
148 m_Context.s_cbRealloc = TMemoryDLContext::ReallocNative;
149 m_Context.s_cbMemalign = TMemoryDLContext::MemalignNative;
150 m_Context.s_cbFree = TMemoryDLContext::FreeNative;
151 m_Context.s_cbIdk = TMemoryDLContext::IdkNative;
152
153 return Error_Ok;
154 }
155
156 // Allocate memory for the heap
157 m_Context.s_Heap = HeapAlloc( m_Context.s_Sysheap, HEAP_ZERO_MEMORY, m_GlobalSize );
158
159 // Save pointers to our own functions
160 if ( m_Context.s_Heap == NULL )
161 {
162 return Error_Heap;
163 }
164
165 m_Context.s_cbMalloc = []( TMemoryDL* pMemModule, TSIZE size ) -> void* {
166 return pMemModule->dlheapmalloc( pMemModule->GetHeap(), size );
167 };
168
169 m_Context.s_cbCalloc = []( TMemoryDL* pMemModule, TSIZE nitems, TSIZE size ) -> void* {
170 return pMemModule->dlheapcalloc( pMemModule->GetHeap(), nitems, size );
171 };
172
173 m_Context.s_cbRealloc = []( TMemoryDL* pMemModule, void* ptr, TSIZE size ) -> void* {
174 return pMemModule->dlheaprealloc( pMemModule->GetHeap(), ptr, size );
175 };
176
177 m_Context.s_cbMemalign = []( TMemoryDL* pMemModule, TSIZE alignment, TSIZE size ) -> void* {
178 return pMemModule->dlheapmemalign( pMemModule->GetHeap(), alignment, size );
179 };
180
181 m_Context.s_cbFree = []( TMemoryDL* pMemModule, void* ptr ) -> void {
182 pMemModule->dlheapfree( pMemModule->GetHeap(), ptr );
183 };
184
185 m_Context.s_cbIdk = []( TMemoryDL* pMemModule, void* ptr, TSIZE size ) -> void {
186
187 };
188
189 m_GlobalHeap = CreateHeapInPlace( m_Context.s_Heap, m_GlobalSize, TMemoryHeapFlags_UseMutex, "global" );
190 return Error_Ok;
191}
192
194
195#endif // TMEMORY_USE_DLMALLOC
#define TASSERT(X,...)
Definition Defines.h:138
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
size_t TSIZE
Definition Typedefs.h:9
#define TNULL
Definition Typedefs.h:23
static void MemSet(void *ptr, TINT value, TSIZE size)
Definition TUtil.h:89