Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1805 yogev_ezra 1
#ifndef __MEMORY_HEAP_RBTREE_H_INCLUDED_
2
#define __MEMORY_HEAP_RBTREE_H_INCLUDED_
3
 
4
namespace MemoryHeap
5
{
6
	typedef unsigned int TMemItem;
7
 
8
	enum {NumTreeSmall = 8 * sizeof(TMemItem)};
9
 
10
// Memory heap interface.
11
 
12
	struct TFreeSpace
13
	{
14
		TMemItem Small[NumTreeSmall], Min, SmallMask;
15
	};
16
 
17
	struct TMemBlock
18
	{
19
		TMemItem *Begin;
20
	};
21
 
22
	bool BlockValid(const TMemBlock &block);   // Is the given memory block valid?
23
	void *BlockBegin(const TMemBlock &block);   // Return the beginning address of the block.
24
	void *BlockEnd(const TMemBlock &block);   // Return the ending address of the block.
25
	TFreeSpace &BlockFreeSpace(const TMemBlock &block);   // Return the free space of the block.
26
 
27
	void InitFreeSpace(TFreeSpace &fs);   // Initialize the free space.
28
	TMemBlock NullBlock();   // Return null invalid block.
29
	TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs);
30
			// Create a memory block with the given begin and end and add free space of it to (fs),
31
			//_ give (BlockAddSize) bytes of the block for it's data.
32
			//_ (Program can alloc (end - begin - BlockAddSize) bytes after it,
33
			//_ that must be not less than (MemMinSize) ).
34
	TMemBlock CreateBlock(void *begin, void *end);
35
			// Create a memory block with the given begin and end and new free space for it,
36
			//_ give (BlockAddSizeFS) bytes of the block for it's data.
37
			//_ (Program can alloc (end - begin - BlockAddSizeFS) bytes after it,
38
			//_ that must be not less than (MemMinSize) ).
39
	void ResizeBlock(TMemBlock block, void *new_end);   // Resize the memory block to the given new end.
40
	void RemoveBlock(TMemBlock block);   // Remove the given memory block.
41
 
42
	void *BlockEndFor(TMemBlock block, unsigned int size);
43
			// Return the new end of the block needed for (ResizeBlock) to alloc the given size of memory.
44
	unsigned int BlockSize(TMemBlock block);   // Return the size of the given block.
45
	unsigned int MemSize(void *mem);   // Return the size of the allocced memory.
46
 
47
	void *Alloc(TFreeSpace &fs, unsigned int size);
48
			// Alloc a memory in the given free space, give (MemAddSize) bytes for it's data.
49
	void *ReAlloc(TFreeSpace &fs, unsigned int size, void *mem);
50
			// ReAlloc the given memory, it must lie in the block with the given free space.
51
	void Free(TFreeSpace &fs, void *mem);
52
			// Free the given memory, it must lie in the block with the given free space.
53
 
54
// Macro definitions.
55
 
56
#define MEMORY_HEAP_ALIGN_DOWN(s)  (MemoryHeap::TMemItem(s) & ~(MemoryHeap::MemAlign - 1))
57
#define MEMORY_HEAP_ALIGN_UP(s)    ((MemoryHeap::TMemItem(s) + (MemoryHeap::MemAlign - 1)) & ~(MemoryHeap::MemAlign - 1))
58
#define MEMORY_HEAP_ITEM(s,k)  ( ((MemoryHeap::TMemItem*)(s))[(k)] )
59
#define MEMORY_HEAP_NEXT(s)    (MEMORY_HEAP_ITEM((s),-1))
60
#define MEMORY_HEAP_PREV(s)    (MEMORY_HEAP_ITEM((s),-2))
61
#define MEMORY_HEAP_FREE(s)    (MEMORY_HEAP_ITEM((s),-1) & 1)
62
 
63
// Constants.
64
 
65
	enum {MemAlign = sizeof(TMemItem)};
66
	enum {MemAddSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))};
