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

Reply via email to