Index: Kernel/Core/PageAllocator.cs =================================================================== --- Kernel/Core/PageAllocator.cs (revision 457) +++ Kernel/Core/PageAllocator.cs (working copy) @@ -9,6 +9,7 @@
using SharpOS.AOT; using SharpOS.ADC; +using System.Runtime.InteropServices; namespace SharpOS.Memory { @@ -25,12 +26,14 @@ static byte *kernelStartPage; // physical pointer to the first page occupied by the kernel static uint kernelSize; // kernel image size (pages) static uint totalPages; // amount of pages with RAM - - static uint *fpStack; // stack containing free page addresses + + static uint currentPage; + static uint *fpStack; // stack containing free page addresses static uint fpStackSize; // size of the free page stack (KB) static uint fpStackPointer; - - static uint *rpStack; // stack containing reserved page addresses + + static bool reservedPagesLeft; + static ReservedPages *rpStack; // stack containing reserved page addresses static uint rpStackSize; // size of the reserved page stack (KB) static uint rpStackPointer; @@ -39,7 +42,13 @@ #endregion #region Nested types - + [StructLayout(LayoutKind.Sequential)] + private struct ReservedPages + { + public uint Address; + public uint Size; + } + public enum Errors: uint { Success = 0, Unknown, @@ -95,9 +104,10 @@ start += fpStackSize * Pager.AtomicPageSize; // Allocate the reserved page stack - rpStack = (uint*)start; + rpStack = (ReservedPages*)start; rpStackPointer = 0; rpStackSize = 1; + reservedPagesLeft = false; // Allocate paging information pagingMemory->Start = (byte*)PtrToPage(start + (rpStackSize * 1024) + (Pager.AtomicPageSize - 1)); @@ -130,13 +140,7 @@ Kernel.Warning("Paging not set in commandline!"); // NOTE: 0x0000 page is reserved - for (int i = (int)(totalPages - 1); i >= 1; --i) - { - // we should be doing this but it's so slow! - // it needs to be rewritten to be fast enough to do.. - //if (!IsPageReserved(page)) - PushFreePage((byte*)(i * Pager.AtomicPageSize)); - } + currentPage = 1; if (paging) { @@ -196,17 +200,21 @@ /// </summary> public static bool IsPageReserved (void *page) { - uint sp = 0; - uint *ptr = rpStack; - - while (sp < rpStackPointer) { - if (*ptr == (uint)page) - return true; - ++sp; - ++ptr; - } - - return false; + uint sp = 0; + ReservedPages* ptr = rpStack; + uint pageAddr = (uint)page; + + while (sp < rpStackPointer) + { + if (pageAddr >= ptr->Address && pageAddr <= (ptr->Address + (ptr->Size * Pager.AtomicPageSize))) + { + return true; + } + ++sp; + ++ptr; + } + + return false; } #endregion @@ -219,16 +227,7 @@ { void *page = null; - if (fpStackPointer == 0) - return null; - - do { - page = PopFreePage (); - if (!IsPageReserved(page)) // slow! - return page; - } while (page != null); - - return null; + return PopFreePage (); } /// <summary> @@ -432,7 +431,11 @@ #endregion #region ReservePage () family - + private static ReservedPages* GetReservedPage() + { + return &rpStack[rpStackPointer++]; + } + /// <summary> /// Reserves a memory page so that it cannot be allocated using /// <see cref="M:Alloc()" /> or <see cref="M:RangeAlloc(uint count)" />. @@ -442,6 +445,7 @@ /// </param> public static bool ReservePage(void *page) { + reservedPagesLeft = true; if (page == null) return false; @@ -451,10 +455,12 @@ //if (!IsPageFree(page, &fsp)) // return false; - - PushReservedPage(page); - - return true; + + ReservedPages* pages = GetReservedPage(); + pages->Address = (uint)page; + pages->Size = 1; + + return true; } /// <summary> @@ -469,13 +475,13 @@ /// </param> public static bool ReservePageRange(void *firstPage, uint pages, string name) { - byte* page = (byte*)firstPage; - for (int i = 0; i < pages; i++) - { - PushReservedPage(page); - page += Pager.AtomicPageSize; - } - return false; + reservedPagesLeft = true; + + ReservedPages* reservePages = GetReservedPage(); + reservePages->Address = (uint)firstPage; + reservePages->Size = pages; + + return true; } #endregion @@ -551,20 +557,31 @@ private static void *PopFreePage() { - if (fpStackPointer == 0) - return null; - return (void*)fpStack[--fpStackPointer]; + if (fpStackPointer == 0 && currentPage < (totalPages - 1)) + { + while (currentPage < (totalPages - 1)) + { + uint* page = (uint*)(currentPage * Pager.AtomicPageSize); + currentPage++; + + if (IsPageReserved(page)) + { + continue; + } + + return (void*)page; + } + } + else if (fpStackPointer == 0) + return null; + + return (void*)fpStack[--fpStackPointer]; } - - private static void PushReservedPage(void *page) - { - rpStack[rpStackPointer++] = (uint)page; - } #endregion #region Debug - public static void Dump(uint* stack, uint stackptr, int count) + public static void DumpStack(uint* stack, uint stackptr, int count) { for (int i = (int)stackptr - 1; i >= 0 && i>= stackptr - count; i--) { @@ -575,12 +592,26 @@ } } - public static void Dump(int count) + private static void DumpReservedStack(ReservedPages* pageStack, uint stackPtr, int count) + { + for (int i = (int)stackPtr - 1; i >= 0 && i >=stackPtr - count;i--) + { + ADC.TextMode.Write(i); + ADC.TextMode.Write(": Address: "); + ADC.TextMode.Write((int)pageStack->Address); + ADC.TextMode.Write(", Size: "); + ADC.TextMode.Write((int)pageStack->Size); + pageStack++; + ADC.TextMode.WriteLine(); + } + } + + public static void Dump(int count) { ADC.TextMode.WriteLine("Free"); - Dump(fpStack, fpStackPointer, count); + DumpStack(fpStack, fpStackPointer, count); ADC.TextMode.WriteLine("Reserved"); - Dump(rpStack, rpStackPointer, count); + DumpReservedStack(rpStack, rpStackPointer, count); } #endregion ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ SharpOS-Developers mailing list SharpOS-Developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sharpos-developers