67
	enum {BlockEndSize = MemAddSize};
68
	enum {BlockAddSize = MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)) + BlockEndSize};
69
	enum {BlockAddSizeFS = BlockAddSize + BlockEndSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace))};
70
	enum {MemMinSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))};
71
 
72
// Inline functions.
73
 
74
	inline bool BlockValid(const TMemBlock &block) {return block.Begin != 0;}
75
 
76
	inline void *BlockBegin(const TMemBlock &block) {return (void*)block.Begin;}
77
 
78
	inline void *BlockEnd(const TMemBlock &block) {return block.Begin ? (void*)block.Begin[1] : 0;}
79
 
80
	inline TFreeSpace &BlockFreeSpace(const TMemBlock &block) {return *(TFreeSpace*)block.Begin[0];}
81
 
82
	inline TMemBlock NullBlock() {TMemBlock block; block.Begin = 0; return block;}
83
 
84
	inline void *BlockEndFor(TMemBlock block, unsigned int size)
85
	{
86
		TMemItem last = (TMemItem)block.Begin[1];
87
		TMemItem prevlast = MEMORY_HEAP_PREV(last);
88
		return (void*)( (MEMORY_HEAP_FREE(prevlast) ? prevlast : last) + MemAddSize +
89
						((size <= MemMinSize) ? MemMinSize : MEMORY_HEAP_ALIGN_UP(size)) );
90
	}
91
 
92
	inline unsigned int BlockSize(TMemBlock block)
93
	{
94
		if (!block.Begin) return 0;
95
		return (unsigned int)(block.Begin[1] - (TMemItem)block.Begin);
96
	}
97
 
98
	inline unsigned int MemSize(void *mem)
99
	{
100
		if (!mem) return 0;
101
		TMemItem c = (TMemItem)mem;
102
		return MEMORY_HEAP_NEXT(c) - c - MemAddSize;
103
	}
104
 
105
// Free space item functions.
106
 
107
	TMemItem _FirstNotZeroBit(TMemItem i)
108
	{
109
		TMemItem r = 0;
110
		while ((i >>= 1) != 0) r++;
111
		return r;
112
	}
113
 
114
	void _RBTreeRotate(TMemItem parent, TMemItem item, int side)
115
	{
116
		TMemItem temp = MEMORY_HEAP_ITEM(parent,0);
117
		MEMORY_HEAP_ITEM(item,0) = temp;
118
		if (temp)
119
		{
120
			if (MEMORY_HEAP_ITEM(temp,2) == parent)
121
			{
122
				MEMORY_HEAP_ITEM(temp,2) = item;
123
			}
124
			else MEMORY_HEAP_ITEM(temp,3) = item;
125
		}
126
		temp = MEMORY_HEAP_ITEM(item,side^1);
127
		if (temp) MEMORY_HEAP_ITEM(temp,0) = parent;
128
		MEMORY_HEAP_ITEM(parent,side) = temp;
129
		MEMORY_HEAP_ITEM(parent,0) = item;
130
		MEMORY_HEAP_ITEM(item,side^1) = parent;
131
		temp = MEMORY_HEAP_ITEM(parent,1);
132
		MEMORY_HEAP_ITEM(parent,1) = MEMORY_HEAP_ITEM(item,1);
133
		MEMORY_HEAP_ITEM(item,1) = temp;
134
	}
135
 
136
	void InitFreeSpace(TFreeSpace &fs)
137
	{
138
		TMemItem i;
139
		for (i = 0; i <= NumTreeSmall; i++) fs.Small[i] = 0;
140
		fs.Min = 0; fs.SmallMask = 0;
141
	}
142
 
143
	void _FreeAdd(TFreeSpace &fs, TMemItem item)
144
	{
145
		TMemItem size = MEMORY_HEAP_NEXT(item) - item;
146
		if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall)
