private static void DoInitialize(uint aEndOfRam) { mLastTable = null; mLastEntryIndex = 0u; mEndOfRam = aEndOfRam; // }
public static uint MemAlloc(uint aLength) { if (aLength == 0) { mDebugger.Send(" Request to retrieve block with size = 0 was halted!"); while (true) { } } var xInterruptsWereEnabled = Processor.DisableInterrupts(); try { EnsureIsInitialized(); var xCurrentTableIdx = mLastTableIndex; DataLookupTable *xCurrentTable = GlobalSystemInfo.GlobalInformationTable->FirstDataLookupTable; DataLookupTable *xPreviousTable = null; uint xResult; #region Loop through existing tables and see if we find a free spot while (xCurrentTable != null) { //mDebugger.Trace($"At address {(uint)xCurrentTable}"); if (ScanDataLookupTable(xCurrentTableIdx, xCurrentTable, aLength, out xResult)) { if (xResult < Processor.GetEndOfKernel()) { mDebugger.Send("Wrong handle returned!"); while (true) { } } return(xResult); } xCurrentTableIdx++; xPreviousTable = xCurrentTable; xCurrentTable = xCurrentTable->Next; mLastTableIndex = xCurrentTableIdx; mLastEntryIndex = 0; } #endregion Loop through existing tables and see if we find a free spot // no tables found, lets create a new one, and use that if (xPreviousTable == null) { // this check should theoretically be unnecessary, but lets keep it, to do some double-checking. mDebugger.Send("No PreviousTable found!"); while (true) { } } var xLastItem = xPreviousTable->GetEntry(DataLookupTable.EntriesPerTable - 1); var xNextTablePointer = (DataLookupTable *)((uint)xLastItem->DataBlock + xLastItem->Size); // the memory hasn't been cleared yet, so lets do that now. ClearMemory(xNextTablePointer, GlobalSystemInfo.TotalDataLookupTableSize); xPreviousTable->Next = xNextTablePointer; xNextTablePointer->Previous = xPreviousTable; if (!ScanDataLookupTable(xCurrentTableIdx, xNextTablePointer, aLength, out xResult)) { // Something seriously weird happened: we could create a new DataLookupTable (with new entries) // but couldn't allocate a new handle from it. mDebugger.Send(" Something seriously weird happened: we could create a new DataLookupTable (with new entries), but couldn't allocate a new handle from it."); while (true) { } } mLastTableIndex = xCurrentTableIdx; mLastEntryIndex = 0; return(xResult); } finally { if (xInterruptsWereEnabled) { Processor.EnableInterrupts(); } else { //mDebugger.Trace(" Not enabling interrupts, because they weren't enabled yet!"); } } }
private static bool ScanDataLookupTable(uint aTableIdx, DataLookupTable *aTable, uint aSize, out uint aHandle) { DataLookupEntry *xPreviousEntry = null; for (uint i = mLastEntryIndex; i < DataLookupTable.EntriesPerTable; i++) { var xCurrentEntry = aTable->GetEntry(i); //mDebugger.Trace($"Item.Size", xCurrentEntry->Size); //mDebugger.Trace($"Item.Refcount", xCurrentEntry->Refcount); if (xCurrentEntry->Size == 0) { #region Found an uninitialized entry // found an entry now. Let's set it if (aTable->Next != null) { // once a handle is used, the size should be set. But at this point, it somehow got unset again. // This should never occur. mDebugger.Send("Found an entry which has no size, but there is a followup DataLookupTable"); while (true) { } } void *xDataBlock; //mDebugger.Trace("Now calculate datablock pointer"); // now we found ourself a free handle if (i == 0) { //mDebugger.Trace("Using table end"); // we don't have a previous handle yet, so we take the FirstByteAfterTable field of the DataLookupTable // note: we're explicitly initializing all blocks, as memory hasn't been cleared yet. var xTableAddr = (uint)aTable; //mDebugger.Trace($"aTableAddr", xTableAddr); var xTotalTableSize = GlobalSystemInfo.TotalDataLookupTableSize; //mDebugger.Trace($"TotalTableSize", xTotalTableSize); xDataBlock = (void *)(((uint)aTable) + GlobalSystemInfo.TotalDataLookupTableSize); } else { //mDebugger.Trace("Using previous entry"); // We're not the very first handle being assigned, so calculate the start address using the previous block xDataBlock = (void *)((uint)xPreviousEntry->DataBlock + xPreviousEntry->Size); } // make sure the memory is empty ClearMemory(xDataBlock, aSize); //mDebugger.Trace("Cleared memory"); xCurrentEntry->Size = aSize; xCurrentEntry->DataBlock = xDataBlock; xCurrentEntry->Refcount = 1; aHandle = (uint)xCurrentEntry->DataBlock; //mDebugger.Trace($"Returning handle ", aHandle); mLastEntryIndex = i; #endregion Found an uninitialized entry return(true); } // Refcount == UInt32.MaxValue, it means that the block has been reclaimed, and can be reused now. if (xCurrentEntry->Refcount == UInt32.MaxValue) { // we can reuse this entry if its Size >= aLength if (xCurrentEntry->Size >= aSize) { // we can reuse this entry xCurrentEntry->Refcount = 1; aHandle = (uint)xCurrentEntry->DataBlock; mLastEntryIndex = i; return(true); } } xPreviousEntry = xCurrentEntry; } aHandle = 0; return(false); }
public static uint MemAlloc(uint aLength) { if (aLength == 0) { DebugAndHalt(" Request to retrieve block with size = 0 was halted!"); } var xInterruptsWereEnabled = CPU.DisableInterrupts(); try { EnsureIsInitialized(); var xCurrentTableIdx = mLastTableIndex; DataLookupTable *xCurrentTable = GlobalSystemInfo.GlobalInformationTable->FirstDataLookupTable; DataLookupTable *xPreviousTable = null; uint xResult; while (xCurrentTable != null) { DebugHex("Scanning DataLookupTable ", xCurrentTableIdx); //DebugHex("At address", (uint)xCurrentTable); if (ScanDataLookupTable(xCurrentTableIdx, xCurrentTable, aLength, out xResult)) { DebugHex("Returning handle", xResult); DebugHex("For dataobject size", aLength); if (xResult < CPU.GetEndOfKernel()) { DebugAndHalt("Wrong handle returned!"); } return(xResult); } xCurrentTableIdx++; xPreviousTable = xCurrentTable; xCurrentTable = xCurrentTable->Next; mLastTableIndex = xCurrentTableIdx; mLastEntryIndex = 0; } // no tables found, lets create a new one, and use that if (xPreviousTable == null) { // this check should theoretically be unnecessary, but lets keep it, to do some double-checking. DebugAndHalt("No PreviousTable found!"); } Debug("Creating new DataLookupTable"); var xLastItem = xPreviousTable->GetEntry(DataLookupTable.EntriesPerTable - 1); var xNextTablePointer = (DataLookupTable *)((uint)xLastItem->DataBlock + xLastItem->Size); // the memory hasn't been cleared yet, so lets do that now. ClearMemory(xNextTablePointer, GlobalSystemInfo.TotalDataLookupTableSize); xPreviousTable->Next = xNextTablePointer; xNextTablePointer->Previous = xPreviousTable; if (!ScanDataLookupTable(xCurrentTableIdx, xNextTablePointer, aLength, out xResult)) { // Something seriously weird happened: we could create a new DataLookupTable (with new entries) // but couldn't allocate a new handle from it. DebugAndHalt(" Something seriously weird happened: we could create a new DataLookupTable (with new entries), but couldn't allocate a new handle from it."); } DebugHex("Returning handle", xResult); DebugHex("For dataobject size", aLength); mLastTableIndex = xCurrentTableIdx; mLastEntryIndex = 0; return(xResult); } finally { if (xInterruptsWereEnabled) { CPU.EnableInterrupts(); } else { //Debug(" Not enabling interrupts, because they weren't enabled yet!"); } } }