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