147
		{
148
			TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign;
149
			TMemItem &addto = fs.Small[s];
150
			MEMORY_HEAP_ITEM(item,1) = (TMemItem)(&addto);
151
			MEMORY_HEAP_ITEM(item,0) = (TMemItem)addto;
152
			if (addto) MEMORY_HEAP_ITEM(addto,1) = item;
153
			addto = item;
154
			fs.SmallMask |= TMemItem(1) << s;
155
			return;
156
		}
157
		TMemItem addto = fs.Min, parent, temp;
158
		MEMORY_HEAP_ITEM(item,2) = 0;
159
		MEMORY_HEAP_ITEM(item,3) = 0;
160
		if (!addto)
161
		{
162
			MEMORY_HEAP_ITEM(item,0) = 0;
163
			MEMORY_HEAP_ITEM(item,1) = 1;
164
			fs.Min = item;
165
			return;
166
		}
167
		MEMORY_HEAP_ITEM(item,1) = 0;
168
		TMemItem side = 2;
169
		if (MEMORY_HEAP_NEXT(addto) - addto >= size) fs.Min = item;
170
		else
171
		{
172
			for (;;)
173
			{
174
				parent = MEMORY_HEAP_ITEM(addto,0);
175
				if (!parent) break;
176
				if (MEMORY_HEAP_NEXT(parent) - parent < size) addto = parent;
177
				else break;
178
			}
179
			for (;;)
180
			{
181
				if (MEMORY_HEAP_NEXT(addto) - addto < size)
182
				{
183
					temp = MEMORY_HEAP_ITEM(addto,3);
184
					if (!temp) {side = 3; break;}
185
					addto = temp;
186
				}
187
				else
188
				{
189
					temp = MEMORY_HEAP_ITEM(addto,2);
190
					if (!temp) break;
191
					addto = temp;
192
				}
193
			}
194
		}
195
		MEMORY_HEAP_ITEM(item,0) = addto;
196
		MEMORY_HEAP_ITEM(addto,side) = item;
197
		for (;;)
198
		{
199
			if (MEMORY_HEAP_ITEM(addto,1) != 0) return;
200
			parent = MEMORY_HEAP_ITEM(addto,0);
201
			temp = MEMORY_HEAP_ITEM(parent,2);
202
			if (temp == addto)
203
			{
204
				temp = MEMORY_HEAP_ITEM(parent,3);
205
				side = 2;
206
			}
207
			else side = 3;
208
			if (!temp || MEMORY_HEAP_ITEM(temp,1) != 0) break;
209
			MEMORY_HEAP_ITEM(addto,1) = 1;
210
			MEMORY_HEAP_ITEM(temp,1) = 1;
211
			item = parent;
212
			addto = MEMORY_HEAP_ITEM(item,0);
213
			if (!addto) return;
214
			MEMORY_HEAP_ITEM(item,1) = 0;
215
		}
216
		if (MEMORY_HEAP_ITEM(addto,side) != item)
217
		{
218
			temp = MEMORY_HEAP_ITEM(item,side);
219
			if (temp) MEMORY_HEAP_ITEM(temp,0) = addto;
220
			MEMORY_HEAP_ITEM(addto,side^1) = temp;
221
			MEMORY_HEAP_ITEM(addto,0) = item;
222
			MEMORY_HEAP_ITEM(item,side) = addto;
223
			MEMORY_HEAP_ITEM(item,0) = parent;
224
			MEMORY_HEAP_ITEM(parent,side) = item;
225
		}
226
		else item = addto;
227
		_RBTreeRotate(parent, item, side);
228
	}
229
 
230
	void _FreeDel(TFreeSpace &fs, TMemItem item)
231
	{
232
		TMemItem size = MEMORY_HEAP_NEXT(item) - item;
233
		if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall)
234
		{
235
			TMemItem prev = MEMORY_HEAP_ITEM(item,1);
236
			TMemItem next = MEMORY_HEAP_ITEM(item,0);
237
			MEMORY_HEAP_ITEM(prev,0) = next;
238
			if (next) MEMORY_HEAP_ITEM(next,1) = prev;
239
			else
240
			{
241
				TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign;
242
				if (!fs.Small[s]) fs.SmallMask &= ~(TMemItem(1) << s);
243
			}
244
			return;
245
		}
