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