]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_hc.c
Signed-off-by: sparky4 <sparky4@cock.li>
[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
28 void __near* LargestFreeBlock(size_t* Size)
29 {
30         size_t s0, s1;
31         void __near* p;
32
33         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
34         while (s0 && (p = _nmalloc(s0)) == NULL)
35                 s0 >>= 1;
36
37         if (p)
38                 _nfree(p);
39
40         s1 = s0 >> 1;
41         while (s1)
42         {
43                 if ((p = _nmalloc(s0 + s1)) != NULL)
44                 {
45                         s0 += s1;
46                         _nfree(p);
47                 }
48         s1 >>= 1;
49         }
50         while (s0 && (p = _nmalloc(s0)) == NULL)
51                 s0 ^= s0 & -s0;
52
53         *Size = s0;
54         return p;
55 }
56
57 size_t _coreleft(void)
58 {
59         size_t total = 0;
60         void __near* pFirst = NULL;
61         void __near* pLast = NULL;
62         for(;;)
63         {
64                 size_t largest;
65                 void __near* p = LargestFreeBlock(&largest);
66                 if (largest < sizeof(void __near*))
67                 {
68                         if (p != NULL)
69                         _nfree(p);
70                         break;
71                 }
72                 *(void __near* __near*)p = NULL;
73                 total += largest;
74                 if (pFirst == NULL)
75                         pFirst = p;
76
77                 if (pLast != NULL)
78                         *(void __near* __near*)pLast = p;
79                 pLast = p;
80         }
81
82         while (pFirst != NULL)
83         {
84                 void __near* p = *(void __near* __near*)pFirst;
85                 _nfree(pFirst);
86                 pFirst = p;
87         }
88         return total;
89 }
90
91 void far* LargestFarFreeBlock(size_t* Size)
92 {
93         size_t s0, s1;
94         void far* p;
95
96         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
97         while (s0 && (p = _fmalloc(s0)) == NULL)
98                 s0 >>= 1;
99
100         if (p)
101                 _ffree(p);
102
103         s1 = s0 >> 1;
104         while (s1)
105         {
106                 if ((p = _fmalloc(s0 + s1)) != NULL)
107                 {
108                         s0 += s1;
109                         _ffree(p);
110                 }
111         s1 >>= 1;
112         }
113         while (s0 && (p = _fmalloc(s0)) == NULL)
114                 s0 ^= s0 & -s0;
115
116         *Size = s0;
117         return p;
118 }
119
120 size_t _farcoreleft(void)
121 {
122         size_t total = 0;
123         void far* pFirst = NULL;
124         void far* pLast = NULL;
125         for(;;)
126         {
127                 size_t largest;
128                 void far* p = LargestFarFreeBlock(&largest);
129                 if (largest < sizeof(void far*))
130                 {
131                         if (p != NULL)
132                         _ffree(p);
133                         break;
134                 }
135                 *(void far* far*)p = NULL;
136                 total += largest;
137                 if (pFirst == NULL)
138                         pFirst = p;
139
140                 if (pLast != NULL)
141                         *(void far* far*)pLast = p;
142                 pLast = p;
143         }
144
145         while (pFirst != NULL)
146         {
147                 void far* p = *(void far* far*)pFirst;
148                 _ffree(pFirst);
149                 pFirst = p;
150         }
151         return total;
152 }
153
154 void huge* LargestHugeFreeBlock(size_t* Size)
155 {
156         size_t s0, s1;
157         void huge* p;
158
159         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
160         while (s0 && (p = halloc((dword)s0, 1)) == NULL)
161                 s0 >>= 1;
162
163         if (p)
164                 hfree(p);
165
166         s1 = s0 >> 1;
167         while (s1)
168         {
169                 if ((p = halloc((dword)(s0 + s1), 1)) != NULL)
170                 {
171                         s0 += s1;
172                         hfree(p);
173                 }
174         s1 >>= 1;
175         }
176         while (s0 && (p = halloc((dword)s0, 1)) == NULL)
177                 s0 ^= s0 & -s0;
178
179         *Size = s0;
180         return p;
181 }
182
183 size_t _hugecoreleft(void)
184 {
185         size_t total = 0;
186         void huge* pFirst = NULL;
187         void huge* pLast = NULL;
188         for(;;)
189         {
190                 size_t largest;
191                 void huge* p = LargestHugeFreeBlock(&largest);
192                 if (largest < sizeof(void huge*))
193                 {
194                         if (p != NULL)
195                         hfree(p);
196                         break;
197                 }
198                 *(void huge* huge*)p = NULL;
199                 total += largest;
200                 if (pFirst == NULL)
201                         pFirst = p;
202
203                 if (pLast != NULL)
204                         *(void huge* huge*)pLast = p;
205                 pLast = p;
206         }
207
208         while (pFirst != NULL)
209         {
210                 void huge* p = *(void huge* huge*)pFirst;
211                 hfree(pFirst);
212                 pFirst = p;
213         }
214         return total;
215 }
216
217 /*void __based(__self)* LargestBasedFreeBlock(size_t* Size)
218 {
219         __segment segu;
220         size_t s0, s1;
221         void __based(__self)* p;
222
223         s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
224         while (s0 && (p = _bmalloc(segu, s0)) == NULL)
225                 s0 >>= 1;
226
227         if (p)
228                 _ffree(p);
229
230         s1 = s0 >> 1;
231         while (s1)
232         {
233                 if ((p = _bmalloc(segu, s0 + s1)) != NULL)
234                 {
235                         s0 += s1;
236                         _ffree(p);
237                 }
238         s1 >>= 1;
239         }
240         while (s0 && (p = _bmalloc(segu, s0)) == NULL)
241                 s0 ^= s0 & -s0;
242
243         *Size = s0;
244         return p;
245 }
246
247 size_t _basedcoreleft(void)
248 {
249         __segment segu;
250         size_t total = 0;
251         void __based(segu)* pFirst = NULL;
252         void __based(segu)* pLast = NULL;
253         // allocate based heap
254         segu = _bheapseg( 1024 );
255         if( segu == _NULLSEG ) {
256                 printf( "Unable to allocate based heap\n" );
257                 return 0;
258                 //exit( 1 );
259         }
260         else
261
262         for(;;)
263         {
264                 size_t largest;
265                 void __based(segu)* p = LargestBasedFreeBlock(&largest);
266                 if (largest < sizeof(void far*))
267                 {
268                         if (p != NULL)
269                         _ffree(p);
270                         break;
271                 }
272                 *(void far* far*)p = NULL;
273                 total += largest;
274                 if (pFirst == NULL)
275                         pFirst = p;
276
277                 if (pLast != NULL)
278                         *(void far* far*)pLast = p;
279                 pLast = p;
280         }
281
282         while (pFirst != NULL)
283         {
284                 void far* p = *(void far* far*)pFirst;
285                 _ffree(pFirst);
286                 pFirst = p;
287         }
288         return total;
289 }*/
290
291 size_t GetFreeSize(void)
292 {
293         struct _heapinfo h_info;
294         int heap_status;
295         size_t h_free=0, h_total=0, h_used=0;
296
297         h_info._pentry = NULL;
298         for(;;) {
299                 heap_status = _heapwalk( &h_info );
300                 if( heap_status != _HEAPOK ) break;
301                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
302                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
303                 h_total += h_info._size;
304         }
305         heapstat0(heap_status);
306         return h_free;
307 }
308
309 size_t GetFarFreeSize(void)
310 {
311         struct _heapinfo fh_info;
312         int heap_status;
313         size_t fh_free=0, fh_total=0, fh_used=0;
314
315         fh_info._pentry = NULL;
316         for(;;) {
317                 heap_status = _fheapwalk( &fh_info );
318                 if( heap_status != _HEAPOK ) break;
319                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
320                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
321                 fh_total += fh_info._size;
322         }
323         heapstat0(heap_status);
324         return fh_free;
325 }
326
327 size_t GetNearFreeSize(void)
328 {
329         struct _heapinfo nh_info;
330         int heap_status;
331         size_t nh_free=0, nh_total=0, nh_used=0;
332
333         nh_info._pentry = NULL;
334         for(;;) {
335                 heap_status = _nheapwalk( &nh_info );
336                 if( heap_status != _HEAPOK ) break;
337                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
338                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
339                 nh_total += nh_info._size;
340         }
341         heapstat0(heap_status);
342         return nh_free;
343 }
344
345 void heapdump(void)
346 {
347         struct _heapinfo fh_info, nh_info, h_info;
348         int heap_status;
349         size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;
350         byte    scratch[1024],str[16];
351
352         HC_OpenDebug();
353
354         strcpy(scratch,"\n      == default ==\n\n");
355         write(heaphandle,scratch,strlen(scratch));
356         h_info._pentry = NULL;
357         h_free=0; h_total=0; h_used=0;
358         for(;;) {
359                 heap_status = _heapwalk( &h_info );
360                 if( heap_status != _HEAPOK ) break;
361
362                 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,16); strcat(scratch,str); strcat(scratch,"\n");
363                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
364                 if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
365                 h_total += h_info._size;
366                 write(heaphandle,scratch,strlen(scratch));
367         }
368         heapstat(heap_status, &scratch);
369         
370         //near
371         strcpy(scratch,"\n      == near ==\n\n");
372         write(heaphandle,scratch,strlen(scratch));
373         nh_info._pentry = NULL;
374         nh_free=0; nh_total=0; nh_used=0;
375         for(;;) {
376                 heap_status = _nheapwalk( &nh_info );
377                 if( heap_status != _HEAPOK ) break;
378                 
379                 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,16); strcat(scratch,str); strcat(scratch,"\n");
380 /*              printf( "  %s block at %Fp of size %4.4X\n",
381 (nh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
382 nh_info._pentry, nh_info._size );*/
383                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
384                 if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
385                 nh_total += nh_info._size;
386                 write(heaphandle,scratch,strlen(scratch));
387         }
388         heapstat(heap_status, &scratch);
389
390         //far
391         strcpy(scratch,"\n      == far ==\n\n");
392         write(heaphandle,scratch,strlen(scratch));
393         fh_info._pentry = NULL;
394         fh_free=0; fh_total=0; fh_used=0;
395         for(;;) {
396                 heap_status = _fheapwalk( &fh_info );
397                 if( heap_status != _HEAPOK ) break;
398
399                 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,16); strcat(scratch,str); strcat(scratch,"\n");
400                 /*printf( "  %s block at %Fp of size %4.4X\n",
401 (fh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
402 fh_info._pentry, fh_info._size );*/
403                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
404                 if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
405                 fh_total += fh_info._size;
406                 write(heaphandle,scratch,strlen(scratch));
407         }
408         heapstat(heap_status, &scratch);
409
410         strcpy(scratch,"\n");
411         strcat(scratch,kittengets(2,0,"Memory Type         Total      Used       Free\n"));
412         strcat(scratch,"----------------  --------   --------   --------\n");
413         printmeminfoline(&scratch, "Default", h_total, h_used, h_free);
414         printmeminfoline(&scratch, "Near", nh_total, nh_used, nh_free);
415         printmeminfoline(&scratch, "Far", fh_total, fh_used, fh_free);
416         strcat(scratch,"----------------  --------   --------   --------\n");
417         strcat(scratch,"coreleft = ");                  ultoa((dword)_coreleft(),str,10);               strcat(scratch,str);    strcat(scratch,"\n");
418         strcat(scratch,"farcoreleft = ");               ultoa((dword)_farcoreleft(),str,10);    strcat(scratch,str);    strcat(scratch,"\n");
419         strcat(scratch,"GetFreeSize = ");               ultoa((dword)GetFreeSize(),str,10);             strcat(scratch,str);    strcat(scratch,"\n");
420         strcat(scratch,"GetNearFreeSize = ");   ultoa((dword)GetNearFreeSize(),str,10); strcat(scratch,str);    strcat(scratch,"\n");
421         strcat(scratch,"GetFarFreeSize = ");    ultoa((dword)GetFarFreeSize(),str,10);  strcat(scratch,str);    strcat(scratch,"\n");
422         strcat(scratch,"memavl = ");                    ultoa((dword)_memavl(),str,10);                 strcat(scratch,str);    strcat(scratch,"\n");
423         strcat(scratch,"stackavail = ");                ultoa((dword)stackavail(),str,10);              strcat(scratch,str);    strcat(scratch,"\n");
424         write(heaphandle,scratch,strlen(scratch));
425         HC_CloseDebug();
426 }
427
428 void heapstat(int heap_status, byte *str)
429 {
430         switch( heap_status ) {
431                 case _HEAPEND:
432                         strcpy((str),"OK - end of heap\n");
433                 break;
434                 case _HEAPEMPTY:
435                         strcpy((str),"OK - heap is empty\n");
436                         
437                 break;
438                 case _HEAPBADBEGIN:
439                         strcpy((str),"ERROR - heap is damaged\n");
440                 break;
441                 case _HEAPBADPTR:
442                         strcpy((str),"ERROR - bad pointer to heap\n");
443                 break;
444                 case _HEAPBADNODE:
445                         strcpy((str),"ERROR - bad node in heap\n");
446         }
447         write(heaphandle,(str),strlen((str)));
448 }
449
450 void heapstat0(int heap_status)
451 {
452         switch( heap_status ) {
453                 case _HEAPEND:
454                         //printf("OK - end of heap\n");
455                 break;
456                 case _HEAPEMPTY:
457                         //printf("OK - heap is empty\n");
458                         
459                 break;
460                 case _HEAPBADBEGIN:
461                         printf("ERROR - heap is damaged\n");
462                 break;
463                 case _HEAPBADPTR:
464                         printf("ERROR - bad pointer to heap\n");
465                 break;
466                 case _HEAPBADNODE:
467                         printf("ERROR - bad node in heap\n");
468         }
469 }
470
471 /*
472 ============================
473 =
474 = HC_OpenDebug / HC_CloseDebug
475 =
476 = Opens a binary file with the handle "heaphandle"
477 =
478 ============================
479 */
480 void HC_OpenDebug()
481 {
482         unlink("heap.16");
483         heaphandle = open("heap.16", O_CREAT | O_WRONLY | O_TEXT);
484 }
485
486 void HC_CloseDebug()
487 {
488         close(heaphandle);
489 }