Subversion Repositories Kolibri OS

Rev

Rev 1769 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1769 Rev 8184
Line 1... Line 1...
1
#ifndef __MEMORY_HEAP_RBTREE_H_INCLUDED_
1
#ifndef __MEMORY_HEAP_H_INCLUDED_
2
#define __MEMORY_HEAP_RBTREE_H_INCLUDED_
2
#define __MEMORY_HEAP_H_INCLUDED_
Line 3... Line 3...
3
 
3
 
4
namespace MemoryHeap
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
	{
5
{
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
 
6
	long mem_Init();
47
	void *Alloc(TFreeSpace &fs, unsigned int size);
-
 
48
			// Alloc a memory in the given free space, give (MemAddSize) bytes for it's data.
7
	void *mem_Alloc(unsigned long size);
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.
8
	void *mem_ReAlloc(unsigned long size, void *mem);
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
	}
9
	bool mem_Free(void *mem);
Line 623... Line 10...
623
}
10
}