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