- Main Page
- Classes
- Files

- File List
- File Members

# flMemoryVMem.c

Go to the documentation of this file.

    00001 #include "flGlobal.h"
    00002
    00003 #if FL_MEMORY_VMEM != 0
    00004 #include <string.h>
    00005 #include <stdio.h>
    00006 #include <pspkernel.h>
    00007
    00008 #if FL_INCLUDE_ALL_C == 0
    00009 #include "flMemory.h"
    00010
    00011 #if FL_DEBUG != 0
    00012 #include "flDebug.h"
    00013 #endif
    00014 #endif
    00015
    00016 u32   vmemStart = MEMORY_VMEM_BASE;
    00017 u32   vmemSize = MEMORY_VMEM_SIZE;
    00018 u32*  vmemBlockTable = NULL;
    00019 u32   vmemBlocks = 0;
    00020 u32   vmemFreeBlocks = 0;
    00021 bool  vmemInitialized = false;
    00022
    00023 #if FL_MEMORY_VMEM_CACHE
    00024 void* vmemCache = (void*)((MEMORY_VMEM_BASE + MEMORY_VMEM_SIZE) - FL_MEMORY_VMEM_CACHE);
    00025 #endif
    00026
    00027 VmemStrideBlock* vmemStrideBlocks = NULL;
    00028
    00029 void  vmemInit() {
    00030      // Allocation table entries
    00031      // 00000000 00000000 00000000 00000000
    00032      // AA       FFFFFFFF FFFFFFFF FFFFFFFF - For AA type 0
    00033      // AA       PPPPPPPP PPPPPPPP PPPPPPPP - For AA type 1
    00034      // AA       SSSSSSSS SSSSSSSS SSSSSSSS - For AA type 2
    00035      // AA       SSSSSSSS PPPPPPPP PPPPPPPP - For AA type 3
    00036      // A = Allocation type (0 - FreeBlockStart, 1 - FreeMidBlock, 2 - AllocatedStartBlock, 3 - AllocatedMidBlock).
    00037      // S = Allocation length in blocks.
    00038      // P = Block number of start block.
    00039      // F = Number of free blocks following.
    00040
    00041      if(vmemInitialized) {
    00042           #if FL_DEBUG_WARNING != 0
    00043           debugWarning("Trying to initialize vram, but it is already initialized.");
    00044           #endif
    00045           return;
    00046      }
    00047
    00048      #if FL_MEMORY_VMEM_CACHE
    00049      vmemCache = (void*)memUncachedPtr(vmemAbsolutePtr(vmemAllocBuffer(FL_MEMORY_VMEM_CACHE, 1, 8, 0)));
    00050      sceKernelDcacheWritebackInvalidateRange(vmemCache, FL_MEMORY_VMEM_CACHE);
    00051      #endif
    00052
    00053      while(vmemStart & (FL_MEMORY_VMEM_BLOCKSIZE - 1)) {
    00054           vmemStart++;
    00055           vmemSize--;
    00056      }
    00057
    00058      vmemBlocks = (vmemSize / FL_MEMORY_VMEM_BLOCKSIZE);
    00059      vmemBlockTable = memAlloc(vmemBlocks << 2);
    00060      vmemFreeBlocks = vmemBlocks;
    00061
    00062      vmemBlockTable[0] = (vmemBlocks & 0x00FFFFFF);
    00063
    00064      vmemInitialized = true;
    00065 }
    00066
    00067 void vmemTerm() {
    00068      if(!vmemInitialized) {
    00069          #if FL_DEBUG_WARNING != 0
    00070           debugWarning("Trying to de-initialize vram, but it is not initialized.");
    00071           #endif
    00072           return;
    00073      }
    00074      vmemInitialized = false;
    00075      memFree(vmemBlockTable);
    00076      vmemBlocks = 0;
    00077      vmemSize = MEMORY_VMEM_SIZE;
    00078      vmemStart = MEMORY_VMEM_BASE;
    00079      vmemStrideBlockDelRecursive(vmemStrideBlocks);
    00080 }
    00081
    00082 void* vmemNormalPtr(void* inPtr) {
    00083      inPtr = memCachedPtr(inPtr);
    00084
    00085      // The following assumes that any pointer passed in that is under MEMORY_VMEM_BASE
    00086      // is a relative pointer, however assumptions are bad.
    00087      //if((u32)inPtr < MEMORY_VMEM_SIZE)
    00088      //   inPtr = (void*)((u32)inPtr + MEMORY_VMEM_BASE);*/
    00089
    00090      if(((u32)inPtr < MEMORY_VMEM_BASE) || ((u32)inPtr >= (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2))))
    00091           return NULL;
    00092      while((u32)inPtr >= (MEMORY_VMEM_BASE + MEMORY_VMEM_SIZE))
    00093           inPtr = (void*)((u32)inPtr - MEMORY_VMEM_SIZE);
    00094      return inPtr;
    00095 }
    00096
    00097 void* vmemAllocBuffer(u32 inWidth, u32 inHeight, u8 inBitDepth, u32 inStride) {
    00098       void* tempOut;
    00099       if(vmemInitialized) {
    00100            #if FL_DEBUG_DEVWARNING != 0
    00101            debugDevWarning("Allocating buffers after vmem is initialized is bad practice.");
    00102            #endif
    00103            tempOut = vmemAlloc((inWidth * inHeight * inBitDepth) >> 3);
    00104       } else {
    00105            if(vmemSize < ((inWidth * inHeight * inBitDepth) >> 3)) {
    00106                 #if DEBUG_ERROR != 0
    00107                 debugError("Error allocating vram buffer.\nProgram will probably now be unstable.");
    00108                 #endif
    00109                 return (void*)(MEMORY_VMEM_SIZE << 2);
    00110            }
    00111            vmemSize -= ((inWidth * inHeight * inBitDepth) >> 3);
    00112            tempOut = (void*)vmemStart;
    00113            vmemStart += ((inWidth * inHeight * inBitDepth) >> 3);
    00114       }
    00115       if(inStride) {
    00116            u32 tempStride = (((inWidth - inStride) * inBitDepth) >> 3);
    00117            void* tempStart = (void*)((u32)tempOut + tempStride);
    00118            u32 tempBlockSize = ((inStride * inBitDepth) >> 3);
    00119            u32 tempBlockCount = inHeight;
    00120            vmemStrideBlockAdd(tempStart, tempStride, tempBlockSize, tempBlockCount);
    00121       }
    00122       return vmemRelativePtr(tempOut);
    00123 }
    00124
    00125 #if FL_DEBUG_CALLEDFROM != 0
    00126 void* vmemAllocFrom(u32 inSize, const char* inFile, const char* inFunc, int inLine) {
    00127 #else
    00128 void* vmemAlloc(u32 inSize) {
    00129 #endif
    00130      void* tempOut = vmemStrideAlloc(inSize);
    00131      if(tempOut)
    00132           return tempOut;
    00133
    00134      if(!vmemInitialized) {
    00135           #if FL_DEBUG_WARNING != 0
    00136           #if FL_DEBUG_CALLEDFROM != 0
    00137           debugWarningFrom(inFile, inFunc, inLine, "Trying to allocate vram before vram is initialized.");
    00138           #else
    00139           debugWarning("Trying to allocate vram before vram is initialized.");
    00140           #endif
    00141           #endif
    00142           return NULL;
    00143      }
    00144
    00145      if(inSize > (vmemFreeBlocks * FL_MEMORY_VMEM_BLOCKSIZE)) {
    00146           #if FL_DEBUG_WARNING != 0
    00147           #if FL_DEBUG_CALLEDFROM != 0
    00148           debugWarningFrom(inFile, inFunc, inLine, "Error allocating video memory, not enough vmem free to attempt allocation.");
    00149           #else
    00150           debugWarning("Error allocating video memory, not enough vmem free to attempt allocation.");
    00151           #endif
    00152           #endif
    00153           return NULL;
    00154      }
    00155
    00156      while(inSize & (FL_MEMORY_VMEM_BLOCKSIZE - 1))
    00157           inSize++;
    00158      unsigned int tempBlocksNeeded = (inSize / FL_MEMORY_VMEM_BLOCKSIZE);
    00159      int tempBestBlock = -1;
    00160      unsigned int tempBestBlockSize = 0;
    00161      unsigned int i = 0;
    00162
    00163      // Find best memory chunk to allocate.
    00164      while(i < vmemBlocks) {
    00165           if(((vmemBlockTable[i] & 0xC0000000) == 0) && ((vmemBlockTable[i] & 0x00FFFFFF) >= tempBlocksNeeded)) {
    00166                if(((vmemBlockTable[i] & 0x00FFFFFF) < tempBestBlockSize) || (tempBestBlock < 0)){
    00167                     tempBestBlock = i;
    00168                     tempBestBlockSize = (vmemBlockTable[i] & 0x00FFFFFF);
    00169                     if(tempBestBlockSize == tempBlocksNeeded)
    00170                          break;
    00171                }
    00172           }
    00173           if(vmemBlockTable[i] & 0x40000000) {
    00174                #if FL_DEBUG_WARNING != 0
    00175                #if FL_DEBUG_CALLEDFROM != 0
    00176                debugWarningFrom(inFile, inFunc, inLine, "Error while walking vmem, block table corrupt.");
    00177                #else
    00178                debugWarning("Error while walking vmem, block table corrupt.");
    00179                #endif
    00180                #endif
    00181                return NULL;
    00182           } else
    00183                i += (vmemBlockTable[i] & 0x00FFFFFF);
    00184      }
    00185
    00186      // If no suitable memory chunk was found.
    00187      if(tempBestBlock < 0) {
    00188           #if FL_DEBUG_WARNING != 0
    00189           #if FL_DEBUG_CALLEDFROM != 0
    00190           debugWarningFrom(inFile, inFunc, inLine, "Error allocating video memory, memory is fragmented.");
    00191           #else
    00192           debugWarning("Error allocating video memory, memory is fragmented.");
    00193           #endif
    00194           #endif
    00195           return NULL;
    00196      }
    00197
    00198      // Split block between allocation and remaining free memory.
    00199      vmemBlockTable[tempBestBlock] = ((tempBlocksNeeded & 0x00FFFFFF) | 0x80000000);
    00200      if(tempBlocksNeeded > 1)
    00201           vmemBlockTable[tempBestBlock + tempBlocksNeeded - 1] = ((tempBestBlock & 0x00FFFFFF) | 0xC0000000);
    00202      if(tempBestBlockSize != tempBlocksNeeded) {
    00203           vmemBlockTable[tempBestBlock + tempBlocksNeeded] = ((tempBestBlockSize - tempBlocksNeeded) & 0x00FFFFFF);
    00204           if((tempBestBlockSize - tempBlocksNeeded) > 1)
    00205                vmemBlockTable[tempBestBlock + tempBestBlockSize - 1] = (((tempBestBlock + tempBlocksNeeded) & 0x00FFFFFF) | 0x40000000);
    00206      }
    00207
    00208      // Calculate pointer value
    00209      tempOut = (void*)(vmemStart + (tempBestBlock * FL_MEMORY_VMEM_BLOCKSIZE));
    00210      vmemFreeBlocks -= tempBlocksNeeded;
    00211
    00212      return tempOut;
    00213 }
    00214
    00215 #if FL_DEBUG_CALLEDFROM != 0
    00216 void* vmemCallocFrom(u32 inSize0, u32 inSize1, const char* inFile, const char* inFunc, int inLine) {
    00217 #else
    00218 void* vmemCalloc(u32 inSize0, u32 inSize1) {
    00219 #endif
    00220      void* tempOut = vmemStrideCalloc(inSize0, inSize1);
    00221      if(tempOut)
    00222           return tempOut;
    00223
    00224      #if FL_DEBUG_CALLEDFROM != 0
    00225      tempOut = vmemAllocFrom(inSize0 * inSize1, inFile, inFunc, inLine);
    00226      #else
    00227      tempOut = vmemAlloc(inSize0 * inSize1);
    00228      #endif
    00229
    00230      if(!tempOut)
    00231           return NULL;
    00232      memClear(tempOut, (inSize0 * inSize1));
    00233      return tempOut;
    00234 }
    00235
    00236 #if FL_DEBUG_CALLEDFROM != 0
    00237 void* vmemReallocFrom(void* inData, u32 inSize, const char* inFile, const char* inFunc, int inLine) {
    00238 #else
    00239 void* vmemRealloc(void* inData, u32 inSize) {
    00240 #endif
    00241      #if FL_DEBUG_DEVWARNING != 0
    00242      #if FL_DEBUG_CALLEDFROM != 0
    00243      debugDevWarningFrom(inFile, inFunc, inLine, "VRam reallocation not yet quickly implemented, reverting to vmemAlloc->memCopy->vmemFree combo.");
    00244      #else
    00245      debugDevWarning("VRam reallocation not yet quickly implemented, reverting to vmemAlloc->memCopy->vmemFree combo.");
    00246      #endif
    00247      #endif
    00248      void* tempOut = vmemAlloc(inSize);
    00249      if(!tempOut) {
    00250           #if FL_DEBUG_WARNING != 0
    00251           #if FL_DEBUG_CALLEDFROM != 0
    00252           debugWarningFrom(inFile, inFunc, inLine, "VRam reallocation failed, memory is full/fragmented.");
    00253           #else
    00254           debugWarning("VRam reallocation failed, memory is full/fragmented.");
    00255           #endif
    00256           #endif
    00257           return NULL;
    00258      }
    00259
    00260      unsigned int tempStartBlock = ((((u32)memCachedPtr(vmemRelativePtr(inData))) - vmemStart) / FL_MEMORY_VMEM_BLOCKSIZE);
    00261      if((((u32)memCachedPtr(vmemRelativePtr(inData))) < vmemStart) || (tempStartBlock >= vmemBlocks)) {
    00262           #if FL_DEBUG_ERROR != 0
    00263           #if FL_DEBUG_CALLEDFROM != 0
    00264           debugErrorFrom(inFile, inFunc, inLine, "Trying to realloc invalid vram pointer, out of range.");
    00265           #else
    00266           debugError("Trying to realloc invalid vram pointer, out of range.");
    00267           #endif
    00268           #endif
    00269           return NULL;
    00270      }
    00271      if((vmemBlockTable[tempStartBlock] & 0xC0000000) != 0x80000000) {
    00272           #if FL_DEBUG_ERROR != 0
    00273           #if FL_DEBUG_CALLEDFROM != 0
    00274           debugErrorFrom(inFile, inFunc, inLine, "Trying to realloc invalid vram pointer, middle of block.");
    00275           #else
    00276           debugError("Trying to realloc invalid vram pointer, middle of block.");
    00277           #endif
    00278           #endif
    00279           return NULL;
    00280      }
    00281      int tempLength = (vmemBlockTable[tempStartBlock] & 0x00FFFFFF);
    00282
    00283      memCopy(tempOut, inData, (tempLength * FL_MEMORY_VMEM_BLOCKSIZE));
    00284
    00285      vmemFree(inData);
    00286      return tempOut;
    00287 }
    00288
    00289 #if FL_DEBUG_CALLEDFROM != 0
    00290 void vmemFreeFrom(void* inData, const char* inFile, const char* inFunc, int inLine) {
    00291 #else
    00292 void vmemFree(void* inData) {
    00293 #endif
    00294      if(!vmemInitialized)
    00295           return;
    00296
    00297      if(vmemStrideFree(inData))
    00298           return;
    00299
    00300      inData = vmemNormalPtr(inData);
    00301
    00302      if(!inData || (((u32)inData - vmemStart) % FL_MEMORY_VMEM_BLOCKSIZE) || (((u32)inData - vmemStart) >= vmemSize) || ((u32)inData < vmemStart)) {
    00303           #if FL_DEBUG_ERROR != 0
    00304           #if FL_DEBUG_CALLEDFROM != 0
    00305           debugErrorFrom(inFile, inFunc, inLine, "Trying to free invalid vram pointer, out of range.");
    00306           #else
    00307           debugError("Trying to free invalid vram pointer, out of range.");
    00308           #endif
    00309           #endif
    00310           return;
    00311      }
    00312
    00313      u32 tempStartBlock = (((u32)inData - vmemStart) / FL_MEMORY_VMEM_BLOCKSIZE);
    00314      u32 tempLength = (vmemBlockTable[tempStartBlock] & 0x00FFFFFF);
    00315      if((vmemBlockTable[tempStartBlock] & 0xC0000000) != 0x80000000) {
    00316           #if FL_DEBUG_ERROR != 0
    00317           #if FL_DEBUG_CALLEDFROM != 0
    00318           debugErrorFrom(inFile, inFunc, inLine, "Trying to free invalid vram pointer, middle of block or not allocated.");
    00319           #else
    00320           debugError("Trying to free invalid vram pointer, middle of block or not allocated.");
    00321           #endif
    00322           #endif
    00323           return;
    00324      }
    00325
    00326      vmemFreeBlocks += tempLength;
    00327
    00328      // If there is a free block after it then join onto that.
    00329      if((tempStartBlock + tempLength) < vmemBlocks) {
    00330           if((vmemBlockTable[tempStartBlock + tempLength] & 0xC0000000) == 0x00000000) {
    00331                tempLength += (vmemBlockTable[tempStartBlock + tempLength] & 0x00FFFFFF);
    00332           }
    00333      }
    00334
    00335      // If there is a free block before it then join onto that.
    00336      if(tempStartBlock > 0) {
    00337           if((vmemBlockTable[tempStartBlock - 1] & 0xC0000000) == 0x00000000) {
    00338                tempStartBlock--;
    00339                tempLength++;
    00340           } else if((vmemBlockTable[tempStartBlock - 1] & 0xC0000000) == 0x40000000) {
    00341                tempStartBlock = (vmemBlockTable[tempStartBlock - 1] & 0x00FFFFFF);
    00342                tempLength += (vmemBlockTable[tempStartBlock] & 0x00FFFFFF);
    00343           }
    00344      }
    00345
    00346      // Create full length free block.
    00347      vmemBlockTable[tempStartBlock] = tempLength;
    00348      vmemBlockTable[tempStartBlock + tempLength - 1] = (tempStartBlock | 0x40000000);
    00349
    00350      return;
    00351 }
    00352
    00353 u32 vmemFreeSpace() {
    00354      return ((vmemFreeBlocks * FL_MEMORY_VMEM_BLOCKSIZE) + vmemStrideFreeSpace());
    00355 }
    00356
    00357 u32 vmemLargestFreeBlock() {
    00358      unsigned int i = 0;
    00359      unsigned int tempOut = 0;
    00360      while(i < vmemBlocks) {
    00361           if((vmemBlockTable[i] & 0xC0000000) == 0) {
    00362                if((vmemBlockTable[i] & 0x00FFFFFF) > tempOut)
    00363                     tempOut = (vmemBlockTable[i] & 0x00FFFFFF);
    00364           }
    00365           if(vmemBlockTable[i] & 0x40000000) {
    00366                #if FL_DEBUG_WARNING != 0
    00367                debugWarning("Error while walking vmem, block table corruption.");
    00368                #endif
    00369                return 0;
    00370           } else
    00371                i += (vmemBlockTable[i] & 0x00FFFFFF);
    00372      }
    00373      return (tempOut * FL_MEMORY_VMEM_BLOCKSIZE);
    00374 }
    00375
    00376 float vmemFragmentation() {
    00377      if(!vmemInitialized)
    00378           return -1.0f;
    00379      unsigned int i = 0;
    00380      unsigned int tempFragments = 0;
    00381      while(i < vmemBlocks) {
    00382           if((vmemBlockTable[i] & 0xC0000000) == 0)
    00383                tempFragments++;
    00384           if(vmemBlockTable[i] & 0x40000000) {
    00385                #if FL_DEBUG_WARNING != 0
    00386                debugWarning("Error while walking vmem, block table corruption.");
    00387                #endif
    00388                return -1.0f;
    00389           } else
    00390                i += (vmemBlockTable[i] & 0x00FFFFFF);
    00391      }
    00392      float tempOut = ((float)vmemFreeSpace() / (float)tempFragments);
    00393      return (tempOut * FL_MEMORY_VMEM_BLOCKSIZE);
    00394 }
    00395
    00396 void vmemStrideBlockAdd(void* inStart, u32 inStride, u32 inBlockSize, u32 inBlockCount) {
    00397      if(!inStride || !inBlockSize || !inBlockCount) {
    00398           #if FL_DEBUG_WARNING != 0
    00399           debugWarning("Trying to create stride block with bad parameters.");
    00400           #endif
    00401           return;
    00402      }
    00403      inStart = vmemNormalPtr(inStart);
    00404      if(!memBlockValid(inStart, (((inBlockSize + inStride) * inBlockCount) - inStride))) {
    00405           #if FL_DEBUG_WARNING != 0
    00406           debugWarning("Cannot create stride block from an invalid pointer or memory block.");
    00407           #endif
    00408           return;
    00409      }
    00410
    00411      VmemStrideBlock* tempOut = (VmemStrideBlock*)memAlloc(sizeof(VmemStrideBlock) + inBlockCount);
    00412      if(!tempOut) {
    00413           #if FL_DEBUG_WARNING != 0
    00414           debugWarning("Failed to allocate node to add vmem stride block.");
    00415           #endif
    00416           return;
    00417      }
    00418
    00419      tempOut->vmsbStart = inStart;
    00420      tempOut->vmsbStride = inStride;
    00421      tempOut->vmsbBlockSize = inBlockSize;
    00422      tempOut->vmsbBlockCount = inBlockCount;
    00423      tempOut->vmsbBlockAlign = min(memAddressAlignment(inStart), memAddressAlignment((void*)(inStride + inBlockSize)));
    00424
    00425      tempOut->vmsbBlockTable = (u8*)((u32)tempOut + sizeof(VmemStrideBlock));
    00426      memClear(tempOut->vmsbBlockTable, tempOut->vmsbBlockCount);
    00427      tempOut->vmsbLast = NULL;
    00428      tempOut->vmsbNext = vmemStrideBlocks;
    00429      if(tempOut->vmsbNext)
    00430           ((VmemStrideBlock*)(tempOut->vmsbNext))->vmsbLast = tempOut;
    00431      vmemStrideBlocks = tempOut;
    00432 }
    00433
    00434 void vmemStrideBlockDel(VmemStrideBlock* inBlock) {
    00435      if(!inBlock)
    00436           return;
    00437      if(!inBlock->vmsbLast)
    00438           vmemStrideBlocks = (VmemStrideBlock*)inBlock->vmsbNext;
    00439      else
    00440           inBlock->vmsbLast = inBlock->vmsbNext;
    00441      memFree(inBlock);
    00442 }
    00443
    00444 void vmemStrideBlockDelRecursive(VmemStrideBlock* inBlock) {
    00445      if(!inBlock)
    00446           return;
    00447      if(inBlock->vmsbLast) {
    00448           vmemStrideBlockDelRecursive((VmemStrideBlock*)inBlock->vmsbLast);
    00449           return;
    00450      }
    00451      if(inBlock->vmsbNext)
    00452           vmemStrideBlockDelRecursive((VmemStrideBlock*)inBlock->vmsbNext);
    00453      memFree(inBlock);
    00454 }
    00455
    00456 void* vmemStrideAlign(u32 inAlign, u32 inSize) {
    00457      if(!vmemStrideBlocks || !inSize)
    00458           return NULL;
    00459      if(!inAlign)
    00460           inAlign = FL_MEMORY_ALIGNMENT_DEFAULT;
    00461
    00462      VmemStrideBlock* tempBlock = vmemStrideBlocks;
    00463
    00464      VmemStrideBlock* tempBestBlock = NULL;
    00465      u32              tempBestIndex = 0;
    00466
    00467      u32 i;
    00468      while(flRunning) {
    00469           if((tempBlock->vmsbBlockAlign >= inAlign) && (tempBlock->vmsbBlockSize >= inSize)) {
    00470                if(!tempBestBlock || (tempBlock->vmsbBlockSize < tempBestBlock->vmsbBlockSize)) {
    00471                     for(i = 0; i < tempBlock->vmsbBlockCount; i++) {
    00472                          if(!tempBlock->vmsbBlockTable[i]) {
    00473                               tempBestBlock = tempBlock;
    00474                               tempBestIndex = i;
    00475                               break;
    00476                          }
    00477                     }
    00478                }
    00479           }
    00480           if(!tempBlock->vmsbNext)
    00481                break;
    00482           tempBlock = ((VmemStrideBlock*)(tempBlock->vmsbNext));
    00483      }
    00484
    00485      if(!tempBestBlock)
    00486           return NULL;
    00487
    00488      tempBestBlock->vmsbBlockTable[tempBestIndex] = 1;
    00489      return (void*)((u32)tempBestBlock->vmsbStart + (tempBestIndex * (tempBestBlock->vmsbBlockSize + tempBestBlock->vmsbStride)));
    00490 }
    00491
    00492 void* vmemStrideAlloc(u32 inSize) {
    00493      return vmemStrideAlign(FL_MEMORY_ALIGNMENT_DEFAULT, inSize);
    00494 }
    00495
    00496 void* vmemStrideCalloc(u32 inSize0, u32 inSize1) {
    00497      void* tempOut = vmemStrideAlloc(inSize0 * inSize1);
    00498      memClear(tempOut, (inSize0 * inSize1));
    00499      return tempOut;
    00500 }
    00501
    00502 bool vmemStrideFree(void* inData) {
    00503      if(!vmemStrideBlocks)
    00504           return false;
    00505
    00506      inData = vmemNormalPtr(inData);
    00507      if(!inData)
    00508           return false;
    00509
    00510      VmemStrideBlock* tempBlock = vmemStrideBlocks;
    00511      u32 i;
    00512      while(flRunning) {
    00513           if(((u32)inData >= (u32)tempBlock->vmsbStart) && ((u32)inData < ((u32)tempBlock->vmsbStart + (((tempBlock->vmsbBlockSize + tempBlock->vmsbStride) * tempBlock->vmsbBlockCount) - tempBlock->vmsbStride)))) {
    00514                for(i = 0; i < tempBlock->vmsbBlockCount; i++) {
    00515                     if(((u32)tempBlock->vmsbStart + (i * (tempBlock->vmsbStride + tempBlock->vmsbBlockSize))) == (u32)inData) {
    00516                          if(!tempBlock->vmsbBlockTable[i])
    00517                               return false;
    00518                          tempBlock->vmsbBlockTable[i] = 0;
    00519                          return true;
    00520                     }
    00521                }
    00522                #if FL_DEBUG_WARNING != 0
    00523                debugWarning("Trying to free an invalid stride block");
    00524                #endif
    00525                return true;
    00526           }
    00527           if(!tempBlock->vmsbNext)
    00528                break;
    00529           tempBlock = ((VmemStrideBlock*)(tempBlock->vmsbNext));
    00530      }
    00531      return false;
    00532 }
    00533
    00534 float vmemStrideUsage() {
    00535      if(!vmemStrideBlocks)
    00536           return 0.0f;
    00537
    00538      VmemStrideBlock* tempBlock = vmemStrideBlocks;
    00539
    00540      u32 tempSize = 0;
    00541      u32 tempUsed = 0;
    00542      u32 i;
    00543
    00544      while(flRunning) {
    00545           tempSize += (tempBlock->vmsbBlockSize * tempBlock->vmsbBlockCount);
    00546
    00547           for(i = 0; i < tempBlock->vmsbBlockCount; i++) {
    00548                if(tempBlock->vmsbBlockTable[i])
    00549                     tempUsed += tempBlock->vmsbBlockSize;
    00550           }
    00551
    00552           if(!tempBlock->vmsbNext)
    00553                break;
    00554
    00555           tempBlock = ((VmemStrideBlock*)(tempBlock->vmsbNext));
    00556      }
    00557
    00558      if(!tempSize)
    00559           return 0.0f;
    00560      return ((float)tempUsed / (float)tempSize);
    00561 }
    00562
    00563 u32 vmemStrideFreeSpace() {
    00564      if(!vmemStrideBlocks)
    00565           return 0;
    00566
    00567      VmemStrideBlock* tempBlock = vmemStrideBlocks;
    00568
    00569      u32 tempSize = 0;
    00570      u32 tempUsed = 0;
    00571      u32 i;
    00572
    00573      while(flRunning) {
    00574           tempSize += (tempBlock->vmsbBlockSize * tempBlock->vmsbBlockCount);
    00575
    00576           for(i = 0; i < tempBlock->vmsbBlockCount; i++) {
    00577                if(tempBlock->vmsbBlockTable[i])
    00578                     tempUsed += tempBlock->vmsbBlockSize;
    00579           }
    00580
    00581           if(!tempBlock->vmsbNext)
    00582                break;
    00583
    00584           tempBlock = ((VmemStrideBlock*)(tempBlock->vmsbNext));
    00585      }
    00586
    00587      return (tempSize - tempUsed);
    00588 }
    00589
    00590 #endif