246
		TMemItem parent, temp, second, add;
247
		TMemItem side = 2;
248
		temp = MEMORY_HEAP_ITEM(item,3);
249
		if (temp)
250
		{
251
			for (;;)
252
			{
253
				second = temp;
254
				temp = MEMORY_HEAP_ITEM(temp,2);
255
				if (!temp) break;
256
			}
257
			if (fs.Min == item) fs.Min = second;
258
			add = MEMORY_HEAP_ITEM(second,3);
259
			parent = MEMORY_HEAP_ITEM(second,0);
260
			if (parent == item) {parent = second; side = 3;}
261
			else
262
			{
263
				temp = MEMORY_HEAP_ITEM(item,3);
264
				MEMORY_HEAP_ITEM(second,3) = temp;
265
				MEMORY_HEAP_ITEM(temp,0) = second;
266
			}
267
			temp = MEMORY_HEAP_ITEM(item,2);
268
			MEMORY_HEAP_ITEM(second,2) = temp;
269
			if (temp) MEMORY_HEAP_ITEM(temp,0) = second;
270
			temp = MEMORY_HEAP_ITEM(item,0);
271
			MEMORY_HEAP_ITEM(second,0) = temp;
272
			if (temp)
273
			{
274
				if (MEMORY_HEAP_ITEM(temp,2) == item)
275
				{
276
					MEMORY_HEAP_ITEM(temp,2) = second;
277
				}
278
				else MEMORY_HEAP_ITEM(temp,3) = second;
279
			}
280
			MEMORY_HEAP_ITEM(parent,side) = add;
281
			if (add) MEMORY_HEAP_ITEM(add,0) = parent;
282
			bool color = MEMORY_HEAP_ITEM(second,1);
283
			MEMORY_HEAP_ITEM(second,1) = MEMORY_HEAP_ITEM(item,1);
284
			if (!color) return;
285
		}
286
		else
287
		{
288
			if (fs.Min == item) fs.Min = MEMORY_HEAP_ITEM(item,0);
289
			add = MEMORY_HEAP_ITEM(item,2);
290
			parent = MEMORY_HEAP_ITEM(item,0);
291
			if (add) MEMORY_HEAP_ITEM(add,0) = parent;
292
			if (parent)
293
			{
294
				if (MEMORY_HEAP_ITEM(parent,2) == item)
295
				{
296
					MEMORY_HEAP_ITEM(parent,2) = add;
297
				}
298
				else
299
				{
300
					MEMORY_HEAP_ITEM(parent,3) = add;
301
					side = 3;
302
				}
303
			}
304
			else
305
			{
306
				if (add) MEMORY_HEAP_ITEM(add,1) = 1;
307
				return;
308
			}
309
			if (!MEMORY_HEAP_ITEM(item,1)) return;
310
		}
311
		if (add && !MEMORY_HEAP_ITEM(add,1))
312
		{
313
			MEMORY_HEAP_ITEM(add,1) = 1;
314
			return;
315
		}
316
		for (;;)
317
		{
318
			second = MEMORY_HEAP_ITEM(parent,side^1);
319
			if (!MEMORY_HEAP_ITEM(second,1))
320
			{
321
				_RBTreeRotate(parent, second, side^1);
322
				second = MEMORY_HEAP_ITEM(parent,side^1);
323
			}
324
			temp = MEMORY_HEAP_ITEM(second,side^1);
325
			if (temp && !MEMORY_HEAP_ITEM(temp,1))
326
			{
327
				MEMORY_HEAP_ITEM(temp,1) = 1;
328
				break;
329
			}
330
			temp = MEMORY_HEAP_ITEM(second,side);
331
			if (temp && !MEMORY_HEAP_ITEM(temp,1))
332
			{
333
				_RBTreeRotate(second, temp, side);
334
				MEMORY_HEAP_ITEM(second,1) = 1;
335
				second = temp;
336
				break;
337
			}
338
			MEMORY_HEAP_ITEM(second,1) = 0;
339
			if (!MEMORY_HEAP_ITEM(parent,1))
340
			{
341
				MEMORY_HEAP_ITEM(parent,1) = 1;
342
				return;
343
			}
344
			second = parent;
345
			parent = MEMORY_HEAP_ITEM(second,0);
346
			if (!parent) return;
347
			if (MEMORY_HEAP_ITEM(parent,2) == second) side = 2;
348
			else side = 3;
349
		}
