00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "MemoryManager.h"
00022
00023 #include "SegmentedAllocator.h"
00024
00025 MemoryManager* MemoryManager::memorymanager = 0;
00026
00027 MemoryManager::MemoryManager()
00028 {
00029 assert(memorymanager == 0);
00030 memorymanager = this;
00031
00033 allocatorCount = 2;
00034
00035 allocators[0] = new SegmentedAllocator(192, 8500);
00036 allocators[1] = new SegmentedAllocator(4224, 25);
00037
00038 Pentagram::setAllocationFunctions(MemoryManager::allocate,
00039 MemoryManager::deallocate);
00040 }
00041
00042 MemoryManager::~MemoryManager()
00043 {
00044 memorymanager = 0;
00045
00046 Pentagram::setAllocationFunctions(malloc, free);
00047 delete allocators[0];
00048 delete allocators[1];
00049 }
00050
00051 void * MemoryManager::_allocate(size_t size)
00052 {
00053 int i;
00054
00055 for (i = 0; i < allocatorCount; ++i)
00056 {
00057 if (allocators[i]->getCapacity() >= size)
00058 {
00059 return allocators[i]->allocate(size);
00060 }
00061 }
00062
00063
00064 void * ptr = malloc(size);
00065 #ifdef DEBUG
00066 con.Printf("MemoryManager::allocate - Allocated %d bytes to 0x%X\n", size, ptr);
00067 #endif
00068
00069 return ptr;
00070 }
00071
00072 void MemoryManager::_deallocate(void * ptr)
00073 {
00074 Pool * p;
00075 int i;
00076 for (i = 0; i < allocatorCount; ++i)
00077 {
00078 p = allocators[i]->findPool(ptr);
00079 if (p)
00080 {
00081 p->deallocate(ptr);
00082 return;
00083 }
00084 }
00085
00086 #ifdef DEBUG
00087 con.Printf("MemoryManager::deallocate - deallocating memory at 0x%X\n", ptr);
00088 #endif
00089
00090 free(ptr);
00091 }
00092
00093 void MemoryManager::freeResources()
00094 {
00095 int i;
00096 for (i = 0; i < allocatorCount; ++i)
00097 {
00098 allocators[i]->freeResources();
00099 }
00100 }
00101
00102 void MemoryManager::ConCmd_MemInfo(const Console::ArgvType &argv)
00103 {
00104 MemoryManager * mm = MemoryManager::get_instance();
00105 int i, count;
00106
00107 if (!mm)
00108 return;
00109
00110 count = mm->getAllocatorCount();
00111
00112 pout << "Allocators: " << count << std::endl;
00113 for (i = 0; i < count; ++i)
00114 {
00115 pout << " Allocator " << i << ": " << std::endl;
00116 mm->getAllocator(i)->printInfo();
00117 pout << "==============" << std::endl;
00118 }
00119 }
00120
00121 #ifdef DEBUG
00122
00123 #include <SDL.h>
00124
00125 class TestClassBase
00126 {
00127 public:
00128 TestClassBase()
00129 {
00130 next = 0;
00131 }
00132
00133 virtual ~TestClassBase()
00134 {
00135 }
00136
00137 void setNext(TestClassBase * n)
00138 {
00139 n->next = next;
00140 next = n;
00141 }
00142
00143 void removeNext()
00144 {
00145 TestClassBase * n;
00146 if (! next)
00147 return;
00148 n = next;
00149 next = n->next;
00150 delete n;
00151 }
00152
00153 ENABLE_RUNTIME_CLASSTYPE();
00154
00155 TestClassBase *next;
00156 int arr[32];
00157 };
00158
00159 DEFINE_RUNTIME_CLASSTYPE_CODE_BASE_CLASS(TestClassBase);
00160
00161 class TestClassOne: public TestClassBase
00162 {
00163 public:
00164 TestClassOne()
00165 {
00166 }
00167
00168 virtual ~TestClassOne()
00169 {
00170 }
00171
00172 ENABLE_RUNTIME_CLASSTYPE();
00173 };
00174
00175 DEFINE_RUNTIME_CLASSTYPE_CODE(TestClassOne, TestClassBase);
00176
00177
00178 class TestClassTwo: public TestClassBase
00179 {
00180 public:
00181 TestClassTwo()
00182 {
00183 }
00184
00185 virtual ~TestClassTwo()
00186 {
00187 }
00188
00189 ENABLE_RUNTIME_CLASSTYPE();
00190 ENABLE_CUSTOM_MEMORY_ALLOCATION();
00191 };
00192
00193 DEFINE_RUNTIME_CLASSTYPE_CODE(TestClassTwo, TestClassBase);
00194 DEFINE_CUSTOM_MEMORY_ALLOCATION(TestClassTwo);
00195
00196 void MemoryManager::ConCmd_test(const Console::ArgvType &argv)
00197 {
00198
00199 int a[10] = {1000, 1231, 2423, 1233, 3213, 2554, 1123, 2432, 3311, 1022};
00200 int b[10] = {900, 1111, 2321, 1000, 1321, 1432, 1123, 2144, 2443, 0};
00201 int i, j, repeat;
00202 uint32 pooled, unpooled;
00203 TestClassBase * t;
00204
00205 t = new TestClassBase();
00206
00207 unpooled = SDL_GetTicks();
00208 for (repeat=0; repeat < 100; ++repeat)
00209 {
00210 for (i=0; i < 10; ++i)
00211 {
00212
00213 for (j=0; j < a[i]; ++j)
00214 {
00215 t->setNext(new TestClassOne());
00216 }
00217
00218 for (j=0; j < b[i]; ++j)
00219 {
00220 t->removeNext();
00221 }
00222 }
00223 while (t->next)
00224 {
00225 t->removeNext();
00226 }
00227 }
00228 unpooled = SDL_GetTicks() - unpooled;
00229
00230 pooled = SDL_GetTicks();
00231 for (repeat=0; repeat < 100; ++repeat)
00232 {
00233 for (i=0; i < 10; ++i)
00234 {
00235
00236 for (j=0; j < a[i]; ++j)
00237 {
00238 t->setNext(new TestClassTwo());
00239 }
00240
00241 for (j=0; j < b[i]; ++j)
00242 {
00243 t->removeNext();
00244 }
00245 }
00246 while (t->next)
00247 {
00248 t->removeNext();
00249 }
00250 }
00251 pooled = SDL_GetTicks() - pooled;
00252
00253 delete t;
00254
00255 con.Printf("Unpooled Allocation: %d ms\nPooled Allocation: %d ms\n", unpooled, pooled);
00256 }
00257
00258 #else
00259 void MemoryManager::ConCmd_test(const Console::ArgvType &argv)
00260 {
00261 }
00262
00263 #endif
00264