[docs] Replace cyrillic 'с' with latin 'c' in register names
[kolibrios.git] / programs / other / graph / mcsmemm.cpp
blob8073a0e7039e29390d99e8c9b2e2579eae3c927b
1 // memman.cpp : Defines the entry point for the console application.
2 //
4 #include "kosSyst.h"
5 #include "mcsmemm.h"
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 )
35 __asm
37 mov eax, 68
38 mov ebx, 12
39 mov ecx, reqsize
40 int 0x40
45 Dword freemem( void *vaddress )
47 __asm
49 mov eax, 68
50 mov ebx, 13
51 mov ecx, vaddress
52 int 0x40
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 )
69 Byte *result;
70 sProcessInfo pInfo;
73 if ( mmInitialized )
75 result = mmHeapTop;
77 else
80 kos_ProcessInfo( &pInfo );
82 result = (Byte *)(pInfo.processInfo.used_memory + 1);
84 mmInitialized = true;
87 if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) )
89 result = NULL;
92 mmHeapTop = result + reqSize;
94 return result;
99 Byte *allocmem( Dword reqsize )
101 MemBlock *BlockForCheck;
102 MemBlock *LastKnownGood;
103 Dword tail;
104 Byte *address;
106 //ïîäðîâíÿåì ðàçìåð
107 if( ( tail = reqsize % SIZE_ALIGN ) != 0 )
109 reqsize += SIZE_ALIGN - tail;
112 LastKnownGood = NULL;
114 // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
115 while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
118 kos_Pause( 1 );
121 //èùåì ïîäõîäÿùèé ñâîáîäíûé áëîê
122 if( rootfree != NULL )
124 for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next )
126 if ( BlockForCheck->Size >= reqsize )
128 //íàøëè
129 if ( LastKnownGood != NULL )
131 if ( LastKnownGood->Size >= BlockForCheck->Size )
132 LastKnownGood = BlockForCheck;
134 else
135 LastKnownGood = BlockForCheck;
136 if ( LastKnownGood->Size == reqsize )
137 break;
139 if ( BlockForCheck->Next == NULL )
140 break;
144 if ( LastKnownGood != NULL )
146 //ïðîâåðèì íàéäåííûé áëîê íà âîçìîæíîñòü äåëåíèÿ
147 tail = LastKnownGood->Size - reqsize;
148 if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) )
150 //áóäåì ðàçáèâàòü
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;
161 else
163 rootuser = BlockForCheck;
164 BlockForCheck->Next = NULL;
165 BlockForCheck->Previous = NULL;
168 //èçìåíèì ðàçìåð îñòàâøåéñÿ ÷àñòè
169 LastKnownGood->Size = tail - sizeof(MemBlock);
170 address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock);
172 // îòïóñòèì ìüþòåêñ
173 rtlInterlockedExchange( &mmMutex, FALSE );
175 return address;
177 else
179 //ïåðåìåñòè áëîê èç î÷åðåäè ñâîáîäíûõ â íà÷àëî î÷åðåäè çàíÿòûõ
180 //ñíà÷àëà âûêèíåì åãî èç î÷åðåäè ñâîáîäíûõ
181 if ( LastKnownGood->Previous != NULL )
183 LastKnownGood->Previous->Next = LastKnownGood->Next;
185 else
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;
202 else
204 rootuser = LastKnownGood;
205 LastKnownGood->Next = NULL;
206 LastKnownGood->Previous = NULL;
209 address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
211 // îòïóñòèì ìüþòåêñ
212 rtlInterlockedExchange( &mmMutex, FALSE );
214 return address;
217 else
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;
233 else
235 rootuser = LastKnownGood;
236 LastKnownGood->Next = NULL;
237 LastKnownGood->Previous = NULL;
239 address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
241 // îòïóñòèì ìüþòåêñ
242 rtlInterlockedExchange( &mmMutex, FALSE );
244 return address;
248 // îòïóñòèì ìüþòåêñ
249 rtlInterlockedExchange( &mmMutex, FALSE );
252 rtlDebugOutString( "allocmem failed." );
253 kos_ExitApp();
255 return NULL;
259 Dword freemem( void *vaddress )
261 Dword result;
263 Byte *checknext, *address = (Byte *)vaddress;
265 // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
266 while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
269 kos_Pause( 1 );
272 MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) );
274 result = released->Size;
276 //óáèðàåì áëîê èç ñïèñêà çàíÿòûõ
277 if ( released->Previous != NULL )
279 released->Previous->Next = released->Next;
281 else
283 rootuser = released->Next;
285 if ( released->Next != NULL )
287 released->Next->Previous = released->Previous;
289 //çàêèíåì òåïåðü ýòîò áëîê â ñïèñîê ñâîáîäíûõ
290 released->Next = rootfree;
291 released->Previous = NULL;
292 rootfree = released;
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);
314 break;
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;
342 rootfree = released;
343 break;
348 // îòïóñòèì ìüþòåêñ
349 rtlInterlockedExchange( &mmMutex, FALSE );
351 return result;