350
		_RBTreeRotate(parent, second, side^1);
351
	}
352
 
353
	TMemItem _FreeFindAfter(TMemItem item, TMemItem size)
354
	{
355
		if (!item) return 0;
356
		TMemItem paritem, s;
357
		if (MEMORY_HEAP_NEXT(item) - item >= size) return item;
358
		for (;;)
359
		{
360
			paritem = MEMORY_HEAP_ITEM(item,0);
361
			if (!paritem) break;
362
			s = MEMORY_HEAP_NEXT(paritem) - paritem;
363
			if (s == size) return paritem;
364
			if (s < size) item = paritem;
365
			else break;
366
		}
367
		MEMORY_HEAP_ITEM(item,3);
368
		for (;;)
369
		{
370
			if (!item) return paritem;
371
			s = MEMORY_HEAP_NEXT(item) - item;
372
			if (s == size) return item;
373
			if (s < size) item = MEMORY_HEAP_ITEM(item,3);
374
			else
375
			{
376
				paritem = item;
377
				item = MEMORY_HEAP_ITEM(item,2);
378
			}
379
		}
380
	}
381
 
382
	TMemItem _FreeFind(TFreeSpace &fs, TMemItem size)
383
	{
384
		TMemItem item, nextitem, s;
385
		if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall)
386
		{
387
			TMemItem m, t;
388
			s = (size - (MemAddSize + MemMinSize)) / MemAlign;
389
			item = fs.Small[s];
390
			if (item) return item;
391
			if (size < MemAlign * NumTreeSmall)
392
			{
393
				t = size / MemAlign;
394
				m = fs.SmallMask >> t;
395
				if (m) return fs.Small[t + _FirstNotZeroBit(m)];
396
				else if (fs.Min) return fs.Min;
397
			}
398
			else
399
			{
400
				item = _FreeFindAfter(fs.Min, size + 1 + MemAddSize + MemMinSize);
401
				if (item) return item;
402
			}
403
			m = fs.SmallMask >> s;
404
			if (m) return fs.Small[s + _FirstNotZeroBit(m)];
405
			else return fs.Min;
406
		}
407
		item = _FreeFindAfter(fs.Min, ++size);
408
		if (!item) return 0;
409
		s = MEMORY_HEAP_NEXT(item) - item;
410
		if (s == size) return item;
411
		size += MemAddSize + MemMinSize;
412
		if (s >= size) return item;
413
		nextitem = _FreeFindAfter(item, size);
414
		return nextitem ? nextitem : item;
415
	}
416
 
417
// Block functions.
418
 
419
	inline void _CreateBlockEnd(TMemBlock &block, TFreeSpace &fs, TMemItem c, TMemItem e)
420
	{
421
		block.Begin[0] = (TMemItem)(&fs);
422
		if (e - c < TMemItem(MemAddSize + MemMinSize))
423
		{
424
			MEMORY_HEAP_NEXT(c) = 0;
425
			block.Begin[1] = c;
426
		}
427
		else
428
		{
429
			MEMORY_HEAP_NEXT(c) = e + 1;
430
			_FreeAdd(fs, c);
431
			MEMORY_HEAP_PREV(e) = c;
432
			MEMORY_HEAP_NEXT(e) = 0;
433
			block.Begin[1] = e;
434
		}
435
	}
