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