]> Shamusworld >> Repos - virtualjaguar/blob - src/memory.cpp
9cff768f35c6436c403fb92a9343ee39062c5b12
[virtualjaguar] / src / memory.cpp
1 //
2 // Memory handler
3 //
4 // by David Raingeard (Cal2)
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups by James L. Hammons
7 //
8
9 #include "memory.h"
10
11 #include <malloc.h>
12 #include <stdlib.h>
13 #include "log.h"
14
15 #warning This module needs some serious cleanup. !!! FIX !!!
16
17 // Useful structs (for doubly linked list in this case)
18
19 typedef struct sMemBlockInfo
20 {
21         void * ptr;
22         const char * info;
23         uint32 size;
24         sMemBlockInfo * next;
25         sMemBlockInfo * prev;
26 } sMemBlockInfo;
27
28 // Private global variables
29
30 static sMemBlockInfo memoryInfo;
31 //static uint32 memoryMaxAllocated;
32 static uint32 currentAllocatedMemory;
33 static uint32 maximumAllocatedMemory;
34
35
36 void memory_addMemInfo(void * ptr, uint32 size, const char * info)
37 {
38         sMemBlockInfo * alias = &memoryInfo;
39
40         while (alias->next)
41                 alias = alias->next;
42
43         alias->next = (sMemBlockInfo *)malloc(sizeof(sMemBlockInfo));
44
45         if (alias->next == NULL)
46         {
47                 exit(0);
48                 return;
49         }
50
51         alias->next->prev = alias;
52         alias = alias->next;
53         alias->next = NULL;
54         alias->size = size;
55         alias->ptr = ptr;
56         alias->info = info;
57 }
58
59 void MemoryInit(void)
60 {
61         memoryInfo.next = memoryInfo.prev = NULL;
62         currentAllocatedMemory = maximumAllocatedMemory = 0;
63 }
64
65 void MemoryDone(void)
66 {
67 }
68
69 void * memory_malloc(uint32 size, const char * info)
70 {
71         void * ptr = (void *)malloc(size);
72
73         if (ptr == NULL)
74                 return NULL;
75
76         memory_addMemInfo(ptr, size, info);
77         currentAllocatedMemory += size;
78
79         if (currentAllocatedMemory > maximumAllocatedMemory)
80                 maximumAllocatedMemory = currentAllocatedMemory;
81
82         return ptr;
83 }
84
85 // OK, this sux, causes the compiler to complain about type punned pointers.
86 // The only difference between this and the previous is that this one ABORTS
87 // if it can't allocate the memory. BAD BAD BAD
88
89 void memory_malloc_secure(void ** new_ptr, uint32 size, const char * info)
90 {
91         WriteLog("Memory: Allocating %i bytes of memory for <%s>...", size, (info == NULL ? "unknown" : info));
92
93         void * ptr = malloc(size);
94
95         if (ptr == NULL)
96         {
97                 WriteLog("Failed!\n");
98                 LogDone();
99
100 #warning BAD, BAD, BAD! Need to do better than this!!!
101 #warning And since we ARE keeping track of all memory allocations, we should unwind the stack here as well...!
102 #warning !!! FIX !!!
103
104                 exit(0);
105         }
106
107         memory_addMemInfo(ptr, size, info);
108         currentAllocatedMemory += size;
109
110         if (currentAllocatedMemory > maximumAllocatedMemory)
111                 maximumAllocatedMemory = currentAllocatedMemory;
112
113         *new_ptr = ptr;
114         WriteLog("OK\n");
115 }
116
117 /*
118 void * memory_malloc_secure2(uint32 size, const char * info)
119 {
120         WriteLog("Memory: Allocating %i bytes of memory for <%s>...", size, (info == NULL ? "unknown" : info));
121
122         void * ptr = malloc(size);
123
124         if (ptr == NULL)
125         {
126                 WriteLog("Failed!\n");
127                 log_done();
128
129 //BAD, BAD, BAD! Need to do better than this!!!
130 //And since we ARE keeping track of all memory allocations, we should unwind the stack here as well...!
131 // !!! FIX !!!
132
133                 exit(0);
134         }
135
136         memory_addMemInfo(ptr, size, info);
137         currentAllocatedMemory += size;
138
139         if (currentAllocatedMemory > maximumAllocatedMemory)
140                 maximumAllocatedMemory = currentAllocatedMemory;
141
142         new_ptr = ptr;
143         WriteLog("OK\n");
144 }
145 */
146
147 void memory_free(void * ptr)
148 {
149 //      sMemBlockInfo * alias= &memoryInfo;
150 //      alias = alias->next;
151         sMemBlockInfo * alias= memoryInfo.next;
152
153         while (alias->ptr != ptr)
154                 alias = alias->next;
155
156         WriteLog("Memory: Freeing %i bytes from <%s>...\n", (int)alias->size, alias->info);
157
158         free(ptr);
159         currentAllocatedMemory -= alias->size;
160         alias->prev->next = alias->next;
161
162         if (alias->next != NULL)
163                 alias->next->prev = alias->prev;
164
165         free(alias);
166 }
167
168 void memory_memoryUsage(FILE * fp)
169 {
170         uint32 total = 0;
171
172         fprintf(fp, "Memory usage:\n");
173
174 //      sMemBlockInfo * alias = &memoryInfo;
175 //      alias = alias->next;
176         sMemBlockInfo * alias= memoryInfo.next;
177
178         while (alias)
179         {
180 //              fprintf(fp, "\t%16i bytes: <%s> (@ %08X)\n", (int)alias->size, alias->info, (unsigned int)alias->ptr);
181                 fprintf(fp, "\t%16i bytes: <%s> (@ %08X)\n", (int)alias->size, alias->info, alias->ptr);
182                 total += alias->size;
183                 alias = alias->next;
184         }
185
186         fprintf(fp, "\n\t%16i bytes total(%i Mb)\n", (int)total, (int)(total >> 20));
187         fprintf(fp, "\n\t%16i bytes memory peak(%i Mb)\n", (int)maximumAllocatedMemory, (int)(maximumAllocatedMemory >> 20));
188 }