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