Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1005 barsuk 1
// memman.cpp : Defines the entry point for the console application.
2
//
3
 
4
#include "kosSyst.h"
5
#include "mcsmemm.h"
6
 
7
 
8
void * __cdecl operator new ( size_t count, size_t element_size )
9
{
10
	return allocmem( (Dword)(count * element_size) );
11
}
12
 
13
void * __cdecl operator new [] ( size_t amount )
14
{
15
	return allocmem( (Dword)amount );
16
}
17
 
18
void * __cdecl operator new ( size_t amount )
19
{
20
	return allocmem( (Dword)amount );
21
}
22
 
23
void __cdecl operator delete ( void *pointer )
24
{
25
	if ( pointer != NULL ) freemem( pointer );
26
}
27
 
28
void __cdecl operator delete [] ( void *pointer )
29
{
30
	if ( pointer != NULL ) freemem( pointer );
31
}
32
 
33
Byte *allocmem( Dword reqsize )
34
{
35
	__asm
36
	{
37
		mov eax, 68
38
		mov ebx, 12
39
		mov ecx, reqsize
40
		int 0x40
41
	}
42
 
43
}
44
 
45
Dword freemem( void *vaddress )
46
{
47
	__asm
48
	{
49
		mov eax, 68
50
		mov ebx, 13
51
		mov ecx, vaddress
52
		int 0x40
53
	}
54
 
55
}
56
/*
57
 
58
//
59
Dword mmMutex = FALSE;
60
MemBlock *rootfree = NULL;
61
MemBlock *rootuser = NULL;
62
bool mmInitialized = false;
63
Byte *mmHeapTop = NULL;
64
 
65
 
66
//
67
Byte * AllocMemFromSystem( Dword reqSize )
68
{
69
	Byte *result;
70
	sProcessInfo pInfo;
71
 
72
	//
73
	if ( mmInitialized )
74
	{
75
		result = mmHeapTop;
76
	}
77
	else
78
	{
79
		//
80
		kos_ProcessInfo( &pInfo );
81
		//
82
		result = (Byte *)(pInfo.processInfo.used_memory + 1);
83
		//
84
		mmInitialized = true;
85
	}
86
	//
87
	if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) )
88
	{
89
		result = NULL;
90
	}
91
	//
92
	mmHeapTop = result + reqSize;
93
	//
94
	return result;
95
}
96
 
97
 
98
//
99
Byte *allocmem( Dword reqsize )
100
{
101
  MemBlock *BlockForCheck;
102
  MemBlock *LastKnownGood;
103
  Dword tail;
104
  Byte *address;
105
 
106
  //подровняем размер
107
  if( ( tail = reqsize % SIZE_ALIGN ) != 0 )
108
  {
109
    reqsize += SIZE_ALIGN - tail;
110
  }
111
 
112
  LastKnownGood = NULL;
113
 
114
  // ждём освобождения мьютекса
115
  while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
116
  {
117
	  //
118
	  kos_Pause( 1 );
119
  }
120
 
121
  //ищем подходящий свободный блок
122
  if( rootfree != NULL )
123
  {
124
    for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next )
125
    {
126
      if ( BlockForCheck->Size >= reqsize )
127
      {
128
        //нашли
129
        if ( LastKnownGood != NULL )
130
        {
131
          if ( LastKnownGood->Size >= BlockForCheck->Size )
132
            LastKnownGood = BlockForCheck;
133
        }
134
        else
135
          LastKnownGood = BlockForCheck;
136
        if ( LastKnownGood->Size == reqsize )
137
          break;
138
      }
139
      if ( BlockForCheck->Next == NULL )
140
        break;
141
    }
142
  }
143
 
144
  if ( LastKnownGood != NULL )
145
  {
146
    //проверим найденный блок на возможность деления
147
    tail = LastKnownGood->Size - reqsize;
148
    if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) )
149
    {
150
      //будем разбивать
151
      BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail );
152
      BlockForCheck->Size = reqsize;
153
      //вставим занятый блок в начало списка занатых блоков
154
      if( rootuser != NULL )
155
      {
156
        BlockForCheck->Next = rootuser;
157
        rootuser->Previous = BlockForCheck;
158
        BlockForCheck->Previous = NULL;
159
        rootuser = BlockForCheck;
160
      }
161
      else
162
      {
163
        rootuser = BlockForCheck;
164
        BlockForCheck->Next = NULL;
165
        BlockForCheck->Previous = NULL;
166
      }
167
 
168
      //изменим размер оставшейся части
169
      LastKnownGood->Size = tail - sizeof(MemBlock);
170
      address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock);
171
 
172
	  // отпустим мьютекс
173
      rtlInterlockedExchange( &mmMutex, FALSE );
174
 
175
      return address;
176
    }
177
    else
178
    {
179
      //перемести блок из очереди свободных в начало очереди занятых
180
      //сначала выкинем его из очереди свободных
181
      if ( LastKnownGood->Previous != NULL )
182
      {
183
        LastKnownGood->Previous->Next = LastKnownGood->Next;
184
      }
185
      else
186
      {
187
        //блок стоит в начале очереди
188
        rootfree = LastKnownGood->Next;
189
      }
190
      if( LastKnownGood->Next != NULL )
191
      {
192
        LastKnownGood->Next->Previous = LastKnownGood->Previous;
193
      }
194
      //теперь вставим его в очередь занятых
195
      if( rootuser != NULL )
196
      {
197
        LastKnownGood->Next = rootuser;
198
        rootuser->Previous = LastKnownGood;
199
        LastKnownGood->Previous = NULL;
200
        rootuser = LastKnownGood;
201
      }
202
      else
203
      {
204
        rootuser = LastKnownGood;
205
        LastKnownGood->Next = NULL;
206
        LastKnownGood->Previous = NULL;
207
      }
208
	  //
209
      address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
210
 
211
	  // отпустим мьютекс
212
      rtlInterlockedExchange( &mmMutex, FALSE );
213
 
214
      return address;
215
    }
216
  }
217
  else
218
  {
219
    //надо получить ещё кусочек памяти
220
    LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) );
221
	//
222
    if( LastKnownGood != NULL )
223
    {
224
      LastKnownGood->Size = reqsize;
225
      //теперь вставим его в очередь занятых
226
      if( rootuser != NULL )
227
      {
228
        LastKnownGood->Next = rootuser;
229
        rootuser->Previous = LastKnownGood;
230
        LastKnownGood->Previous = NULL;
231
        rootuser = LastKnownGood;
232
      }
233
      else
234
      {
235
        rootuser = LastKnownGood;
236
        LastKnownGood->Next = NULL;
237
        LastKnownGood->Previous = NULL;
238
      }
239
      address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
240
 
241
	  // отпустим мьютекс
242
      rtlInterlockedExchange( &mmMutex, FALSE );
243
 
244
      return address;
245
    }
246
  }
247
 
248
  // отпустим мьютекс
249
  rtlInterlockedExchange( &mmMutex, FALSE );
250
 
251
  //
252
  rtlDebugOutString( "allocmem failed." );
253
  kos_ExitApp();
254
  //
255
  return NULL;
256
}
257
 
258
//
259
Dword freemem( void *vaddress )
260
{
261
  Dword result;
262
 
263
  Byte *checknext, *address = (Byte *)vaddress;
264
 
265
  // ждём освобождения мьютекса
266
  while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
267
  {
268
	  //
269
	  kos_Pause( 1 );
270
  }
271
 
272
  MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) );
273
 
274
  result = released->Size;
275
 
276
  //убираем блок из списка занятых
277
  if ( released->Previous != NULL )
278
  {
279
    released->Previous->Next = released->Next;
280
  }
281
  else
282
  {
283
    rootuser = released->Next;
284
  }
285
  if ( released->Next != NULL )
286
  {
287
    released->Next->Previous = released->Previous;
288
  }
289
  //закинем теперь этот блок в список свободных
290
  released->Next = rootfree;
291
  released->Previous = NULL;
292
  rootfree = released;
293
  if ( released->Next != NULL )
294
  {
295
    released->Next->Previous = released;
296
  }
297
 
298
  //теперь поищем смежные свободные блоки
299
  checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) );
300
  //
301
  for ( released = rootfree->Next; released != NULL; released = released->Next )
302
  {
303
    if ( checknext == (Byte *)released )
304
    {
305
      //собираем блоки вместе
306
      //сначала выкинем из очереди свободных
307
      released->Previous->Next = released->Next;
308
      if( released->Next != NULL )
309
      {
310
        released->Next->Previous = released->Previous;
311
      }
312
      //теперь увеличим размер корневого блока
313
      rootfree->Size += released->Size + sizeof(MemBlock);
314
      break;
315
    }
316
  }
317
  //если надо, поищем блоки перед текщим.
318
  checknext = (Byte *)(rootfree);
319
  //
320
  if ( released == NULL )
321
  {
322
    for ( released = rootfree->Next; released != NULL; released = released->Next )
323
    {
324
      if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) )
325
      {
326
        //собираем блоки вместе
327
        //увеличим размер блока
328
        released->Size += rootfree->Size + sizeof(MemBlock);
329
        //теперь выкинем из очереди свободных
330
        released->Previous->Next = released->Next;
331
        if ( released->Next != NULL )
332
        {
333
          released->Next->Previous = released->Previous;
334
        }
335
        //и закинем его в начало очереди вместо присоединённого блока из корня списка
336
        if ( rootfree->Next != NULL )
337
        {
338
          rootfree->Next->Previous = released;
339
        }
340
        released->Next = rootfree->Next;
341
        released->Previous = NULL;
342
        rootfree = released;
343
        break;
344
      }
345
    }
346
  }
347
 
348
  // отпустим мьютекс
349
  rtlInterlockedExchange( &mmMutex, FALSE );
350
 
351
  return result;
352
}
353
 
354
*/