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