436
 
437
	TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs)
438
	{
439
		TMemBlock block = {0};
440
		TMemItem b = MEMORY_HEAP_ALIGN_UP(begin);
441
		TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end);
442
		if (e <= b || e - b < TMemItem(BlockAddSize - MemAddSize)) return block;
443
		block.Begin = (TMemItem*)b;
444
		b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem));
445
		MEMORY_HEAP_PREV(b) = 0;
446
		_CreateBlockEnd(block, fs, b, e);
447
		return block;
448
	}
449
 
450
	TMemBlock CreateBlock(void *begin, void *end)
451
	{
452
		TMemBlock block = {0};
453
		TMemItem b = MEMORY_HEAP_ALIGN_UP(begin);
454
		TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end);
455
		if (e <= b || e - b < TMemItem(BlockAddSizeFS - MemAddSize)) return block;
456
		block.Begin = (TMemItem*)b;
457
		b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem));
458
		TMemItem c = b + MemAddSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace));
459
		MEMORY_HEAP_PREV(b) = 0;
460
		MEMORY_HEAP_NEXT(b) = c;
461
		MEMORY_HEAP_PREV(c) = b;
462
		InitFreeSpace(*(TFreeSpace*)b);
463
		_CreateBlockEnd(block, *(TFreeSpace*)b, c, e);
464
		return block;
465
	}
466
 
467
	void ResizeBlock(TMemBlock block, void *new_end)
468
	{
469
		if (!BlockValid(block)) return;
470
		TMemItem e = MEMORY_HEAP_ALIGN_DOWN(new_end);
471
		TMemItem c = block.Begin[1];
472
		TFreeSpace &fs = *(TFreeSpace*)block.Begin[0];
473
		do
474
		{
475
			if (c == e) return;
476
			else if (c > e)
477
			{
478
				while ((c = MEMORY_HEAP_PREV(c)) > e)
479
				{
480
					if (MEMORY_HEAP_FREE(c)) _FreeDel(fs, c);
481
				}
482
				if (!c) {block.Begin = 0; return;}
483
				if (MEMORY_HEAP_FREE(c))
484
				{
485
					_FreeDel(fs, c);
486
					if (e - c < TMemItem(MemAddSize + MemMinSize)) e = c;
487
					else
488
					{
489
						MEMORY_HEAP_NEXT(c) = e + 1;
490
						_FreeAdd(*(TFreeSpace*)block.Begin[0], c);
491
						break;
492
					}
493
				}
494
				else if (e - c >= TMemItem(MemAddSize + MemMinSize))
495
				{
496
					MEMORY_HEAP_NEXT(c) = e; break;
497
				}
498
				MEMORY_HEAP_NEXT(c) = 0;
499
				block.Begin[1] = c;
500
				if (c == e) return;
501
			}
502
			TMemItem pc = MEMORY_HEAP_PREV(c);
503
			if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc);
504
			else if (e - c < TMemItem(MemAddSize + MemMinSize)) return;
505
			MEMORY_HEAP_NEXT(c) = e + 1;
506
			_FreeAdd(fs, c);
507
		} while(false);
508
		MEMORY_HEAP_PREV(e) = c;
509
		MEMORY_HEAP_NEXT(e) = 0;
510
		block.Begin[1] = e;
511
	}
512
 
513
	void RemoveBlock(TMemBlock block)
514
	{
515
		if (!BlockValid(block)) return;
516
		TMemItem e = block.Begin[1];
517
		TFreeSpace &fs = *(TFreeSpace*)block.Begin[0];
518
		while ((e = MEMORY_HEAP_PREV(e)) != 0)
519
		{
520
			if (MEMORY_HEAP_FREE(e)) _FreeDel(fs, e);
521
		}
522
		block.Begin = 0;
523
	}
524
 
525
// Free space functions.
526
 
527
	void _CopyMemItemArray(TMemItem dest, TMemItem src, TMemItem end)
