00001 #include "flGlobal.h"
00002 #if FL_MEMORY != 0
00003 #include <malloc.h>
00004 #include <stdio.h>
00005 #include <string.h>
00006 #include <pspkernel.h>
00007
00008 #if FL_INCLUDE_ALL_C == 0
00009 #include "flMemory.h"
00010 #include "flFile.h"
00011
00012 #if FL_DEBUG
00013 #include "flDebug.h"
00014 #endif
00015 #endif
00016
00017 #if FL_MEMORY_PAGE
00018 unsigned int memPageID = 0;
00019 #endif
00020
00021 #if FL_MEMORY_ERRORBYTES
00022 MemoryTree* memErrorTree = NULL;
00023 #endif
00024
00025 bool memInitialized = false;
00026 bool memScratchpadUsed = false;
00027
00028 void memInit() {
00029 #if ((FL_MEMORY_PAGE) || (FL_MEMORY_SCRATCHPAD))
00030 FILE* tempFile;
00031 #endif
00032
00033 #if FL_MEMORY_PAGE
00034 tempFile = fopen(MEMORY_PAGE_PATH, "w");
00035 if(!tempFile) {
00036 #if FL_DEBUG_ERROR
00037 debugError("Couldn't create blank memory page file at \"%s\".", MEMORY_PAGE_PATH);
00038 #endif
00039 return;
00040 }
00041 #if FL_DEBUG_STATUS
00042 debugStatusLog("Clearing page file.");
00043 #endif
00044 fclose(tempFile);
00045 #endif
00046
00047 #if FL_MEMORY_SCRATCHPAD
00048 bool tempClear = true; u32 i;
00049 for(i = MEMORY_SCRATCHPAD_BASE; i < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE); i++) {
00050 if(*((u8*)i)) {
00051 tempClear = false;
00052 break;
00053 }
00054 }
00055 if(!tempClear) {
00056 #if FL_DEBUG_STATUS
00057 debugStatusLog("Dumping scratchpad.");
00058 #endif
00059 u8 tempBuffer[16384];
00060 memCopy(tempBuffer, (void*)MEMORY_SCRATCHPAD_BASE, MEMORY_SCRATCHPAD_SIZE);
00061 tempFile = fopen("./scratchpad.dump", "w");
00062 if(tempFile) {
00063 fwrite(tempBuffer, 512, 32, tempFile);
00064 fclose(tempFile);
00065 }
00066 }
00067 #endif
00068
00069 memInitialized = true;
00070 }
00071
00072 void memTerm() {
00073 #if FL_MEMORY_PAGE
00074 #if FL_DEBUG_STATUS
00075 debugStatusLog("Deleting page file.");
00076 #endif
00077 fileDelete(FL_MEMORY_PAGE_PATH);
00078 #endif
00079
00080 #if FL_MEMORY_SCRATCHPAD
00081 #if FL_DEBUG_STATUS
00082 debugStatusLog("Restoring scratchpad.");
00083 #endif
00084 u8 tempBuffer[16384];
00085 FILE* tempFile = fopen("./scratchpad.dump", "r");
00086 if(tempFile) {
00087 fread(tempBuffer, 4, 4096, tempFile);
00088 fclose(tempFile);
00089 fileDelete("./scratchpad.dump");
00090 memCopy((void*)MEMORY_SCRATCHPAD_BASE, tempBuffer, MEMORY_SCRATCHPAD_SIZE);
00091 } else
00092 memClear((void*)MEMORY_SCRATCHPAD_BASE, MEMORY_SCRATCHPAD_SIZE);
00093 #endif
00094
00095 memInitialized = false;
00096 #if FL_DEBUG_STATUS
00097 debugStatusLog("Memory terminated.");
00098 #endif
00099 }
00100
00101 u32 memFreeSpace(u32 inAccuracy) {
00102 if(!inAccuracy)
00103 inAccuracy = 1;
00104
00105 u32 tempBlockSize = (MEMORY_USER_SIZE >> 1);
00106 u32 tempFreeSpace = 0;
00107 void* tempPointers[8192];
00108 u32 tempPtr = 0;
00109 while((tempPtr < 8192) && (tempBlockSize > inAccuracy)) {
00110 tempPointers[tempPtr] = malloc(tempBlockSize);
00111 while(tempPointers[tempPtr]) {
00112 tempPtr++;
00113 tempFreeSpace += tempBlockSize;
00114 tempPointers[tempPtr] = malloc(tempBlockSize);
00115 }
00116 tempBlockSize >>= 1;
00117 }
00118
00119 tempPtr = 0;
00120 while(tempPointers[tempPtr]) {
00121 free(tempPointers[tempPtr]);
00122 tempPtr++;
00123 }
00124
00125 return tempFreeSpace;
00126 }
00127
00128 u32 memFreeSpaceTotal() {
00129 u32 tempTotal = (memScratchpadUsed ? 0 : 16384);
00130 tempTotal += memFreeSpace(1);
00131 #if FL_MEMORY_VMEM
00132 tempTotal += vmemFreeSpace();
00133 #endif
00134 return tempTotal;
00135 }
00136
00137 char* memString(u32 inBytes, bool inBinary) {
00138 u32 i = 0;
00139 float tempBytes = inBytes;
00140
00141 if(inBinary) {
00142 while(inBytes >> 10) {
00143 i++;
00144 tempBytes /= 1024.0f;
00145 inBytes >>= 10;
00146 }
00147 } else {
00148 while(inBytes / 1000) {
00149 i++;
00150 tempBytes /= 1000.0f;
00151 inBytes /= 1000;
00152 }
00153 }
00154
00155 char* tempOut = memAlloc(16);
00156 sprintf(tempOut, "%4.2f ", tempBytes);
00157
00158 if(i & 1) {
00159 if(i == 1)
00160 strcat(tempOut, "K");
00161 else
00162 strcat(tempOut, "G");
00163 } else
00164 strcat(tempOut, "M");
00165
00166 if(i && inBinary)
00167 strcat(tempOut, "i");
00168
00169 strcat(tempOut, "B");
00170
00171 return tempOut;
00172 }
00173
00174 #if FL_DEBUG_CALLEDFROM
00175 void memSetByteFrom(void* inPtr, int inVal, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
00176 #else
00177 void memSetByte(void* inPtr, int inVal, unsigned int inSize) {
00178 #endif
00179 if(!inPtr || !inSize) {
00180 #if FL_DEBUG_WARNING
00181 char tempString[256];
00182 tempString[0] = 0;
00183 if(!inPtr)
00184 strcat(tempString, "memSetByte failed, pointer is NULL.\n");
00185 if(!inSize)
00186 strcat(tempString, "Trying to memSetByte 0 bytes of memory.\n");
00187
00188 #if FL_DEBUG_CALLEDFROM
00189 debugWarningFrom(inFile, inFunc, inLine, tempString);
00190 #else
00191 debugWarning(tempString);
00192 #endif
00193 #endif
00194 return;
00195 }
00196 if(!memBlockValid(inPtr, inSize)) {
00197 #if FL_DEBUG_WARNING
00198 #if FL_DEBUG_CALLEDFROM
00199 debugWarningFrom(inFile, inFunc, inLine, "(memSetByte) Trying to memSetByte an invalid memory block.");
00200 #else
00201 debugWarning("Trying to memSetByte an invalid memory block.");
00202 #endif
00203 #endif
00204 return;
00205 }
00206
00207 inSize += (u32)inPtr;
00208 if((inSize & 3) || ((u32)inPtr & 3)) {
00209 if((inSize & 1) || ((u32)inPtr & 1)) {
00210 u8 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x80 : 0x00));
00211 u8* tempPtr = (u8*)inPtr;
00212 while((u32)tempPtr < inSize)
00213 *(tempPtr++) = tempVal;
00214 } else {
00215 u16 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x80 : 0x00));
00216 tempVal |= (tempVal << 8);
00217 u16* tempPtr = (u16*)inPtr;
00218 while((u32)tempPtr < inSize)
00219 *(tempPtr++) = tempVal;
00220 }
00221 } else {
00222 u32 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x80 : 0x00));
00223 tempVal |= (tempVal << 8);
00224 tempVal |= (tempVal << 16);
00225 u32* tempPtr = (u32*)inPtr;
00226 while((u32)tempPtr < inSize)
00227 *(tempPtr++) = tempVal;
00228 }
00229
00230 #if FL_MEMORY_ERRORBYTES
00231 #if FL_DEBUG_CALLEDFROM
00232 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00233 #else
00234 memtErrorBytesCheck(&memErrorTree);
00235 #endif
00236 #endif
00237 }
00238
00239 #if FL_DEBUG_CALLEDFROM
00240 void memSetShortFrom(void* inPtr, int inVal, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
00241 #else
00242 void memSetShort(void* inPtr, int inVal, unsigned int inSize) {
00243 #endif
00244 if(!inPtr || !inSize) {
00245 #if FL_DEBUG_WARNING
00246 char tempString[256];
00247 tempString[0] = 0;
00248 if(!inPtr)
00249 strcat(tempString, "memSetShort failed, pointer is NULL.\n");
00250 if(!inSize)
00251 strcat(tempString, "Trying to memSetShort 0 bytes of memory.\n");
00252
00253 #if FL_DEBUG_CALLEDFROM
00254 debugWarningFrom(inFile, inFunc, inLine, tempString);
00255 #else
00256 debugWarning(tempString);
00257 #endif
00258 #endif
00259 return;
00260 }
00261 if(!memBlockValid(inPtr, inSize)) {
00262 #if FL_DEBUG_WARNING
00263 #if FL_DEBUG_CALLEDFROM
00264 debugWarningFrom(inFile, inFunc, inLine, "(memSetShort) Trying to memSetShort an invalid memory block.");
00265 #else
00266 debugWarning("Trying to memSetShort an invalid memory block.");
00267 #endif
00268 #endif
00269 return;
00270 }
00271
00272 inSize += (u32)inPtr;
00273 if((inSize & 3) || ((u32)inPtr & 3)) {
00274 if((inSize & 1) || ((u32)inPtr & 1)) {
00275 u16 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x8000 : 0x0000));
00276 u8* tempPtr = (u8*)inPtr;
00277 if(inSize & 1)
00278 tempVal = ((tempVal & 0x00FF) << 8) | ((tempVal & 0xFF00) >> 8);
00279 while((u32)tempPtr < inSize) {
00280 *tempPtr = ((u32)tempPtr ? (tempVal & 0x00FF) : ((tempVal & 0xFF00) >> 8));
00281 tempPtr++;
00282 }
00283 } else {
00284 u16 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x8000 : 0x0000));
00285 u16* tempPtr = (u16*)inPtr;
00286 while((u32)tempPtr < inSize)
00287 *(tempPtr++) = tempVal;
00288 }
00289 } else {
00290 u32 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x8000 : 0x0000));
00291 tempVal |= (tempVal << 16);
00292 u32* tempPtr = (u32*)inPtr;
00293 while((u32)tempPtr < inSize)
00294 *(tempPtr++) = tempVal;
00295 }
00296
00297 #if FL_MEMORY_ERRORBYTES
00298 #if FL_DEBUG_CALLEDFROM
00299 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00300 #else
00301 memtErrorBytesCheck(&memErrorTree);
00302 #endif
00303 #endif
00304 }
00305
00306 #if FL_DEBUG_CALLEDFROM
00307 void memClearFrom(void* inPtr, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
00308 #else
00309 void memClear(void* inPtr, unsigned int inSize) {
00310 #endif
00311 if(!inPtr || !inSize) {
00312 #if FL_DEBUG_WARNING
00313 char tempString[256];
00314 tempString[0] = 0;
00315 if(!inPtr)
00316 strcat(tempString, "memClear failed, pointer is NULL.\n");
00317 if(!inSize)
00318 strcat(tempString, "Trying to memClear 0 bytes of memory.\n");
00319
00320 #if FL_DEBUG_CALLEDFROM
00321 debugWarningFrom(inFile, inFunc, inLine, tempString);
00322 #else
00323 debugWarning(tempString);
00324 #endif
00325 #endif
00326 return;
00327 }
00328 if(!memBlockValid(inPtr, inSize)) {
00329 #if FL_DEBUG_WARNING
00330 #if FL_DEBUG_CALLEDFROM
00331 debugWarningFrom(inFile, inFunc, inLine, "(memClear) Trying to memClear an invalid memory block.");
00332 #else
00333 debugWarning("Trying to memClear an invalid memory block.");
00334 #endif
00335 #endif
00336 return;
00337 }
00338
00339 inSize += (u32)inPtr;
00340 if((inSize & 3) || ((u32)inPtr & 3)) {
00341 if((inSize & 3) || ((u32)inPtr & 3)) {
00342 u8* tempPtr = (u8*)inPtr;
00343 while((u32)tempPtr < inSize)
00344 *(tempPtr++) = 0x00;
00345 } else {
00346 u16* tempPtr = (u16*)inPtr;
00347 while((u32)tempPtr < inSize)
00348 *(tempPtr++) = 0x0000;
00349 }
00350 } else {
00351 u32* tempPtr = (u32*)inPtr;
00352 while((u32)tempPtr < inSize)
00353 *(tempPtr++) = 0x00000000;
00354 }
00355
00356 #if FL_MEMORY_ERRORBYTES
00357 #if FL_DEBUG_CALLEDFROM
00358 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00359 #else
00360 memtErrorBytesCheck(&memErrorTree);
00361 #endif
00362 #endif
00363 }
00364
00365 #if FL_DEBUG_CALLEDFROM
00366 void memCopyFrom(void* inDest, void* inSrc, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
00367 #else
00368 void memCopy(void* inDest, void* inSrc, unsigned int inSize) {
00369 #endif
00370 if(!inDest || !inSrc || !inSize) {
00371 #if FL_DEBUG_WARNING
00372 char tempString[256];
00373 tempString[0] = 0;
00374 if(!inDest)
00375 strcat(tempString, "Trying to memCopy to a NULL destination.\n");
00376 if(!inSrc)
00377 strcat(tempString, "Trying to memCopy from a NULL source.\n");
00378 if(!inSize)
00379 strcat(tempString, "Trying to memCopy 0 bytes of memory.\n");
00380
00381 #if FL_DEBUG_CALLEDFROM
00382 debugWarningFrom(inFile, inFunc, inLine, tempString);
00383 #else
00384 debugWarning(tempString);
00385 #endif
00386 #endif
00387 return;
00388 }
00389
00390 if((((u32)inDest + inSize) < (u32)inDest) || (((u32)inSrc + inSize) < (u32)inSrc)) {
00391 #if FL_DEBUG_WARNING
00392 #if FL_DEBUG_CALLEDFROM
00393 debugWarningFrom(inFile, inFunc, inLine, "(memCopy) Unsigned integer overflow while copying data.");
00394 #else
00395 debugWarning("Unsigned integer overflow while copying data.");
00396 #endif
00397 #endif
00398 return;
00399 }
00400
00401
00402 if((((u32)inSrc + inSize) > (u32)inDest) && (((u32)inSrc + inSize) <= ((u32)inDest + inSize))) {
00403 u32 tempSize = (((u32)inSrc + inSize) - (u32)inDest);
00404 void* tempBuffer = memQalloc(tempSize);
00405 memCopy(tempBuffer, (void*)((u32)inSrc + (inSize - tempSize)), tempSize);
00406 memCopy((void*)((u32)inDest + tempSize), inSrc, (inSize - tempSize));
00407 memCopy(inDest, tempBuffer, tempSize);
00408 memFree(tempBuffer);
00409 return;
00410 }
00411
00412 if(!memBlockValid(inSrc, inSize) || !memBlockValid(inDest, inSize)) {
00413 #if FL_DEBUG_WARNING
00414 #if FL_DEBUG_CALLEDFROM
00415 debugWarningFrom(inFile, inFunc, inLine, "(memCopy) Trying to memCopy to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inDest, ((unsigned int)inDest + inSize), (unsigned int)inSrc, ((unsigned int)inSrc + inSize));
00416 #else
00417 debugWarning("Trying to memCopy to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inDest, ((unsigned int)inDest + inSize), (unsigned int)inSrc, ((unsigned int)inSrc + inSize));
00418 #endif
00419 #endif
00420 return;
00421 }
00422
00423 inSize += (u32)inDest;
00424 if((inSize & 3) || ((u32)inDest & 3) || ((u32)inSrc & 3)) {
00425 if((inSize & 1) || ((u32)inDest & 1) || ((u32)inSrc & 1)) {
00426 u8* tempDest = (u8*)inDest;
00427 u8* tempSrc = (u8*)inSrc;
00428 while((u32)tempDest < inSize)
00429 *(tempDest++) = *(tempSrc++);
00430 } else {
00431 u16* tempDest = (u16*)inDest;
00432 u16* tempSrc = (u16*)inSrc;
00433 while((u32)tempDest < inSize)
00434 *(tempDest++) = *(tempSrc++);
00435 }
00436 } else {
00437 u32* tempDest = (u32*)inDest;
00438 u32* tempSrc = (u32*)inSrc;
00439 while((u32)tempDest < inSize)
00440 *(tempDest++) = *(tempSrc++);
00441 }
00442
00443 #if FL_MEMORY_ERRORBYTES
00444 #if FL_DEBUG_CALLEDFROM
00445 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00446 #else
00447 memtErrorBytesCheck(&memErrorTree);
00448 #endif
00449 #endif
00450 }
00451
00452 #if FL_DEBUG_CALLEDFROM
00453 int memCompareFrom(void* inSrc0, void* inSrc1, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
00454 #else
00455 int memCompare(void* inSrc0, void* inSrc1, unsigned int inSize) {
00456 #endif
00457 if(!inSrc0 || !inSrc1 || !inSize) {
00458 #if FL_DEBUG_WARNING
00459 char tempString[256];
00460 tempString[0] = 0;
00461 if(!inSrc0 || !inSrc1)
00462 strcat(tempString, "Trying to memCompare to a NULL region.\n");
00463 if(!inSize)
00464 strcat(tempString, "Trying to memCompare 0 bytes of memory.\n");
00465 #if FL_DEBUG_CALLEDFROM
00466 debugWarningFrom(inFile, inFunc, inLine, tempString);
00467 #else
00468 debugWarning(tempString);
00469 #endif
00470 #endif
00471 return -1;
00472 }
00473
00474 if((((u32)inSrc0 + inSize) < (u32)inSrc1) || (((u32)inSrc0 + inSize) < (u32)inSrc1)) {
00475 #if FL_DEBUG_WARNING
00476 #if FL_DEBUG_CALLEDFROM
00477 debugWarningFrom(inFile, inFunc, inLine, "(memCompare) Unsigned integer overflow while comparing data.");
00478 #else
00479 debugWarning("Unsigned integer overflow while comparing data.");
00480 #endif
00481 #endif
00482 return -1;
00483 }
00484
00485 if(!memBlockValid(inSrc0, inSize) || !memBlockValid(inSrc1, inSize)) {
00486 #if FL_DEBUG_WARNING
00487 #if FL_DEBUG_CALLEDFROM
00488 debugWarningFrom(inFile, inFunc, inLine, "(memCompare) Trying to memCompare to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inSrc0, ((unsigned int)inSrc0 + inSize), (unsigned int)inSrc1, ((unsigned int)inSrc1 + inSize));
00489 #else
00490 debugWarning("Trying to memCompare to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inSrc0, ((unsigned int)inSrc0 + inSize), (unsigned int)inSrc1, ((unsigned int)inSrc1 + inSize));
00491 #endif
00492 #endif
00493 return -1;
00494 }
00495
00496 int tempOut = memcmp(inSrc0, inSrc1, inSize);
00497
00498 #if FL_MEMORY_ERRORBYTES
00499 #if FL_DEBUG_CALLEDFROM
00500 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00501 #else
00502 memtErrorBytesCheck(&memErrorTree);
00503 #endif
00504 #endif
00505
00506 return tempOut;
00507 }
00508
00509
00510 #if FL_DEBUG_CALLEDFROM
00511 void* memAllocFrom(int inSize, const char* inFile, const char* inFunc, int inLine) {
00512 return memAlignFrom(FL_MEMORY_ALIGNMENT_DEFAULT, inSize, inFile, inFunc, inLine);
00513 }
00514 #else
00515 void* memAlloc(int inSize) {
00516 return memAlign(FL_MEMORY_ALIGNMENT_DEFAULT, inSize);
00517 }
00518 #endif
00519
00520 #if FL_DEBUG_CALLEDFROM
00521 void* memQallocFrom(int inSize, const char* inFile, const char* inFunc, int inLine) {
00522 #else
00523 void* memQalloc(int inSize) {
00524 #endif
00525 #if FL_MEMORY_SCRATCHPAD
00526 if(memInitialized) {
00527 if((inSize <= MEMORY_SCRATCHPAD_SIZE) && !memScratchpadUsed) {
00528 memScratchpadUsed = true;
00529 return (void*)MEMORY_SCRATCHPAD_BASE;
00530 }
00531 }
00532 #endif
00533
00534 void* tempOut;
00535
00536 #if FL_MEMORY_VMEM
00537 if(vmemInitialized) {
00538 tempOut = vmemAlloc(inSize);
00539 if(tempOut)
00540 return tempOut;
00541 }
00542 #endif
00543
00544 tempOut = memAlloc(inSize);
00545
00546 #if FL_DEBUG_WARNING
00547 if(!tempOut) {
00548 #if FL_DEBUG_CALLEDFROM
00549 debugWarningFrom(inFile, inFunc, inLine, "Error allocating memory using memQalloc.\nMemory full/fragmented.");
00550 #else
00551 debugWarningFrom("Error allocating memory using memQalloc.\nMemory full/fragmented.");
00552 #endif
00553 }
00554 #endif
00555
00556 return tempOut;
00557 }
00558
00559 #if FL_DEBUG_CALLEDFROM
00560 void* memCallocFrom(int inSize0, int inSize1, const char* inFile, const char* inFunc, int inLine) {
00561 void* tempOut = memAllocFrom((inSize0 * inSize1), inFile, inFunc, inLine);
00562 #else
00563 void* memCalloc(int inSize0, int inSize1) {
00564 void* tempOut = memAlloc(inSize0 * inSize1);
00565 #endif
00566 if(!tempOut)
00567 return NULL;
00568 #if FL_DEBUG_CALLEDFROM
00569 memClearFrom(tempOut, (inSize0 * inSize1), inFile, inFunc, inLine);
00570 #else
00571 memClear(tempOut, (inSize0 * inSize1));
00572 #endif
00573 return tempOut;
00574 }
00575
00576 #if FL_DEBUG_CALLEDFROM
00577 void* memAllocUncachedFrom(int inSize, const char* inFile, const char* inFunc, int inLine) {
00578 #else
00579 void* memAllocUncached(int inSize) {
00580 #endif
00581 void* tempOut = memAlign(max(64, FL_MEMORY_ALIGNMENT_DEFAULT), inSize);
00582 if(!tempOut) {
00583 #if FL_DEBUG_WARNING
00584 #if FL_DEBUG_CALLEDFROM
00585 debugWarningFrom(inFile, inFunc, inLine, "(memAllocUncached) Error allocating uncached memory, memory is probably full/fragmented.");
00586 #else
00587 debugWarning("Error allocating uncached memory, memory is probably full/fragmented.");
00588 #endif
00589 #endif
00590 return NULL;
00591 }
00592 #if FL_MEMORY_ERRORBYTES
00593 if((inSize + (max(64, FL_MEMORY_ALIGNMENT_DEFAULT) << 1)) >= 16384)
00594 sceKernelDcacheWritebackInvalidateAll();
00595 else
00596 sceKernelDcacheWritebackInvalidateRange((void*)((unsigned int)tempOut - max(64, FL_MEMORY_ALIGNMENT_DEFAULT)), (inSize + (max(64, FL_MEMORY_ALIGNMENT_DEFAULT) << 1)));
00597 #else
00598 if(inSize >= 16384)
00599 sceKernelDcacheWritebackInvalidateAll();
00600 else
00601 sceKernelDcacheWritebackInvalidateRange(tempOut, inSize);
00602 #endif
00603 tempOut = memUncachedPtr(tempOut);
00604 return tempOut;
00605 }
00606
00607 #if FL_DEBUG_CALLEDFROM
00608 void* memReallocFrom(void* inData, int inSize, const char* inFile, const char* inFunc, int inLine) {
00609 #else
00610 void* memRealloc(void* inData, int inSize) {
00611 #endif
00612 #if FL_MEMORY_VMEM
00613 if(vmemPointer(inData))
00614 return vmemRealloc(inData, inSize);
00615 #endif
00616 if(!inSize) {
00617 #if FL_DEBUG_WARNING
00618 #if FL_DEBUG_CALLEDFROM
00619 debugWarningFrom(inFile, inFunc, inLine, "(memRealloc) Trying to re-allocate to 0 bytes.");
00620 #else
00621 debugWarning("Trying to re-allocate to 0 bytes.");
00622 #endif
00623 #endif
00624 return NULL;
00625 }
00626 #if FL_MEMORY_ERRORBYTES
00627 if(!memErrorBytesCheck(inData)) {
00628 #if FL_DEBUG_ERROR
00629 #if FL_DEBUG_CALLEDFROM
00630 debugErrorFrom(inFile, inFunc, inLine, "Error re-allocating memory, original data was corrupt.");
00631 #else
00632 debugError("Error re-allocating memory, original data was corrupt.");
00633 #endif
00634 #endif
00635 return NULL;
00636 }
00637 u32* tempData = (u32*)((unsigned int)inData - 16);
00638 u32 tempBoundry = tempData[0];
00639 while(inSize & (tempBoundry - 1))
00640 inSize++;
00641 inData = (void*)((unsigned int)inData - tempBoundry);
00642 void* tempOut = realloc(inData, (inSize + (tempBoundry << 1)));
00643 if(!tempOut) {
00644 #if FL_DEBUG_WARNING
00645 #if FL_DEBUG_CALLEDFROM
00646 debugWarningFrom(inFile, inFunc, inLine, "(memRealloc) Error re-allocating memory, memory is probably full/fragmented.");
00647 #else
00648 debugWarning("Error re-allocating memory, memory is probably full/fragmented.");
00649 #endif
00650 #endif
00651 return NULL;
00652 }
00653
00654 #if FL_DEBUG_CALLEDFROM
00655 memtAddFrom(&memErrorTree, tempOut, inSize, tempBoundry, inFile, inFunc, inLine);
00656 #else
00657 memtAdd(&memErrorTree, tempOut, inSize, tempBoundry);
00658 #endif
00659
00660 tempOut = (void*)((unsigned int)tempOut + tempBoundry);
00661 u32* tempPattern = (u32*)((unsigned int)tempOut - 16);
00662 tempPattern[0] = tempBoundry;
00663 tempPattern[1] = inSize;
00664 tempPattern[2] = 0xFEEBDAED;
00665 tempPattern[3] = 0x76543210;
00666 tempPattern = (u32*)((unsigned int)tempOut + inSize);
00667 tempPattern[0] = 0xDEADBEEF;
00668 tempPattern[1] = 0x01234567;
00669 tempPattern[2] = tempBoundry;
00670 tempPattern[3] = inSize;
00671
00672 #if FL_DEBUG_CALLEDFROM
00673 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00674 #else
00675 memtErrorBytesCheck(&memErrorTree);
00676 #endif
00677 #else
00678 if((unsigned int)inData & MEMORY_UNCACHED_OFFSET) {
00679 while(inSize & 63)
00680 inSize++;
00681 } else {
00682 while(inSize & 15)
00683 inSize++;
00684 }
00685 void* tempOut = realloc(inData, inSize);
00686 #if FL_DEBUG_WARNING
00687 if(!tempOut) {
00688 #if FL_DEBUG_CALLEDFROM
00689 debugWarningFrom(inFile, inFunc, inLine, "(memRealloc) Error re-allocating memory, memory is probably full/fragmented.");
00690 #else
00691 debugWarning("Error re-allocating memory, memory is probably full/fragmented.");
00692 #endif
00693 }
00694 #endif
00695 #endif
00696 if((unsigned int)inData & MEMORY_UNCACHED_OFFSET)
00697 tempOut = memUncachedPtr(tempOut);
00698 return tempOut;
00699 }
00700
00701 #if FL_DEBUG_CALLEDFROM
00702 void* memAlignFrom(int inBoundry, int inSize, const char* inFile, const char* inFunc, int inLine) {
00703 #else
00704 void* memAlign(int inBoundry, int inSize) {
00705 #endif
00706 if(!inSize) {
00707 #if FL_DEBUG_WARNING
00708 #if FL_DEBUG_CALLEDFROM
00709 debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Trying to allocate aligned data of 0 bytes.");
00710 #else
00711 debugWarning("Trying to allocate aligned data of 0 bytes.");
00712 #endif
00713 #endif
00714 return NULL;
00715 }
00716 if(!inBoundry) {
00717 #if FL_DEBUG_WARNING
00718 #if FL_DEBUG_CALLEDFROM
00719 debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Trying to align to 0 byte boundry.\nReverting to default allocation alignment.");
00720 #else
00721 debugWarning("Trying to align to 0 byte boundry.\nReverting to default allocation alignment.");
00722 #endif
00723 #endif
00724 }
00725
00726 if(inBoundry < FL_MEMORY_ALIGNMENT_DEFAULT)
00727 inBoundry = FL_MEMORY_ALIGNMENT_DEFAULT;
00728
00729 int i, tempBoundZeroCnt = 0, tempBoundMaxPower = 0;
00730 for(i = 0; i < (sizeof(void*) << 3); i++) {
00731 if(inBoundry & (1 << i)) {
00732 tempBoundZeroCnt++;
00733 tempBoundMaxPower = i;
00734 }
00735 }
00736 if(tempBoundZeroCnt > 1) {
00737 #if FL_DEBUG_WARNING
00738 #if FL_DEBUG_CALLEDFROM
00739 debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Trying to align to a non-binary boundry.\nReverting to next valid boundry.");
00740 #else
00741 debugWarning("Trying to align to a non-binary boundry.\nReverting to next valid boundry.");
00742 #endif
00743 #endif
00744 inBoundry = (1 << (tempBoundMaxPower + 1));
00745 }
00746
00747 while(inSize & (inBoundry - 1))
00748 inSize++;
00749
00750 void* tempOut;
00751
00752 #if FL_MEMORY_VMEM_STRIDE_FILL
00753 tempOut = vmemStrideAlign(inBoundry, inSize);
00754 if(tempOut)
00755 return tempOut;
00756 #endif
00757
00758 #if FL_MEMORY_ERRORBYTES
00759 tempOut = memalign(inBoundry, (inSize + (inBoundry << 1)));
00760 if(!tempOut) {
00761 #if FL_DEBUG_WARNING
00762 #if FL_DEBUG_CALLEDFROM
00763 debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Error allocating aligned memory, memory is probably full/fragmented.");
00764 #else
00765 debugWarning("Error allocating aligned memory, memory is probably full/fragmented.");
00766 #endif
00767 #endif
00768 return NULL;
00769 }
00770 #if FL_DEBUG_CALLEDFROM
00771 memtAddFrom(&memErrorTree, tempOut, inSize, inBoundry, inFile, inFunc, inLine);
00772 #else
00773 memtAdd(&memErrorTree, tempOut, inSize, inBoundry);
00774 #endif
00775
00776 tempOut = (void*)((unsigned int)tempOut + inBoundry);
00777 u32* tempPattern = (u32*)((unsigned int)tempOut - 16);
00778 tempPattern[0] = inBoundry;
00779 tempPattern[1] = inSize;
00780 tempPattern[2] = 0xFEEBDAED;
00781 tempPattern[3] = 0x76543210;
00782 tempPattern = (u32*)((unsigned int)tempOut + inSize);
00783 tempPattern[0] = 0xDEADBEEF;
00784 tempPattern[1] = 0x01234567;
00785 tempPattern[2] = inBoundry;
00786 tempPattern[3] = inSize;
00787
00788 #if FL_DEBUG_CALLEDFROM
00789 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00790 #else
00791 memtErrorBytesCheck(&memErrorTree);
00792 #endif
00793 #else
00794 tempOut = memalign(inBoundry, inSize);
00795 #if FL_DEBUG_WARNING
00796 if(!tempOut) {
00797 #if FL_DEBUG_CALLEDFROM
00798 debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Error allocating aligned memory, memory is probably full/fragmented.");
00799 #else
00800 debugWarning("Error allocating aligned memory, memory is probably full/fragmented.");
00801 #endif
00802 }
00803 #endif
00804 #endif
00805
00806 #if FL_MEMORY_VMEM_OVERFLOW
00807 if(!tempOut)
00808 tempOut = vmemAlloc(inSize);
00809 #endif
00810
00811 if(!tempOut && !memScratchpadUsed) {
00812 memScratchpadUsed = true;
00813 tempOut = (void*)MEMORY_SCRATCHPAD_BASE;
00814 }
00815
00816 return tempOut;
00817 }
00818
00819 #if FL_DEBUG_CALLEDFROM
00820 void memFreeFrom(void* inData, const char* inFile, const char* inFunc, int inLine) {
00821 #else
00822 void memFree(void* inData) {
00823 #endif
00824 if(!inData) {
00825 #if FL_DEBUG_WARNING
00826 #if FL_DEBUG_CALLEDFROM
00827 debugWarningFrom(inFile, inFunc, inLine, "(memFree) Trying to free NULL pointer.");
00828 #else
00829 debugWarning("Trying to free NULL pointer.");
00830 #endif
00831 #endif
00832 return;
00833 }
00834 if(!memAddressValid(inData)) {
00835 #if FL_DEBUG_WARNING
00836 #if FL_DEBUG_CALLEDFROM
00837 debugWarningFrom(inFile, inFunc, inLine, "(memFree) Trying to free invalid pointer (0x%08X).", (unsigned int)inData);
00838 #else
00839 debugWarning("Trying to free invalid pointer (0x%08X).", (unsigned int)inData);
00840 #endif
00841 #endif
00842 return;
00843 }
00844 if(((u32)inData >= MEMORY_SCRATCHPAD_BASE) && ((u32)inData < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE))) {
00845 memScratchpadUsed = false;
00846 return;
00847 }
00848 #if FL_MEMORY_VMEM
00849 if(vmemPointer(inData)) {
00850 #if FL_DEBUG_CALLEDFROM
00851 return vmemFreeFrom(inData, inFile, inFunc, inLine);
00852 #else
00853 return vmemFree(inData);
00854 #endif
00855 }
00856 #endif
00857 #if FL_MEMORY_ERRORBYTES
00858 if(!memErrorBytesCheck(inData)) {
00859 #if FL_DEBUG_ERROR
00860 #if FL_DEBUG_CALLEDFROM
00861 debugErrorFrom(inFile, inFunc, inLine, "(memFree) Cannot free pointer, data corrupt.");
00862 #else
00863 debugError("Cannot free pointer, data corrupt.");
00864 #endif
00865 #endif
00866 return;
00867 }
00868 u32* tempData = (u32*)((unsigned int)inData - 16);
00869 inData = (void*)((unsigned int)inData - tempData[0]);
00870 if(!inData) {
00871 #if FL_DEBUG_WARNING
00872 #if FL_DEBUG_CALLEDFROM
00873 debugWarningFrom(inFile, inFunc, inLine, "(memFree) Trying to free NULL pointer.");
00874 #else
00875 debugWarning("Trying to free NULL pointer.");
00876 #endif
00877 #endif
00878 return;
00879 }
00880 #endif
00881 #if FL_MEMORY_ERRORBYTES
00882 #if FL_DEBUG_CALLEDFROM
00883 memtDelFrom(&memErrorTree, inData, inFile, inFunc, inLine);
00884 memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
00885 #else
00886 memtDel(&memErrorTree, inData);
00887 memtErrorBytesCheck(&memErrorTree);
00888 #endif
00889 #endif
00890 free(inData);
00891 }
00892
00893 #if FL_DEBUG_CALLEDFROM
00894 void* memUncachedPtrFrom(void* inPtr, const char* inFile, const char* inFunc, int inLine) {
00895 #else
00896 void* memUncachedPtr(void* inPtr) {
00897 #endif
00898 if(!inPtr) {
00899 #if FL_DEBUG_WARNING
00900 #if FL_DEBUG_CALLEDFROM
00901 debugWarningFrom(inFile, inFunc, inLine, "(memUncachedPtr) Trying to create uncached null pointer.");
00902 #else
00903 debugWarning("Trying to create uncached null pointer.");
00904 #endif
00905 #endif
00906 return NULL;
00907 }
00908 inPtr = (void*)((unsigned int)inPtr | MEMORY_UNCACHED_OFFSET);
00909 return inPtr;
00910 }
00911
00912 u32 memAddressAlignment(void* inPtr) {
00913 u32 i;
00914 u32 tempBits = (sizeof(void*) << 3);
00915 for(i = 0; i < tempBits; i++) {
00916 if((u32)inPtr & (1 << i))
00917 return (1 << i);
00918 }
00919 return (1 << (tempBits - 1));
00920 }
00921
00922 bool memAddressValid(void* inPtr) {
00923 u32 tempPtr = (u32)memCachedPtr(inPtr);
00924 if((tempPtr >= MEMORY_USER_BASE) && (tempPtr < (MEMORY_USER_BASE + MEMORY_USER_SIZE)))
00925 return true;
00926 if((tempPtr >= MEMORY_SCRATCHPAD_BASE) && (tempPtr < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE)))
00927 return true;
00928 if((tempPtr >= MEMORY_VMEM_BASE) && (tempPtr < (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2))))
00929 return true;
00930 return false;
00931 }
00932
00933 bool memBlockValid(void* inPtr, u32 inSize) {
00934 u32 tempPtr[2];
00935 tempPtr[0] = (u32)memCachedPtr(inPtr);
00936 tempPtr[1] = ((tempPtr[0] + inSize) - 1);
00937 if((tempPtr[0] >= MEMORY_USER_BASE) && (tempPtr[0] < (MEMORY_USER_BASE + MEMORY_USER_SIZE))) {
00938 if((tempPtr[1] >= MEMORY_USER_BASE) && (tempPtr[1] < (MEMORY_USER_BASE + MEMORY_USER_SIZE)))
00939 return true;
00940 return false;
00941 }
00942 if((tempPtr[0] >= MEMORY_SCRATCHPAD_BASE) && (tempPtr[0] < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE))) {
00943 if((tempPtr[1] >= MEMORY_SCRATCHPAD_BASE) && (tempPtr[1] < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE)))
00944 return true;
00945 return false;
00946 }
00947 if((tempPtr[0] >= MEMORY_VMEM_BASE) && (tempPtr[0] < (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2)))) {
00948 if((tempPtr[1] >= MEMORY_VMEM_BASE) && (tempPtr[1] < (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2)))) {
00949 if((tempPtr[0] & (MEMORY_VMEM_SIZE - 1)) < (tempPtr[1] & (MEMORY_VMEM_SIZE - 1)))
00950 return true;
00951 return false;
00952 }
00953 return false;
00954 }
00955 return false;
00956 }
00957
00958 #if FL_MEMORY_PAGE
00959 unsigned int memToPage(void* inData, unsigned int inSize) {
00960 if(!inData) {
00961 #if FL_DEBUG_WARNING
00962 debugWarning("Trying to page NULL pointer.");
00963 #endif
00964 return 0;
00965 }
00966 if(!memBlockValid(inData, inSize)) {
00967 #if FL_DEBUG_WARNING
00968 debugWarning("Trying to page invalid memory block [%0x08X -> %0x08X].", (unsigned int)inData, ((unsigned int)inData + inSize));
00969 #endif
00970 return 0;
00971 }
00972 if(((unsigned int)inData >= MEMORY_SCRATCHPAD_BASE) && (inSize < MEMORY_SCRATCHPAD_SIZE)) {
00973 #if FL_DEBUG_WARNING
00974 debugWarning("Cannot page scratchpad data directly.");
00975 #endif
00976 return 0;
00977 }
00978
00979 FILE* tempFile = fopen(MEMORY_PAGE_PATH, "ab");
00980 if(!tempFile) {
00981 #if FL_DEBUG_ERROR
00982 debugError("Cannot open page file, to offload page.");
00983 #endif
00984 return 0;
00985 }
00986 unsigned int tempID = memPageID;
00987 memPageID++;
00988 fwrite(&tempID, 1, 4, tempFile);
00989 fwrite(&inSize, 1, 4, tempFile);
00990 fwrite(inData, 1, inSize, tempFile);
00991 fclose(tempFile);
00992 memFree(inData);
00993 return tempID;
00994 }
00995
00996 void* memFromPage(unsigned int inPageID) {
00997 if(!inPageID) {
00998 #if FL_DEBUG_WARNING
00999 debugWarning("Trying to retrieve page 0 (Error page).");
01000 #endif
01001 return NULL;
01002 }
01003 FILE* tempFile = fopen(MEMORY_PAGE_PATH, "rb");
01004 if(!tempFile) {
01005 #if FL_DEBUG_ERROR
01006 debugError("Cannot open page file, to retrieve paged data.");
01007 #endif
01008 return NULL;
01009 }
01010 unsigned int tempID = 0;
01011 unsigned int tempSize = 0;
01012 void* tempOut = NULL;
01013 while(!feof(tempFile)) {
01014 fread(&tempID, 1, 4, tempFile);
01015 fread(&tempSize, 1, 4, tempFile);
01016 if(tempID == inPageID) {
01017 tempOut = memAlloc(tempSize);
01018 if(!tempOut) {
01019 #if FL_DEBUG_ERROR
01020 debugError("Cannot load page file, memory allocation failed.");
01021 #endif
01022 return NULL;
01023 }
01024 fread(tempOut, 1, tempSize, tempFile);
01025 return tempOut;
01026 } else {
01027 fseek(tempFile, tempSize, SEEK_CUR);
01028 }
01029 }
01030 #if FL_DEBUG_ERROR
01031 debugError("Page with matching PageID not found within page file.");
01032 #endif
01033 return NULL;
01034 }
01035 #endif
01036
01037 #if FL_MEMORY_ERRORBYTES
01038 #if FL_DEBUG_CALLEDFROM
01039 bool memErrorBytesCheckFrom(void* inPtr, const char* inFile, const char* inFunc, int inLine) {
01040 #else
01041 bool memErrorBytesCheck(void* inPtr) {
01042 #endif
01043 u32 tempBoundry;
01044 u32 tempSize;
01045 u32* tempPtr = (u32*)((unsigned int)inPtr - 16);
01046 tempBoundry = tempPtr[0];
01047 tempSize = tempPtr[1];
01048 if((tempSize & (tempBoundry - 1)) || ((u32)inPtr & (tempBoundry - 1))) {
01049 #if FL_DEBUG_ERROR
01050 #if FL_DEBUG_CALLEDFROM
01051 debugErrorFrom(inFile, inFunc, inLine, "(memErrorBytesCheck) Memory integrity error, alignment doesn't match description.");
01052 #else
01053 debugError("Memory integrity error, alignment doesn't match description.");
01054 #endif
01055 #endif
01056 return false;
01057 }
01058 if((tempPtr[2] != 0xFEEBDAED) || (tempPtr[3] != 0x76543210)) {
01059 #if FL_DEBUG_ERROR
01060 #if FL_DEBUG_CALLEDFROM
01061 debugErrorFrom(inFile, inFunc, inLine, "(memErrorBytesCheck) Memory integrity error, underflow.");
01062 #else
01063 debugError("Memory integrity error, underflow.");
01064 #endif
01065 #endif
01066 return false;
01067 }
01068 tempPtr = (u32*)((unsigned int)inPtr + tempSize);
01069 if((tempPtr[0] != 0xDEADBEEF) || (tempPtr[1]!= 0x01234567) || (tempPtr[2] != tempBoundry) || (tempPtr[3] != tempSize)) {
01070 #if FL_DEBUG_ERROR
01071 #if FL_DEBUG_CALLEDFROM
01072 debugErrorFrom(inFile, inFunc, inLine, "(memErrorBytesCheck) Memory integrity error, probably overflow, small chance of underflow.");
01073 #else
01074 debugError("Memory integrity error, probably overflow, small chance of underflow.");
01075 #endif
01076 #endif
01077 return false;
01078 }
01079 return true;
01080 }
01081
01082 #if FL_DEBUG_CALLEDFROM
01083 void memtAddFrom(MemoryTree** inMemTree, void* inPtr, u32 inSize, u32 inAlignment, const char* inFile, const char* inFunc, int inLine) {
01084 #else
01085 void memtAdd(MemoryTree** inMemTree, void* inPtr, u32 inSize, u32 inAlignment) {
01086 #endif
01087 if(!inPtr || !inSize || !inAlignment) {
01088 #if FL_DEBUG_ERROR
01089 #if FL_DEBUG_CALLEDFROM
01090 debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node with invalid properties to a memory tree.");
01091 #else
01092 debugError("Trying to add a node with invalid properties to a memory tree.");
01093 #endif
01094 #endif
01095 return;
01096 }
01097
01098 if(!memBlockValid(inPtr, (inSize + (inAlignment << 1)))) {
01099 #if FL_DEBUG_ERROR
01100 #if FL_DEBUG_CALLEDFROM
01101 debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node that points to an invalid memory block to a memory tree.");
01102 #else
01103 debugError("Trying to add a node that points to an invalid memory block to a memory tree.");
01104 #endif
01105 #endif
01106 return;
01107 }
01108
01109 if((inSize & (inAlignment - 1)) || ((u32)inPtr & (inAlignment - 1))) {
01110 #if FL_DEBUG_ERROR
01111 #if FL_DEBUG_CALLEDFROM
01112 debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node that breaks it's own alignment to a memory tree.");
01113 #else
01114 debugError("Trying to add a node that breaks it's own alignment to a memory tree.");
01115 #endif
01116 #endif
01117 return;
01118 }
01119
01120 if(!inMemTree) {
01121 #if FL_DEBUG_ERROR
01122 #if FL_DEBUG_CALLEDFROM
01123 debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node to a NULL memory tree.");
01124 #else
01125 debugError("Trying to add a node to a NULL memory tree.");
01126 #endif
01127 #endif
01128 return;
01129 }
01130
01131 MemoryTree* tempOut = malloc(sizeof(MemoryTree));
01132 if(!tempOut) {
01133 #if FL_DEBUG_ERROR
01134 #if FL_DEBUG_CALLEDFROM
01135 debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Couldn't allocate node for memory tree.\nProbably out of memory.");
01136 #else
01137 debugError("Couldn't allocate node for memory tree.\nProbably out of memory.");
01138 #endif
01139 #endif
01140 return;
01141 }
01142
01143 tempOut->memtData = inPtr;
01144 tempOut->memtSize = inSize;
01145 tempOut->memtAlignment = inAlignment;
01146 tempOut->memtNext = (*inMemTree ? *inMemTree : NULL);
01147 *inMemTree = tempOut;
01148 }
01149
01150 #if FL_DEBUG_CALLEDFROM
01151 void memtDelFrom(MemoryTree** inMemTree, void* inPtr, const char* inFile, const char* inFunc, int inLine) {
01152 #else
01153 void memtDel(MemoryTree** inMemTree, void* inPtr) {
01154 #endif
01155 if(!inMemTree || !*inMemTree) {
01156 #if FL_DEBUG_ERROR
01157 #if FL_DEBUG_CALLEDFROM
01158 debugErrorFrom(inFile, inFunc, inLine, "(memDel) Trying to delete a node from a NULL memory tree.");
01159 #else
01160 debugError("Trying to delete a node from a NULL memory tree.");
01161 #endif
01162 #endif
01163 return;
01164 }
01165
01166 MemoryTree* tempDelNode = NULL;
01167 if((*inMemTree)->memtData == inPtr) {
01168 tempDelNode = *inMemTree;
01169 *inMemTree = (MemoryTree*)tempDelNode->memtNext;
01170 free(tempDelNode);
01171 return;
01172 }
01173
01174 MemoryTree* tempLastNode = *inMemTree;
01175 while(flRunning) {
01176 if(!tempLastNode->memtNext) {
01177 #if FL_DEBUG_ERROR
01178 #if FL_DEBUG_CALLEDFROM
01179 debugErrorFrom(inFile, inFunc, inLine, "(memDel) Pointer not found within memory tree.");
01180 #else
01181 debugError("Pointer not found within memory tree.");
01182 #endif
01183 #endif
01184 return;
01185 }
01186 tempDelNode = (MemoryTree*)tempLastNode->memtNext;
01187 if(tempDelNode->memtData == inPtr)
01188 break;
01189 tempLastNode = tempDelNode;
01190 }
01191 tempLastNode->memtNext = (MemoryTree*)tempDelNode->memtNext;
01192 free(tempDelNode);
01193 }
01194
01195 #if FL_DEBUG_CALLEDFROM
01196 void memtErrorBytesCheckFrom(MemoryTree** inMemTree, const char* inFile, const char* inFunc, int inLine) {
01197 #else
01198 void memtErrorBytesCheck(MemoryTree** inMemTree) {
01199 #endif
01200 if(!inMemTree) {
01201 #if FL_DEBUG_WARNING
01202 #if FL_DEBUG_CALLEDFROM
01203 debugWarningFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Trying to error check a NULL memory tree.");
01204 #else
01205 debugWarning("Trying to error check a NULL memory tree.");
01206 #endif
01207 #endif
01208 return;
01209 }
01210 if(!*inMemTree) {
01211 #if FL_DEBUG_WARNING
01212 #if FL_DEBUG_CALLEDFROM
01213 debugWarningFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Trying to error check an empty memory tree.");
01214 #else
01215 debugWarning("Trying to error check an empty memory tree.");
01216 #endif
01217 #endif
01218 return;
01219 }
01220 MemoryTree* tempNode = *inMemTree;
01221 u32* tempPtr;
01222 u32 tempSize;
01223 u32 tempBoundry;
01224 while(tempNode) {
01225 if(!memBlockValid(tempNode->memtData, (tempNode->memtSize + (tempNode->memtAlignment << 1)))) {
01226 #if FL_DEBUG_ERROR
01227 #if FL_DEBUG_CALLEDFROM
01228 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nPoints to invalid memory block.");
01229 #else
01230 debugError("Memory tree data corrupt.\nPoints to invalid memory block.");
01231 #endif
01232 #endif
01233 return;
01234 }
01235
01236 int i, j = 0;
01237 for(i = 0; i < 32; i++) {
01238 if(tempNode->memtAlignment & (1 << i))
01239 j++;
01240 }
01241 if(j != 1) {
01242 #if FL_DEBUG_ERROR
01243 #if FL_DEBUG_CALLEDFROM
01244 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nBad alignment value.");
01245 #else
01246 debugError("Memory tree data corrupt.\nBad alignment value.");
01247 #endif
01248 #endif
01249 return;
01250 }
01251
01252 if((u32)tempNode->memtData & (tempNode->memtAlignment - 1)) {
01253 #if FL_DEBUG_ERROR
01254 #if FL_DEBUG_CALLEDFROM
01255 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nData is not aligned as described in memory tree.");
01256 #else
01257 debugError("Memory tree data corrupt.\nData is not aligned as described in memory tree.");
01258 #endif
01259 #endif
01260 return;
01261 }
01262 if((u32)tempNode->memtSize & (tempNode->memtAlignment - 1)) {
01263 #if FL_DEBUG_ERROR
01264 #if FL_DEBUG_CALLEDFROM
01265 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nSize is not aligned as described in memory tree.");
01266 #else
01267 debugError("Memory tree data corrupt.\nSize is not aligned as described in memory tree.");
01268 #endif
01269 #endif
01270 return;
01271 }
01272
01273 if(tempNode->memtNext && !memBlockValid(tempNode->memtNext, sizeof(MemoryTree))) {
01274 #if FL_DEBUG_ERROR
01275 #if FL_DEBUG_CALLEDFROM
01276 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nPoints to invalid next node.");
01277 #else
01278 debugError("Memory tree data corrupt.\nPoints to invalid next node.");
01279 #endif
01280 #endif
01281 return;
01282 }
01283
01284 tempPtr = (u32*)tempNode->memtData;
01285 tempSize = tempNode->memtSize;
01286 tempBoundry = tempNode->memtAlignment;
01287
01288 if((tempPtr[0] != tempBoundry) || (tempPtr[1] != tempSize) || (tempPtr[2] != 0xFEEBDAED) || (tempPtr[3] != 0x76543210)) {
01289 #if FL_DEBUG_ERROR
01290 #if FL_DEBUG_CALLEDFROM
01291 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory integrity error, underflow.");
01292 #else
01293 debugError("Memory integrity error, underflow.");
01294 #endif
01295 #endif
01296 return;
01297 }
01298 tempPtr = (u32*)(((unsigned int)tempNode->memtData + tempNode->memtAlignment) + tempSize);
01299 if((tempPtr[0] != 0xDEADBEEF) || (tempPtr[1] != 0x01234567) || (tempPtr[2] != tempBoundry) || (tempPtr[3] != tempSize)) {
01300 #if FL_DEBUG_ERROR
01301 #if FL_DEBUG_CALLEDFROM
01302 debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory integrity error, overflow.");
01303 #else
01304 debugError("Memory integrity error, overflow.");
01305 #endif
01306 #endif
01307 return;
01308 }
01309 tempNode = (MemoryTree*)tempNode->memtNext;
01310 }
01311 }
01312 #endif
01313
01314 #endif