/// <summary> /// Mark memory as allocated and returns its starting address. Changes nothing /// on the real simulator. /// Might throw NoFreeMemoryException exception. /// </summary> /// <param name="iSize">The size of requested block</param> public int MemAllocation(int iSize) { // Find block with size close to the requested size int iBlockLocation = FreeMemList.BinarySearch((FreeMemoryInformation)iSize); if (iBlockLocation < 0) { int iIndex = ~iBlockLocation; // If no block in the request size is free, throw exception if (iIndex == FreeMemList.Count) { throw new NoFreeMemoryException(); } // Remove the old block from the list FreeMemoryInformation oldBlock = (FreeMemoryInformation)FreeMemList[iIndex]; FreeMemList.RemoveAt(iIndex); // add new free block with the size that left FreeMemList.Add(new FreeMemoryInformation(oldBlock.uiAddress + (uint)iSize, oldBlock.iSize - iSize)); FreeMemList.Sort(); // return block return((int)oldBlock.uiAddress); } else { FreeMemoryInformation oldBlock = (FreeMemoryInformation)FreeMemList[iBlockLocation]; FreeMemList.RemoveAt(iBlockLocation); return((int)oldBlock.uiAddress); } }
/// <summary> /// Free allocated memory /// </summary> /// <param name="iAddress">Address of the block to destroy</param> public void FreeMemory(uint uiAddress, int iSize) { // If the memory is out of the heap area if (uiAddress < uiHeapBase || uiAddress + iSize > uiHeapBase + iHeapSize) { throw new RuntimeError(SimulatorMessage.MEMORY_ACCESS_FAULT, (int)uiAddress); } for (int iCounter = 0; iCounter < FreeMemList.Count; ++iCounter) { FreeMemoryInformation curBlock = (FreeMemoryInformation)FreeMemList[iCounter]; // if the address is inside a free space if (uiAddress >= curBlock.uiAddress && uiAddress < curBlock.uiAddress + curBlock.iSize) { throw new RuntimeError(SimulatorMessage.MEMORY_ACCESS_FAULT, (int)uiAddress); } // if the end address is inside a free space else if (uiAddress + iSize > curBlock.uiAddress && uiAddress + iSize < curBlock.uiAddress + curBlock.iSize) { throw new RuntimeError(SimulatorMessage.MEMORY_ACCESS_FAULT, (int)uiAddress); } // if the block to free includes a free area else if (uiAddress < curBlock.uiAddress && uiAddress + iSize > curBlock.uiAddress + curBlock.iSize) { throw new RuntimeError(SimulatorMessage.MEMORY_ACCESS_FAULT, (int)uiAddress); } } FreeMemList.Add(new FreeMemoryInformation(uiAddress, iSize)); FreeMemList.Sort(); }