nmpp
multiheap.h
1#ifndef MULTIHEAP_INCLUDED
2#define MULTIHEAP_INCLUDED
3typedef unsigned size_t32;
4typedef unsigned size_t32;
5
6
7
8#include "nmpp.h"
9
10
11#define GUARD_BITS 0x600DB1D5
12#define MAX_BUFFER32_SIZE 16*1024*1024/4
15 int guardInfoBits0;
16 size_t32 size32Buffer;
19 bool isLocked;
20 int guardInfoBits1;
21
22
24 int* DataBegin(){
25 return ((int*)this+sizeof(S_BufferInfo)/sizeof(int));
26 };
27
29 int* DataEnd(){
30 int *p=((int*)this+sizeof(S_BufferInfo)/sizeof(int)+size32Buffer);
31 return p;
32 }
35 return DataEnd()-2;
36 }
37 unsigned CheckGuardBits(){
38 if (guardInfoBits0!=GUARD_BITS){
39 return 0xBADB00F1;
40 }
41 if (guardInfoBits1!=GUARD_BITS){
42 return 0xBADB00F2;
43 }
44 if (size32Buffer){
45 int* pFinalGuardBits=EndGuardBits();
46 if ((*pFinalGuardBits)!=GUARD_BITS){
47 return 0xBADB00F3;
48 }
49 if (*(pFinalGuardBits+1)!=GUARD_BITS){
50 return 0xBADB00F4;
51 }
52 if (size32Buffer<0)
53 return 0xBADB00FF;
54
55 if (size32Buffer>MAX_BUFFER32_SIZE)
56 return 0xBADB00FE;
57 }
58 return 0;
59 }
60};
61
62
64class C_Heap{
65public:
67 int* pHeapEnd;
70 int status;
71 C_Heap() {
72 pZeroBuffer = 0;
73 pHeapEnd = 0;
75 isHeapLocked=false;
76 status =0;
77 }
79 C_Heap (void* addrHeap, size_t32 size32Heap){
80 Create(addrHeap,size32Heap);
81 }
82
84 void Create( void* addrHeap, size_t32 size32Heap){
85
86 pZeroBuffer= (S_BufferInfo*)addrHeap; // начальный адрес кучи
91 pZeroBuffer->guardInfoBits0=GUARD_BITS;
92 pZeroBuffer->guardInfoBits1=GUARD_BITS;
93
94 pHeapEnd = (int*)addrHeap+size32Heap; // конечный адрес кучи (следующий за последним байтом кучи)
96 }
97
99 int IsMine(void* addr){
100 if ((int*)pZeroBuffer < (int*)addr && (int*)addr < pHeapEnd)
101 return 1;
102 return 0;
103 }
104
106 //int HeapAvail(){
107 // return (size32FreeMem-sizeof(S_BufferInfo)/sizeof(int));
108 //}
109
110 //size_t32 TotalAvail(){
111 // return size32HeapAvail;
112 //}
113
116 int size32Max=0;
117 S_BufferInfo* pBuffer=pZeroBuffer;
118 for ( ; pBuffer->pNextBuffer!=0; pBuffer=pBuffer->pNextBuffer) {
119 int size32Between=(int*)pBuffer->pNextBuffer - pBuffer->DataEnd();
120 if (size32Between>size32Max)
121 size32Max=size32Between;
122 }
123 // находимся на последнем буфере
124 int size32Between=(int*)pHeapEnd - pBuffer->DataEnd();
125 if (size32Between>size32Max)
126 size32Max=size32Between;
127 size32Max-=sizeof(S_BufferInfo)/sizeof(int);
128 return size32Max;
129 }
130
132 int* Allocate(size_t32 size32Buffer){
133 if (isHeapLocked)
134 return 0;
135 if (size32Buffer==0)
136 return 0;
137 size32Buffer+=(size32Buffer&1); // округляем вверх до четного размера
138 size32Buffer+=2; // добавляем 2 слова для защитного поля
139 S_BufferInfo* pBuffer=pZeroBuffer;
140 int size32Between=0;
141 for(; pBuffer->pNextBuffer!=0; pBuffer=pBuffer->pNextBuffer){
142 // проверяем влезает ли массив в промежуток между буферами
143 size32Between=(int*)pBuffer->pNextBuffer - pBuffer->DataEnd();
144 if (size32Between>=size32Buffer+sizeof(S_BufferInfo)/sizeof(int)){
145 // создаем новый буфер
146 S_BufferInfo* pAllocateBuffer=(S_BufferInfo*)pBuffer->DataEnd();
147 // устанавливаем связи в следующем буфере
148 pBuffer->pNextBuffer->pPrevBuffer=pAllocateBuffer;
149 // устнавливаем связи в новом буфере
150 pAllocateBuffer->pPrevBuffer=pBuffer;
151 pAllocateBuffer->pNextBuffer=pBuffer->pNextBuffer;
152 pAllocateBuffer->size32Buffer=size32Buffer;
153 pAllocateBuffer->isLocked=false;
154 // устанавливаем защитные биты
155 pAllocateBuffer->guardInfoBits0=GUARD_BITS;
156 pAllocateBuffer->guardInfoBits1=GUARD_BITS;
157 int* guardEndBits=pAllocateBuffer->EndGuardBits();
158 *guardEndBits =GUARD_BITS;
159 *(guardEndBits+1)=GUARD_BITS;
160 // устанавливаем связи в предыдущем буфере
161 pBuffer->pNextBuffer=pAllocateBuffer;
162 // уменьшаем сободный размер
163 size32HeapAvail-=(size32Buffer+sizeof(S_BufferInfo)/sizeof(int));
164
165 return pAllocateBuffer->DataBegin();
166 }
167 }
168 // дошли до последнего буфера (у которого ->pNextBuffer=0)
169 size32Between=(int*)pHeapEnd - pBuffer->DataEnd();
170 if (size32Between>=size32Buffer+sizeof(S_BufferInfo)/sizeof(int)){
171 // создаем новый буфер
172 S_BufferInfo* pAllocateBuffer=(S_BufferInfo*)pBuffer->DataEnd();
173 // устнавливаем связи в новом буфере
174 pAllocateBuffer->pPrevBuffer=pBuffer;
175 pAllocateBuffer->pNextBuffer=0;
176 pAllocateBuffer->size32Buffer=size32Buffer;
177 pAllocateBuffer->isLocked=false;
178 // устанавливаем защитные биты
179 pAllocateBuffer->guardInfoBits0=GUARD_BITS;
180 pAllocateBuffer->guardInfoBits1=GUARD_BITS;
181 int* guardEndBits=pAllocateBuffer->EndGuardBits();
182 *guardEndBits =GUARD_BITS;
183 *(guardEndBits+1)=GUARD_BITS;
184 // устанавливаем связи в предыдущем буфере
185 pBuffer->pNextBuffer=pAllocateBuffer;
186 size32HeapAvail-=(size32Buffer+sizeof(S_BufferInfo)/sizeof(int));
187 // уменьшаем сободный размер
188 return pAllocateBuffer->DataBegin();
189 }
190 return 0;
191 }
192
194 int ReleaseBuffer(S_BufferInfo* pDelBuffer){
195 if (isHeapLocked)
196 return 0;
197 if (pDelBuffer->isLocked)
198 return 0;
199 if (pDelBuffer->size32Buffer==0)
200 return 0;
201
202 pDelBuffer->pPrevBuffer->pNextBuffer=pDelBuffer->pNextBuffer; // связываем ссылку предыдущего буфера на следующий
203 if (pDelBuffer->pNextBuffer) // если есть следующий
204 pDelBuffer->pNextBuffer->pPrevBuffer=pDelBuffer->pPrevBuffer; // связываем ссылку следующего буфера на предыдущий
205 size32HeapAvail+=(pDelBuffer->size32Buffer+sizeof(S_BufferInfo)/sizeof(int));
206 pDelBuffer->size32Buffer=0;
207 return 1;
208 }
209
211 int Release(void* p){
212 if (isHeapLocked)
213 return 0;
214 S_BufferInfo* pDelBuffer=(S_BufferInfo*)p-1;
215 return ReleaseBuffer(pDelBuffer);
216 }
217
219 void Lock(void* p){
220 S_BufferInfo* pBuffer=(S_BufferInfo*)p-1;
221 pBuffer->isLocked=true;
222 }
223
225 void LockAll(){
227 while (pBuffer) {
228 pBuffer->isLocked=true;
229 pBuffer=pBuffer->pNextBuffer;
230 }
231 }
233 void UnlockAll(){
235 while (pBuffer) {
236 pBuffer->isLocked=false;
237 pBuffer=pBuffer->pNextBuffer;
238 }
239 }
240
242 void Unlock(void* p){
243 S_BufferInfo* pBuffer=(S_BufferInfo*)p-1;
244 pBuffer->isLocked=false;
245 //numHeapLocked--;
246 }
247
251 if (isHeapLocked)
252 return ;
253 while (pBuffer) {
254 if (!pBuffer->isLocked){
255 ReleaseBuffer(pBuffer);
256 }
257 pBuffer=pBuffer->pNextBuffer;
258 }
259 }
261 void LockHeap(){
262 isHeapLocked=true;
263 }
266 isHeapLocked=false;
267 }
268 int Check(){
269 if (status)
270 return status;
271
273 status=0xBADB00F0;
274 return status;
275 }
277 status=0xBADB00FF;
278 return status;
279 }
280 // if (status=pZeroBuffer->CheckGuardBits()){
281 // return status;
282 // }
283
285
286 int AllocatedMemory=0;
287 int MaxHeapSize=(int*)pHeapEnd-(int*)pZeroBuffer;
288
289 for(int i=0;i<100;i++){
290 if (pBuffer==0)
291 break;
292
293
294 if (!IsMine(pBuffer)){
295 status =0xBADB00FA;
296 return status;
297 }
298
299 if (status=pBuffer->CheckGuardBits()){
300 return status;
301 }
302
303 if (pBuffer->pPrevBuffer->pNextBuffer!=pBuffer){
304 status =0xBADB00FB;
305 return status;
306 }
307
308 AllocatedMemory+=sizeof(S_BufferInfo)/sizeof(int);
309 AllocatedMemory+=pBuffer->size32Buffer;
310 if (AllocatedMemory>MaxHeapSize){
311 status=0xBADB00FD;
312 return status;
313 }
314 if ((int)pBuffer&1){
315 status=0xBADB00FC;
316 return status;
317 }
318 pBuffer=pBuffer->pNextBuffer;
319 }
320 return 0;
321 }
322};
323
324
325#define ALLOCATE_FORWARD 1
326#define ALLOCATE_BACKWARD 2
327#define ALLOCATE_RANDOM 4
328#define ALLOCATE_CUSTOM 8
329#define MAX_NUM_BANKS 6
331 public:
332 void* Allocate();
333 int Release();
334};
335
337 unsigned m_z;
338 unsigned m_w;
339public:
340 C_Heap pHeap[MAX_NUM_BANKS];
341 unsigned numHeaps;
343 unsigned AllocateMode ;
345 unsigned idxAllocateLegend;
346 long long allocateHistory;
347 C_MultiHeap(int Mode=ALLOCATE_FORWARD) {
348 allocateHistory=0;
349 numHeaps=0;
351 m_z=3141516;
352 m_w=3141516;
353 AllocateMode=Mode;
355 }
356
357 int Error(){
358 return numAllocateFails;
359 }
360 void Mode(int mode, void** legend=0){
361
362 idxAllocateLegend=0;
363 pAllocateLegend=legend;
364 AllocateMode=mode;
365 }
366
368 unsigned Rand()
369 {
370 m_z = 36969 * (m_z & 0xFFFF) + (m_z >> 16);
371 m_w = 18000 * (m_w & 0xFFFF) + (m_w >> 16);
372 return (m_z << 16) + m_w;
373 }
374 unsigned Rand(unsigned min, unsigned max){
375 unsigned r=Rand();
376 r=(r-min)%(max-min+1)+min;
377 return r;
378
379 }
380
381 C_Heap& operator [](int idxHeap){
382 return pHeap[idxHeap];
383 }
384
386 int CreateHeap(void* addrHeap, size_t32 size32Heap){
387 if (numHeaps>MAX_NUM_BANKS)
388 return 0;
389
390 pHeap[numHeaps].Create(addrHeap,size32Heap);
391 if (pHeap[numHeaps].size32HeapAvail)
392 numHeaps++;
393 return 1;
394 }
395
397 void* Allocate(size_t32 size32Buffer){
398
399 void *p;
400 unsigned i;
401
402 switch (AllocateMode){
403 case ALLOCATE_FORWARD:
404 for(i=0; i<numHeaps; i++){
405 p=pHeap[i].Allocate(size32Buffer);
406 if (p){
407 allocateHistory<<=4;
408 allocateHistory|=i;
409 if (pAllocateLegend){
410 //pAllocateLegend[idxAllocateLegend>>3]&=~(0xFF<<((idxAllocateLegend&7)<<4));
411 //pAllocateLegend[idxAllocateLegend>>3]|=~( i<<((idxAllocateLegend&7)<<4));
412 pAllocateLegend[idxAllocateLegend]=p;
413 idxAllocateLegend++;
414 }
415 return p;
416 }
417 }
419 break;
420
421 case ALLOCATE_BACKWARD:
422 for(i=numHeaps-1; i>=0; i--){
423 p=pHeap[i].Allocate(size32Buffer);
424 if (p){
425 allocateHistory<<=4;
426 allocateHistory|=i;
427 if (pAllocateLegend){
428 //pAllocateLegend[idxAllocateLegend>>3]&=~(0xFF<<((idxAllocateLegend&7)<<4));
429 //pAllocateLegend[idxAllocateLegend>>3]|=~( i<<((idxAllocateLegend&7)<<4));
430 pAllocateLegend[idxAllocateLegend]=p;
431 idxAllocateLegend++;
432 }
433 return p;
434 }
435
436 }
438 break;
439
440 case ALLOCATE_RANDOM:{
441 unsigned mapAllocateFails=0;
442 unsigned mapNoMemory=0xFFFFFFFF>>(32-numHeaps);
443 while(mapAllocateFails!=mapNoMemory){
444 i=Rand()%numHeaps;
445 mapAllocateFails|=(1<<i);
446 p=pHeap[i].Allocate(size32Buffer);
447 if (p){
448 allocateHistory<<=4;
449 allocateHistory|=i;
450 if (pAllocateLegend){
451 //pAllocateLegend[idxAllocateLegend>>3]&=~(0xFF<<((idxAllocateLegend&7)<<4));
452 //pAllocateLegend[idxAllocateLegend>>3]|=~( i<<((idxAllocateLegend&7)<<4));
453 pAllocateLegend[idxAllocateLegend]=p;
454 idxAllocateLegend++;
455 }
456 return p;
457 }
458 }
460 break;
461 }
462 case ALLOCATE_CUSTOM:{
463 //unsigned mapAllocateFails=0;
464 //unsigned mapNoMemory=0xFFFFFFFF>>(32-numHeaps);
465 //i=pAllocateLegend[idxAllocateLegend];
466 //idxAllocateLegend++;
467 //p=pHeap[i].Allocate(size32Buffer);
468 //if (p){
469 // return p;
470 //}
471 //numAllocateFails++;
472 return pAllocateLegend[idxAllocateLegend++];
473 }
474 }
475 return 0;
476 }
477
479 void* Allocate(size_t32 size32Buffer, int nPriorHeap0, int nPriorHeap1=-1,int nPriorHeap2=-1,int nPriorHeap3=-1,int nPriorHeap4=-1,int nPriorHeap5=-1){
480
481 int* p;
482 p=pHeap[nPriorHeap0].Allocate(size32Buffer);
483 if (p) {
484 if (pAllocateLegend){
485 pAllocateLegend[idxAllocateLegend]=p;
486 idxAllocateLegend++;
487 }
488 return p;
489 }
490
491 if (nPriorHeap1!=-1){
492 p=pHeap[nPriorHeap1].Allocate(size32Buffer);
493 if (p) {
494 if (pAllocateLegend){
495 pAllocateLegend[idxAllocateLegend]=p;
496 idxAllocateLegend++;
497 }
498 return p;
499 }
500 }
501 if (nPriorHeap2!=-1){
502 p=pHeap[nPriorHeap2].Allocate(size32Buffer);
503 if (p) {
504 if (pAllocateLegend){
505 pAllocateLegend[idxAllocateLegend]=p;
506 idxAllocateLegend++;
507 }
508 return p;
509 }
510
511 }
512 if (nPriorHeap3!=-1){
513 p=pHeap[nPriorHeap3].Allocate(size32Buffer);
514 if (p) {
515 if (pAllocateLegend){
516 pAllocateLegend[idxAllocateLegend]=p;
517 idxAllocateLegend++;
518 }
519 return p;
520 }
521 }
522 if (nPriorHeap4!=-1){
523 p=pHeap[nPriorHeap4].Allocate(size32Buffer);
524 if (p) {
525 if (pAllocateLegend){
526 pAllocateLegend[idxAllocateLegend]=p;
527 idxAllocateLegend++;
528 }
529 return p;
530 }
531
532 }
533 if (nPriorHeap5!=-1){
534 p=pHeap[nPriorHeap5].Allocate(size32Buffer);
535 if (p) {
536 if (pAllocateLegend){
537 pAllocateLegend[idxAllocateLegend]=p;
538 idxAllocateLegend++;
539 }
540 return p;
541 }
542
543 }
545 return 0;
546 }
548 void* AllocateWith(size_t32 size32Buffer, void* addrInTheSameHeap){
549 for(int i=0; i<numHeaps; i++){
550 if (pHeap[i].IsMine(addrInTheSameHeap)){
551 void *p=pHeap[i].Allocate(size32Buffer);
552 if (p) {
553 if (pAllocateLegend){
554 pAllocateLegend[idxAllocateLegend]=p;
555 idxAllocateLegend++;
556 }
557 return p;
558 }
559 }
560 }
561 return 0;
562 }
563
565 int Which(void *addr){
566 for(int i=0; i<numHeaps; i++){
567 if (pHeap[i].IsMine(addr))
568 return i;
569 }
570 return -1;
571 }
572
573 void Lock(void* addr){
574 S_BufferInfo* pBuffer=(S_BufferInfo*)addr-1;
575 pBuffer->isLocked=true;
576 }
577
578 int Unlock(void* addr){
579 S_BufferInfo* pBuffer=(S_BufferInfo*)addr-1;
580 pBuffer->isLocked=false;
581 return 0;
582 }
583
584 int LockAll(){
585 for(int i=0; i<numHeaps; i++){
586 pHeap[i].LockAll();
587 }
588 return 0;
589 }
590 int UnlockAll(){
591 for(int i=0; i<numHeaps; i++){
592 pHeap[i].UnlockAll();
593 }
594 return 0;
595 }
596 int Release(void* addr){
597 if (AllocateMode==ALLOCATE_CUSTOM)
598 return 0;
599 if (addr)
600 for(int i=0; i<numHeaps; i++){
601 if (pHeap[i].IsMine(addr)){
602 return pHeap[i].Release(addr);
603 }
604 }
605 return 0;
606 }
607
610 for(int i=0; i<numHeaps; i++){
611 pHeap[i].ReleaseAll();
612 }
613 }
614
616 void LockHeap(int idxHeap){
617 pHeap[idxHeap].LockHeap();
618 }
620 void UnlockHeap(int idxHeap){
621 pHeap[idxHeap].UnlockHeap();
622 }
623 int Check(){
624 for(int i=0; i<numHeaps; i++){
625 if (pHeap[i].Check())
626 return pHeap[i].status;
627 }
628 return 0;
629
630 }
631};
632
633
634template<class T> class C_BoxVec
635{
636public:
637 int sizeData;
638 int sizeBox;
639 int nBorder;
640 T* pBox;
641 T* pData;
642 C_MultiHeap* pHeap;
643
644 C_BoxVec(){
645 sizeBox=0;
646 sizeData=0;
647 nBorder=0;
648 pBox=0;
649 pData=0;
650 pHeap=0;
651 }
652
653 C_BoxVec(T* Data, int SizeData, int SizeBorder=0){
654 pHeap=0;
655 Assign(Data, SizeData, SizeBorder);
656 }
657
658 C_BoxVec(C_MultiHeap& MultiHeap, int SizeData, int Border=0){
659 sizeData=SizeData;
660 nBorder =Border;
661 Allocate(MultiHeap);
662 }
663
664
665 T* Addr(int idx){
666 return nmppsAddr_(pData,idx);
667 }
668
669 int Assign (T* Data, int SizeData, int SizeBorder=0){
670 pData =Data;
671 pBox =nmppsAddr_(pData,-SizeBorder);
672 sizeData=SizeData;
673 sizeBox =SizeData+2*SizeBorder;
674 }
675 T* Allocate(C_MultiHeap& MultiHeap, int SizeData, int Border=0){
676 sizeData=SizeData;
677 nBorder =Border;
678 Allocate(MultiHeap);
679 }
680
681 T* Allocate(C_MultiHeap& MultiHeap){
682 pHeap=&MultiHeap;
683 pData=0;
684 sizeBox =sizeData+2*nBorder;
685 int sizeBox32=(int)nmppsAddr_((T*)0,sizeBox)/sizeof(int);
686 pBox =(T*)MultiHeap.Allocate(sizeBox32);
687 if (pBox){
688 pData=nmppsAddr_(pBox,(sizeBox-sizeData)/2);
689 }
690 return pData;
691 }
692
693 int Release(){
694 if (pBox)
695 if (pHeap){
696 pHeap->Release(pBox);
697 pBox=0;
698 }
699 return 0;
700 }
701
702 ~C_BoxVec() {
703 if (pHeap)
704 if (pBox)
705 pHeap->Release(pBox);
706 }
707 //__INLINE__ T& operator [] (int idx){
708 // return *nmppsAddr_(pData,idx);
709 //}
710};
711
712#define BOX_nmppiFILL_NONE 0xF111DEAD
713#define BOX_nmppiFILL_RAND 0xF1110123
714#define BOX_nmppiFILL_00 0
715#define BOX_nmppiFILL_01 1
716#define BOX_nmppiFILL_FF -1
717template<class T> class C_BoxImg
718{
719
720public:
721 int nWidth;
722 int nHeight;
723 int sizeBox;
724 int sizeData;
725 int nBorder;
726 T* pBox;
727 T* pData;
728 C_MultiHeap* pHeap;
729
730 C_BoxImg(){
731 nWidth=0;
732 nHeight=0;
733 sizeBox=0;
734 sizeData=0;
735 nBorder=0;
736 pBox=0;
737 pData=0;
738 pHeap=0;
739 }
740
741
742 C_BoxImg(C_MultiHeap& MultiHeap, int Width, int Height, int BorderHeight=0, int FillMode=BOX_nmppiFILL_FF){
743 nWidth=Width;
744 nHeight=Height;
745 nBorder=BorderHeight;
746 pBox =(T*)0;
747 pData=(T*)0xcbcbcbcb;
748 pHeap=0;
749 if (Allocate(MultiHeap))
750 Fill(FillMode);
751 }
752 void Lock(){
753 S_BufferInfo* Info=((S_BufferInfo*)pBox)-1;
754 Info->isLocked=true;
755 }
756 void Unlock(){
757 S_BufferInfo* Info=((S_BufferInfo*)pBox)-1;
758 Info->isLocked=false;
759 }
760 void Fill(int FillMode){
761 if (FillMode==BOX_nmppiFILL_NONE)
762 return;
763 if (FillMode==BOX_nmppiFILL_RAND){
764 nmppsRandUniform_(pBox,sizeBox);
765 return;
766 }
767 nmppsSet_(pBox,FillMode,sizeBox);
768 }
769
770 C_BoxImg(T* Data, int Width, int Height, int BorderHeight=0){
771 pHeap =0;
772 pData =Data;
773 nWidth =Width;
774 nHeight =Height;
775 nBorder =BorderHeight;
776 pBox =nmppsAddr_(pData,-nBorder*nWidth);
777 sizeData=nWidth*nHeight;
778 sizeBox =sizeData+2*nBorder*nWidth;
779 }
780 void Init(T* Data, int Width, int Height, int BorderHeight=0){
781 pHeap =0;
782 pData =Data;
783 nWidth =Width;
784 nHeight =Height;
785 nBorder =BorderHeight;
786 pBox =nmppsAddr_(pData,-nBorder*nWidth);
787 sizeData=nWidth*nHeight;
788 sizeBox =sizeData+2*nBorder*nWidth;
789 }
790 T* Addr(int y, int x){
791 return nmppsAddr_(pData,y*nWidth+x);
792 }
793
794 T* Allocate(C_MultiHeap& MultiHeap, int Width, int Height, int BorderHeight=0){
795 nWidth=Width;
796 nHeight=Height;
797 nBorder=BorderHeight;
798 return Allocate(MultiHeap);
799
800 }
801
802 T* Allocate(C_MultiHeap& MultiHeap){
803 if (MultiHeap.Check())
804 return 0;
805 pHeap =&MultiHeap;
806 pData =0;
807 sizeData=nWidth*nHeight;
808 sizeBox =sizeData+2*nBorder*nWidth;
809 int sizeBox32=(int)nmppsAddr_((T*)0,sizeBox)/sizeof(int);
810 pBox=(T*)MultiHeap.Allocate(sizeBox32);
811 if (pBox)
812 pData=nmppsAddr_(pBox,(sizeBox-sizeData)/2);
813 return pData;
814 }
815 int Release(){
816 if (pHeap)
817 if (pBox){
818 pHeap->Release(pBox);
819 pHeap=0;
820 //pBox=0;
821 //pData=0;
822
823 }
824 return 1;
825 }
826 __INLINE__ T* operator [] (int idx){
827 return nmppsAddr_(pData,idx);
828 }
829 ~C_BoxImg() {
830 if (pHeap)
831 if (pBox)
832 pHeap->Release(pBox);
833 }
834
835};
836
837#endif
Definition: multiheap.h:330
Definition: multiheap.h:718
Definition: multiheap.h:635
класс - куча
Definition: multiheap.h:64
int * Allocate(size_t32 size32Buffer)
Выделяет буфер в куче
Definition: multiheap.h:132
C_Heap(void *addrHeap, size_t32 size32Heap)
конструктор - создает кучу в указанной памяти
Definition: multiheap.h:79
void UnlockAll()
разблокирует все указатели для удаления через Release
Definition: multiheap.h:233
void Unlock(void *p)
разблокирует все указатели для удаления через Release
Definition: multiheap.h:242
int IsMine(void *addr)
устанавливает принадлежность к куче
Definition: multiheap.h:99
void ReleaseAll()
удаляет все указатели из кучи
Definition: multiheap.h:249
void LockHeap()
Запрещает операции с кучей
Definition: multiheap.h:261
void Lock(void *p)
блокирует указатель от удаления через Release
Definition: multiheap.h:219
int size32HeapAvail
< размер общей свободной памяти в куче
Definition: multiheap.h:68
int Release(void *p)
осообождат память по адресу
Definition: multiheap.h:211
size_t32 AllocateMaxAvail()
Возвращает объем свободной памяти в пуле в 32р. словах
Definition: multiheap.h:115
int ReleaseBuffer(S_BufferInfo *pDelBuffer)
удаляет структуру буфера из списка
Definition: multiheap.h:194
S_BufferInfo * pZeroBuffer
< указатель на нулевой буфер в списке (c нулевым размером)
Definition: multiheap.h:66
void LockAll()
блокирует все указатели от удаления через Release
Definition: multiheap.h:225
void Create(void *addrHeap, size_t32 size32Heap)
создает кучу в указанной памяти
Definition: multiheap.h:84
void UnlockHeap()
Разрещает операции с кучей
Definition: multiheap.h:265
int * pHeapEnd
< указатель на слово следуюшее за концом кучи
Definition: multiheap.h:67
bool isHeapLocked
< запрещает операции с кучей
Definition: multiheap.h:69
Definition: multiheap.h:336
void ReleaseAll()
Удваляет все назаблокированные указатели из куч
Definition: multiheap.h:609
int CreateHeap(void *addrHeap, size_t32 size32Heap)
создает кучу по адресууказанного размера (полный размер со служебными данными)
Definition: multiheap.h:386
int Which(void *addr)
Возвращает номер кучи к которой принадлежит адрес
Definition: multiheap.h:565
void ** pAllocateLegend
история номеров куч использованных в последних 8 Allocate
Definition: multiheap.h:344
unsigned AllocateMode
порядок обхода куч при поиске свободного места
Definition: multiheap.h:343
void UnlockHeap(int idxHeap)
Разрещает операции Allocate и Release с кучей
Definition: multiheap.h:620
unsigned numAllocateFails
число ошибок выделения куч
Definition: multiheap.h:342
void LockHeap(int idxHeap)
Запрещает операции Allocate и Release с кучей
Definition: multiheap.h:616
void * Allocate(size_t32 size32Buffer)
обходит кучи в заднном в AllocateMode порядке и выделяет память заданного размера
Definition: multiheap.h:397
unsigned Rand()
Генератор случайных чисел
Definition: multiheap.h:368
C_Heap pHeap[MAX_NUM_BANKS]
массив куч
Definition: multiheap.h:340
void * Allocate(size_t32 size32Buffer, int nPriorHeap0, int nPriorHeap1=-1, int nPriorHeap2=-1, int nPriorHeap3=-1, int nPriorHeap4=-1, int nPriorHeap5=-1)
обходит кучи в заднном порядке и выделяет память заданного размера
Definition: multiheap.h:479
void * AllocateWith(size_t32 size32Buffer, void *addrInTheSameHeap)
выделяет массив в той же куче где и указатель
Definition: multiheap.h:548
unsigned numHeaps
число проининицализированных куч
Definition: multiheap.h:341
класс буфер - заголовок в начале выделяемой данамической памяти
Definition: multiheap.h:14
S_BufferInfo * pPrevBuffer
< указатель на предыдущий буфер в списке
Definition: multiheap.h:17
int * EndGuardBits()
Возвращает указатель на конечные защитные поля (2 слова)
Definition: multiheap.h:34
S_BufferInfo * pNextBuffer
< указатель на следующий буфер в списке
Definition: multiheap.h:18
int * DataBegin()
Возвращает указатель на данные в буфере
Definition: multiheap.h:24
int * DataEnd()
Возвращает указатель на конец данных в буфере (следу)
Definition: multiheap.h:29
bool isLocked
< флаг блокировки буфера, запрещаюий его удаление с помощью Release()
Definition: multiheap.h:19
size_t32 size32Buffer
< размер массива данных в буфере в 32-р словах
Definition: multiheap.h:16