1 // memman.cpp : Defines the entry point for the console application.
8 void * __cdecl
operator new ( size_t count
, size_t element_size
)
10 return allocmem( (Dword
)(count
* element_size
) );
13 void * __cdecl
operator new [] ( size_t amount
)
15 return allocmem( (Dword
)amount
);
18 void * __cdecl
operator new ( size_t amount
)
20 return allocmem( (Dword
)amount
);
23 void __cdecl
operator delete ( void *pointer
)
25 if ( pointer
!= NULL
) freemem( pointer
);
28 void __cdecl
operator delete [] ( void *pointer
)
30 if ( pointer
!= NULL
) freemem( pointer
);
33 Byte
*allocmem( Dword reqsize
)
45 Dword
freemem( void *vaddress
)
59 Dword mmMutex = FALSE;
60 MemBlock *rootfree = NULL;
61 MemBlock *rootuser = NULL;
62 bool mmInitialized = false;
63 Byte *mmHeapTop = NULL;
67 Byte * AllocMemFromSystem( Dword reqSize )
80 kos_ProcessInfo( &pInfo );
82 result = (Byte *)(pInfo.processInfo.used_memory + 1);
87 if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) )
92 mmHeapTop = result + reqSize;
99 Byte *allocmem( Dword reqsize )
101 MemBlock *BlockForCheck;
102 MemBlock *LastKnownGood;
107 if( ( tail = reqsize % SIZE_ALIGN ) != 0 )
109 reqsize += SIZE_ALIGN - tail;
112 LastKnownGood = NULL;
114 // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
115 while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
121 //èùåì ïîäõîäÿùèé ñâîáîäíûé áëîê
122 if( rootfree != NULL )
124 for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next )
126 if ( BlockForCheck->Size >= reqsize )
129 if ( LastKnownGood != NULL )
131 if ( LastKnownGood->Size >= BlockForCheck->Size )
132 LastKnownGood = BlockForCheck;
135 LastKnownGood = BlockForCheck;
136 if ( LastKnownGood->Size == reqsize )
139 if ( BlockForCheck->Next == NULL )
144 if ( LastKnownGood != NULL )
146 //ïðîâåðèì íàéäåííûé áëîê íà âîçìîæíîñòü äåëåíèÿ
147 tail = LastKnownGood->Size - reqsize;
148 if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) )
151 BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail );
152 BlockForCheck->Size = reqsize;
153 //âñòàâèì çàíÿòûé áëîê â íà÷àëî ñïèñêà çàíàòûõ áëîêîâ
154 if( rootuser != NULL )
156 BlockForCheck->Next = rootuser;
157 rootuser->Previous = BlockForCheck;
158 BlockForCheck->Previous = NULL;
159 rootuser = BlockForCheck;
163 rootuser = BlockForCheck;
164 BlockForCheck->Next = NULL;
165 BlockForCheck->Previous = NULL;
168 //èçìåíèì ðàçìåð îñòàâøåéñÿ ÷àñòè
169 LastKnownGood->Size = tail - sizeof(MemBlock);
170 address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock);
173 rtlInterlockedExchange( &mmMutex, FALSE );
179 //ïåðåìåñòè áëîê èç î÷åðåäè ñâîáîäíûõ â íà÷àëî î÷åðåäè çàíÿòûõ
180 //ñíà÷àëà âûêèíåì åãî èç î÷åðåäè ñâîáîäíûõ
181 if ( LastKnownGood->Previous != NULL )
183 LastKnownGood->Previous->Next = LastKnownGood->Next;
187 //áëîê ñòîèò â íà÷àëå î÷åðåäè
188 rootfree = LastKnownGood->Next;
190 if( LastKnownGood->Next != NULL )
192 LastKnownGood->Next->Previous = LastKnownGood->Previous;
194 //òåïåðü âñòàâèì åãî â î÷åðåäü çàíÿòûõ
195 if( rootuser != NULL )
197 LastKnownGood->Next = rootuser;
198 rootuser->Previous = LastKnownGood;
199 LastKnownGood->Previous = NULL;
200 rootuser = LastKnownGood;
204 rootuser = LastKnownGood;
205 LastKnownGood->Next = NULL;
206 LastKnownGood->Previous = NULL;
209 address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
212 rtlInterlockedExchange( &mmMutex, FALSE );
219 //íàäî ïîëó÷èòü åù¸ êóñî÷åê ïàìÿòè
220 LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) );
222 if( LastKnownGood != NULL )
224 LastKnownGood->Size = reqsize;
225 //òåïåðü âñòàâèì åãî â î÷åðåäü çàíÿòûõ
226 if( rootuser != NULL )
228 LastKnownGood->Next = rootuser;
229 rootuser->Previous = LastKnownGood;
230 LastKnownGood->Previous = NULL;
231 rootuser = LastKnownGood;
235 rootuser = LastKnownGood;
236 LastKnownGood->Next = NULL;
237 LastKnownGood->Previous = NULL;
239 address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
242 rtlInterlockedExchange( &mmMutex, FALSE );
249 rtlInterlockedExchange( &mmMutex, FALSE );
252 rtlDebugOutString( "allocmem failed." );
259 Dword freemem( void *vaddress )
263 Byte *checknext, *address = (Byte *)vaddress;
265 // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
266 while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
272 MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) );
274 result = released->Size;
276 //óáèðàåì áëîê èç ñïèñêà çàíÿòûõ
277 if ( released->Previous != NULL )
279 released->Previous->Next = released->Next;
283 rootuser = released->Next;
285 if ( released->Next != NULL )
287 released->Next->Previous = released->Previous;
289 //çàêèíåì òåïåðü ýòîò áëîê â ñïèñîê ñâîáîäíûõ
290 released->Next = rootfree;
291 released->Previous = NULL;
293 if ( released->Next != NULL )
295 released->Next->Previous = released;
298 //òåïåðü ïîèùåì ñìåæíûå ñâîáîäíûå áëîêè
299 checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) );
301 for ( released = rootfree->Next; released != NULL; released = released->Next )
303 if ( checknext == (Byte *)released )
305 //ñîáèðàåì áëîêè âìåñòå
306 //ñíà÷àëà âûêèíåì èç î÷åðåäè ñâîáîäíûõ
307 released->Previous->Next = released->Next;
308 if( released->Next != NULL )
310 released->Next->Previous = released->Previous;
312 //òåïåðü óâåëè÷èì ðàçìåð êîðíåâîãî áëîêà
313 rootfree->Size += released->Size + sizeof(MemBlock);
317 //åñëè íàäî, ïîèùåì áëîêè ïåðåä òåêùèì.
318 checknext = (Byte *)(rootfree);
320 if ( released == NULL )
322 for ( released = rootfree->Next; released != NULL; released = released->Next )
324 if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) )
326 //ñîáèðàåì áëîêè âìåñòå
327 //óâåëè÷èì ðàçìåð áëîêà
328 released->Size += rootfree->Size + sizeof(MemBlock);
329 //òåïåðü âûêèíåì èç î÷åðåäè ñâîáîäíûõ
330 released->Previous->Next = released->Next;
331 if ( released->Next != NULL )
333 released->Next->Previous = released->Previous;
335 //è çàêèíåì åãî â íà÷àëî î÷åðåäè âìåñòî ïðèñîåäèí¸ííîãî áëîêà èç êîðíÿ ñïèñêà
336 if ( rootfree->Next != NULL )
338 rootfree->Next->Previous = released;
340 released->Next = rootfree->Next;
341 released->Previous = NULL;
349 rtlInterlockedExchange( &mmMutex, FALSE );