flMemory.c

Go to the documentation of this file.
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; // Current page ID.
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      // Handle overlaps
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

Generated on Wed Sep 5 19:04:00 2007 for funcLib by  doxygen 1.5.1