528
	{
529
		TMemItem k = (end - src) / sizeof(TMemItem);
530
		TMemItem *d = (TMemItem*)dest;
531
		TMemItem *s = (TMemItem*)src;
532
		while (k--) *(d++) = *(s++);
533
	}
534
 
535
	void *Alloc(TFreeSpace &fs, unsigned int size)
536
	{
537
		if (!size) return 0;
538
		TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize;
539
		if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize;
540
		TMemItem c = _FreeFind(fs, s);
541
		if (!c) return 0;
542
		_FreeDel(fs, c);
543
		TMemItem nc = --MEMORY_HEAP_NEXT(c);
544
		TMemItem mc = c + s;
545
		if (nc - (MemAddSize + MemMinSize) >= mc)
546
		{
547
			MEMORY_HEAP_NEXT(c) = mc;
548
			MEMORY_HEAP_PREV(mc) = c;
549
			MEMORY_HEAP_NEXT(mc) = nc + 1;
550
			MEMORY_HEAP_PREV(nc) = mc;
551
			_FreeAdd(fs, mc);
552
		}
553
		return (void*)c;
554
	}
555
 
556
	void *ReAlloc(TFreeSpace &fs, void *mem, unsigned int size)
557
	{
558
		if (!mem) return Alloc(fs, size);
559
		if (!size) {Free(fs, mem); return 0;}
560
		TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize;
561
		TMemItem c = (TMemItem)mem;
562
		TMemItem mc = MEMORY_HEAP_NEXT(c);
563
		TMemItem nc = MEMORY_HEAP_NEXT(mc);
564
		if (--nc & 1) nc = mc;
565
		if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize;
566
		if (nc - c < s)
567
		{
568
			mem = Alloc(fs, size);
569
			if (mem)
570
			{
571
				_CopyMemItemArray((TMemItem)mem, c, mc - MemAddSize);
572
				Free(fs, (void*)c);
573
				return mem;
574
			}
575
			else
576
			{
577
				TMemItem pc = MEMORY_HEAP_PREV(c);
578
				if (pc && MEMORY_HEAP_FREE(pc) && nc - pc >= s)
579
				{
580
					_FreeDel(fs, pc);
581
					_CopyMemItemArray(pc, c, mc - MemAddSize);
582
					c = pc;
583
				}
584
				else return 0;
585
			}
586
		}
587
		if (mc < nc) _FreeDel(fs, mc);
588
		mc = c + s;
589
		if (nc - (MemAddSize + MemMinSize) >= mc)
590
		{
591
			MEMORY_HEAP_NEXT(c) = mc;
592
			MEMORY_HEAP_PREV(mc) = c;
593
			MEMORY_HEAP_NEXT(mc) = nc + 1;
594
			MEMORY_HEAP_PREV(nc) = mc;
595
			_FreeAdd(fs, mc);
596
		}
597
		else
598
		{
599
			MEMORY_HEAP_NEXT(c) = nc;
600
			MEMORY_HEAP_PREV(nc) = c;
601
		}
602
		return (void*)c;
603
	}
604
 
605
	int free_a = 0;
606
 
607
	void Free(TFreeSpace &fs, void *mem)
608
	{
609
		TMemItem c = (TMemItem)mem;
610
		if (!c) return;
611
		TMemItem pc = MEMORY_HEAP_PREV(c);
612
		TMemItem mc = MEMORY_HEAP_NEXT(c);
613
		TMemItem nc = MEMORY_HEAP_NEXT(mc);
614
		if (--nc & 1) nc = mc;
615
		else _FreeDel(fs, mc);
616
		if (free_a == 1) return;
617
		if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc);
618
		MEMORY_HEAP_NEXT(c) = nc + 1;
619
		MEMORY_HEAP_PREV(nc) = c;
620
		if (free_a == 2) return;
621
		_FreeAdd(fs, c);
622
	}
623
}
624
 
625
#endif  // ndef __MEMORY_HEAP_RBTREE_H_INCLUDED_
626