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