예제 #1
0
        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!");
                }
            }
        }