]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_hc.c
They now behave the same!! ^^ but there is a problem!! ><
[16.git] / src / lib / 16_hc.c
1 /* Project 16 Source Code~
2  * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
3  *
4  * This file is part of Project 16.
5  *
6  * Project 16 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Project 16 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,
19  * Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22 /*
23         heap test stuff
24 */
25
26 #include "src/lib/16_hc.h"
27 #pragma hdrstop
28
29 #pragma warn -pro
30 #pragma warn -use
31
32 int heaphandle;
33
34 #ifdef __BORLANDC__
35 void * LargestFreeBlock(size_t* Size)
36 #endif
37 #ifdef __WATCOMC__
38 void __near* LargestFreeBlock(size_t* Size)
39 #endif
40 {
41         size_t s0, s1;
42 #ifdef __BORLANDC__
43         void * p;
44 #endif
45 #ifdef __WATCOMC__
46         void __near* p;
47 #endif
48
49         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
50 #ifdef __BORLANDC__
51         while (s0 && (p = malloc(s0)) == NULL)
52 #endif
53 #ifdef __WATCOMC__
54         while (s0 && (p = _nmalloc(s0)) == NULL)
55 #endif
56                 s0 >>= 1;
57
58         if (p)
59 #ifdef __BORLANDC__
60                 free(p);
61 #endif
62 #ifdef __WATCOMC__
63                 _nfree(p);
64 #endif
65
66         s1 = s0 >> 1;
67         while (s1)
68         {
69 #ifdef __BORLANDC__
70                 if ((p = malloc(s0 + s1)) != NULL)
71 #endif
72 #ifdef __WATCOMC__
73                 if ((p = _nmalloc(s0 + s1)) != NULL)
74 #endif
75                 {
76                         s0 += s1;
77 #ifdef __BORLANDC__
78                         free(p);
79 #endif
80 #ifdef __WATCOMC__
81                         _nfree(p);
82 #endif
83                 }
84         s1 >>= 1;
85         }
86 #ifdef __BORLANDC__
87         while (s0 && (p = malloc(s0)) == NULL)
88 #endif
89 #ifdef __WATCOMC__
90         while (s0 && (p = _nmalloc(s0)) == NULL)
91 #endif
92                 s0 ^= s0 & -s0;
93
94         *Size = s0;
95         return p;
96 }
97
98 size_t _coreleft(void)
99 {
100         size_t total = 0;
101         void __near* pFirst = NULL;
102         void __near* pLast = NULL;
103         for(;;)
104         {
105                 size_t largest;
106                 void __near* p = (void __near *)LargestFreeBlock(&largest);
107                 if (largest < sizeof(void __near*))
108                 {
109                         if (p != NULL)
110 #ifdef __BORLANDC__
111                         free(p);
112 #endif
113 #ifdef __WATCOMC__
114                         _nfree(p);
115 #endif
116                         break;
117                 }
118                 *(void __near* __near*)p = NULL;
119                 total += largest;
120                 if (pFirst == NULL)
121                         pFirst = p;
122
123                 if (pLast != NULL)
124                         *(void __near* __near*)pLast = p;
125                 pLast = p;
126         }
127
128         while (pFirst != NULL)
129         {
130                 void __near* p = *(void __near* __near*)pFirst;
131 #ifdef __BORLANDC__
132                 free(pFirst);
133 #endif
134 #ifdef __WATCOMC__
135                 _nfree(pFirst);
136 #endif
137                 pFirst = p;
138         }
139         return total;
140 }
141
142 void far* LargestFarFreeBlock(size_t* Size)
143 {
144         size_t s0, s1;
145         void far* p;
146
147         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
148         while (s0 && (p = _fmalloc(s0)) == NULL)
149                 s0 >>= 1;
150
151         if (p)
152                 _ffree(p);
153
154         s1 = s0 >> 1;
155         while (s1)
156         {
157                 if ((p = _fmalloc(s0 + s1)) != NULL)
158                 {
159                         s0 += s1;
160                         _ffree(p);
161                 }
162         s1 >>= 1;
163         }
164         while (s0 && (p = _fmalloc(s0)) == NULL)
165                 s0 ^= s0 & -s0;
166
167         *Size = s0;
168         return p;
169 }
170
171 size_t _farcoreleft(void)
172 {
173         size_t total = 0;
174         void far* pFirst = NULL;
175         void far* pLast = NULL;
176         for(;;)
177         {
178                 size_t largest;
179                 void far* p = LargestFarFreeBlock(&largest);
180                 if (largest < sizeof(void far*))
181                 {
182                         if (p != NULL)
183                         _ffree(p);
184                         break;
185                 }
186                 *(void far* far*)p = NULL;
187                 total += largest;
188                 if (pFirst == NULL)
189                         pFirst = p;
190
191                 if (pLast != NULL)
192                         *(void far* far*)pLast = p;
193                 pLast = p;
194         }
195
196         while (pFirst != NULL)
197         {
198                 void far* p = *(void far* far*)pFirst;
199                 _ffree(pFirst);
200                 pFirst = p;
201         }
202         return total;
203 }
204
205 #ifdef __WATCOMC__
206 void huge* LargestHugeFreeBlock(size_t* Size)
207 {
208         size_t s0, s1;
209         void huge* p;
210
211         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
212         while (s0 && (p = halloc((dword)s0, 1)) == NULL)
213                 s0 >>= 1;
214
215         if (p)
216                 hfree(p);
217
218         s1 = s0 >> 1;
219         while (s1)
220         {
221                 if ((p = halloc((dword)(s0 + s1), 1)) != NULL)
222                 {
223                         s0 += s1;
224                         hfree(p);
225                 }
226         s1 >>= 1;
227         }
228         while (s0 && (p = halloc((dword)s0, 1)) == NULL)
229                 s0 ^= s0 & -s0;
230
231         *Size = s0;
232         return p;
233 }
234
235 size_t _hugecoreleft(void)
236 {
237         size_t total = 0;
238         void huge* pFirst = NULL;
239         void huge* pLast = NULL;
240         for(;;)
241         {
242                 size_t largest;
243                 void huge* p = LargestHugeFreeBlock(&largest);
244                 if (largest < sizeof(void huge*))
245                 {
246                         if (p != NULL)
247                         hfree(p);
248                         break;
249                 }
250                 *(void huge* huge*)p = NULL;
251                 total += largest;
252                 if (pFirst == NULL)
253                         pFirst = p;
254
255                 if (pLast != NULL)
256                         *(void huge* huge*)pLast = p;
257                 pLast = p;
258         }
259
260         while (pFirst != NULL)
261         {
262                 void huge* p = *(void huge* huge*)pFirst;
263                 hfree(pFirst);
264                 pFirst = p;
265         }
266         return total;
267 }
268
269 /*void __based(__self)* LargestBasedFreeBlock(size_t* Size)
270 {
271         __segment segu;
272         size_t s0, s1;
273         void __based(__self)* p;
274
275         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
276         while (s0 && (p = _bmalloc(segu, s0)) == NULL)
277                 s0 >>= 1;
278
279         if (p)
280                 _ffree(p);
281
282         s1 = s0 >> 1;
283         while (s1)
284         {
285                 if ((p = _bmalloc(segu, s0 + s1)) != NULL)
286                 {
287                         s0 += s1;
288                         _ffree(p);
289                 }
290         s1 >>= 1;
291         }
292         while (s0 && (p = _bmalloc(segu, s0)) == NULL)
293                 s0 ^= s0 & -s0;
294
295         *Size = s0;
296         return p;
297 }
298
299 size_t _basedcoreleft(void)
300 {
301         __segment segu;
302         size_t total = 0;
303         void __based(segu)* pFirst = NULL;
304         void __based(segu)* pLast = NULL;
305         // allocate based heap
306         segu = _bheapseg( 1024 );
307         if( segu == _NULLSEG ) {
308                 printf( "Unable to allocate based heap\n" );
309                 return 0;
310                 //exit( 1 );
311         }
312         else
313
314         for(;;)
315         {
316                 size_t largest;
317                 void __based(segu)* p = LargestBasedFreeBlock(&largest);
318                 if (largest < sizeof(void far*))
319                 {
320                         if (p != NULL)
321                         _ffree(p);
322                         break;
323                 }
324                 *(void far* far*)p = NULL;
325                 total += largest;
326                 if (pFirst == NULL)
327                         pFirst = p;
328
329                 if (pLast != NULL)
330                         *(void far* far*)pLast = p;
331                 pLast = p;
332         }
333
334         while (pFirst != NULL)
335         {
336                 void far* p = *(void far* far*)pFirst;
337                 _ffree(pFirst);
338                 pFirst = p;
339         }
340         return total;
341 }*/
342
343 size_t GetFreeSize(void)
344 {
345         struct _heapinfo h_info;
346         int heap_status;
347         size_t h_free=0, h_total=0, h_used=0;
348
349         h_info._pentry = NULL;
350         for(;;) {
351                 heap_status = _heapwalk( &h_info );
352                 if( heap_status != _HEAPOK ) break;
353                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
354                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
355                 h_total += h_info._size;
356         }
357         heapstat0(heap_status);
358         return h_free;
359 }
360
361 size_t GetFarFreeSize(void)
362 {
363         struct _heapinfo fh_info;
364         int heap_status;
365         size_t fh_free=0, fh_total=0, fh_used=0;
366
367         fh_info._pentry = NULL;
368         for(;;) {
369                 heap_status = _fheapwalk( &fh_info );
370                 if( heap_status != _HEAPOK ) break;
371                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
372                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
373                 fh_total += fh_info._size;
374         }
375         heapstat0(heap_status);
376         return fh_free;
377 }
378
379 size_t GetNearFreeSize(void)
380 {
381         struct _heapinfo nh_info;
382         int heap_status;
383         size_t nh_free=0, nh_total=0, nh_used=0;
384
385         nh_info._pentry = NULL;
386         for(;;) {
387                 heap_status = _nheapwalk( &nh_info );
388                 if( heap_status != _HEAPOK ) break;
389                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
390                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
391                 nh_total += nh_info._size;
392         }
393         heapstat0(heap_status);
394         return nh_free;
395 }
396
397 void heapdump(void)
398 {
399         struct _heapinfo fh_info, nh_info, h_info;
400         int heap_status;
401         size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;
402         byte    scratch[1024],str[16];
403
404         HC_OpenDebug();
405
406         strcpy(scratch,"\n      == default ==\n\n");
407         write(heaphandle,scratch,strlen(scratch));
408         h_info._pentry = NULL;
409         h_free=0; h_total=0; h_used=0;
410         for(;;) {
411                 heap_status = _heapwalk( &h_info );
412                 if( heap_status != _HEAPOK ) break;
413                 strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
414                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
415                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
416                 h_total += h_info._size;
417                 write(heaphandle,scratch,strlen(scratch));
418         }
419         heapstat(heap_status, &scratch);
420
421         //near
422         strcpy(scratch,"\n      == near ==\n\n");
423         write(heaphandle,scratch,strlen(scratch));
424         nh_info._pentry = NULL;
425         nh_free=0; nh_total=0; nh_used=0;
426         for(;;) {
427                 heap_status = _nheapwalk( &nh_info );
428                 if( heap_status != _HEAPOK ) break;
429                 strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
430 /*              printf( "  %s block at %Fp of size %4.4X\n",
431 (nh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
432 nh_info._pentry, nh_info._size );*/
433                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
434                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
435                 nh_total += nh_info._size;
436                 write(heaphandle,scratch,strlen(scratch));
437         }
438         heapstat(heap_status, &scratch);
439
440         //far
441         strcpy(scratch,"\n      == far ==\n\n");
442         write(heaphandle,scratch,strlen(scratch));
443         fh_info._pentry = NULL;
444         fh_free=0; fh_total=0; fh_used=0;
445         for(;;) {
446                 heap_status = _fheapwalk( &fh_info );
447                 if( heap_status != _HEAPOK ) break;
448                 strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
449                 /*printf( "  %s block at %Fp of size %4.4X\n",
450 (fh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
451 fh_info._pentry, fh_info._size );*/
452                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
453                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
454                 fh_total += fh_info._size;
455                 write(heaphandle,scratch,strlen(scratch));
456         }
457         heapstat(heap_status, &scratch);
458
459         strcpy(scratch,"\n");
460         strcat(scratch,kittengets(2,0,"Memory Type         Total      Used       Free\n"));
461         strcat(scratch,"----------------  --------   --------   --------\n");
462         printmeminfoline(&scratch, "Default", h_total, h_used, h_free);
463         printmeminfoline(&scratch, "Near", nh_total, nh_used, nh_free);
464         printmeminfoline(&scratch, "Far", fh_total, fh_used, fh_free);
465         strcat(scratch,"----------------  --------   --------   --------\n");
466         strcat(scratch,"coreleft = ");                  ultoa((dword)_coreleft(),str,10);               strcat(scratch,str);    strcat(scratch,"\n");
467         strcat(scratch,"farcoreleft = ");               ultoa((dword)_farcoreleft(),str,10);    strcat(scratch,str);    strcat(scratch,"\n");
468         strcat(scratch,"GetFreeSize = ");               ultoa((dword)GetFreeSize(),str,10);             strcat(scratch,str);    strcat(scratch,"\n");
469         strcat(scratch,"GetNearFreeSize = ");   ultoa((dword)GetNearFreeSize(),str,10); strcat(scratch,str);    strcat(scratch,"\n");
470         strcat(scratch,"GetFarFreeSize = ");    ultoa((dword)GetFarFreeSize(),str,10);  strcat(scratch,str);    strcat(scratch,"\n");
471         strcat(scratch,"memavl = ");                    ultoa((dword)_memavl(),str,10);                 strcat(scratch,str);    strcat(scratch,"\n");
472         strcat(scratch,"stackavail = ");                ultoa((dword)stackavail(),str,10);              strcat(scratch,str);    strcat(scratch,"\n");
473         write(heaphandle,scratch,strlen(scratch));
474         HC_CloseDebug();
475 }
476
477 void heapstat(int heap_status, byte *str)
478 {
479         switch( heap_status ) {
480                 case _HEAPEND:
481                         strcpy((str),"OK - end of heap\n");
482                 break;
483                 case _HEAPEMPTY:
484                         strcpy((str),"OK - heap is empty\n");
485
486                 break;
487                 case _HEAPBADBEGIN:
488                         strcpy((str),"ERROR - heap is damaged\n");
489                 break;
490                 case _HEAPBADPTR:
491                         strcpy((str),"ERROR - bad pointer to heap\n");
492                 break;
493                 case _HEAPBADNODE:
494                         strcpy((str),"ERROR - bad node in heap\n");
495         }
496         write(heaphandle,(str),strlen((str)));
497 }
498
499 void heapstat0(int heap_status)
500 {
501         switch( heap_status ) {
502                 case _HEAPEND:
503                         //printf("OK - end of heap\n");
504                 break;
505                 case _HEAPEMPTY:
506                         //printf("OK - heap is empty\n");
507
508                 break;
509                 case _HEAPBADBEGIN:
510                         printf("ERROR - heap is damaged\n");
511                 break;
512                 case _HEAPBADPTR:
513                         printf("ERROR - bad pointer to heap\n");
514                 break;
515                 case _HEAPBADNODE:
516                         printf("ERROR - bad node in heap\n");
517         }
518 }
519 #endif
520 /*
521 ============================
522 =
523 = HC_OpenDebug / HC_CloseDebug
524 =
525 = Opens a binary file with the handle "heaphandle"
526 =
527 ============================
528 */
529 void HC_OpenDebug()
530 {
531         unlink("heap.16");
532         heaphandle = open("heap.16", O_CREAT | O_WRONLY | O_TEXT);
533 }
534
535 void HC_CloseDebug()
536 {
537         close(heaphandle);
538 }