示例#1
0
        /// <summary>
        /// Releases a page to the free list
        /// </summary>
        public void Free(Page *page)
        {
            var    oldFree   = _FreePages;
            string debugName = null;

            if (page->DebugTag != null)
            {
                debugName = (string)Intrinsic.GetObjectFromAddress((Pointer)(uint)page->DebugTag);
            }

            UninterruptibleMonitor.Enter(this);
            try
            {
                var debugCount = list_head.list_count((list_head *)page); // DEBUG

                SelfCheck("SCF1", debugCount);
                Page *temp   = page;
                uint  result = 0;

                do
                {
                    result++;
                    if (temp->Status == PageStatus.Free)
                    {
                        //Panic.Error("Double Free");
                        SelfCheck("SCF3", debugCount);
                        KernelMessage.WriteLine("Double Free. Pages {0} Iteration {1}", debugCount, result);
                        Debug.Break();
                    }

                    temp->Status = PageStatus.Free;

                    var oldTemp = temp;
                    temp = (Page *)temp->Lru.next;
                    Native.Nop();
                    _FreePages++;

                    list_head.list_move_tail((list_head *)oldTemp, FreeList);
                }while (temp != page && result != debugCount);

                //list_head.list_headless_splice_tail((list_head*)page, FreeList);
                SelfCheck("SCF2", debugCount);
            }
            finally
            {
                UninterruptibleMonitor.Exit(this);
            }
            var freedPages = _FreePages - oldFree;

            if (KConfig.Log.PageAllocation && TraceOptions.Enabled && freedPages >= TraceOptions.MinPages)
            {
                KernelMessage.Path(DebugName, "Freed Pages: {1}. Addr: {2:X8}. Now available: {3} --> {4}. Allocations={5} DebugName={0}.", debugName, freedPages, GetAddress(page), oldFree, _FreePages, (uint)Requests);
            }

            _Releases++;
        }
示例#2
0
 public void Start()
 {
     UninterruptibleMonitor.Enter(Threads);
     try
     {
         RunState = ProcessRunState.Running;
         for (var i = 0; i < Threads.Count; i++)
         {
             KernelMessage.WriteLine("Starting {0}, ProcessID={1} on Thread {2}", Path, (uint)ProcessID, (uint)Threads[0].ThreadID);
             Threads[i].Start();
         }
     }
     finally
     {
         UninterruptibleMonitor.Exit(Threads);
     }
 }
示例#3
0
        private Page *AllocateInternal(uint pages, AllocatePageOptions options = default)
        {
            if (KConfig.Log.PageAllocation && TraceOptions.Enabled && pages >= TraceOptions.MinPages)
            {
                KernelMessage.Path(DebugName, "Requesting Pages: {1}. Available: {2} DebugName={0}", options.DebugName, pages, _FreePages);
            }

            if (pages == 256)
            {
                Debug.Nop();
            }

            UninterruptibleMonitor.Enter(this);
            try
            {
                SelfCheck("SC1");
                if (pages > 1 && (AddressSpaceKind == AddressSpaceKind.Virtual || options.Continuous))
                {
                    if (!MoveToFreeContinuous(pages))
                    {
                        // Compact
                        //KernelMessage.Path(DebugName, "Compacting Linked List");
                        //this.DumpPages();
                        BuildLinkedLists();
                        if (!MoveToFreeContinuous(pages))
                        {
                            this.DumpPages();
                            KernelMessage.WriteLine("Requesting {0} pages failed", pages);
                            Panic.Error("Requesting pages failed: out of memory");
                        }
                    }
                }

                // ---
                var head     = FreeList;
                var headPage = (Page *)head;
                FreeList = head->next;
                list_head.list_del_init(head);
                headPage->Status = PageStatus.Used;
                if (KConfig.Log.PageAllocation)
                {
                    if (options.DebugName != null)
                    {
                        headPage->DebugTag = (uint)Intrinsic.GetObjectAddress(options.DebugName);
                    }
                    else
                    {
                        headPage->DebugTag = null;
                    }
                }
                _FreePages--;
                // ---

                for (var i = 1; i < pages; i++)
                {
                    var tmpNextFree = FreeList->next;
                    list_head.list_move_tail(FreeList, head);
                    var p = (Page *)FreeList;
                    if (p->Status == PageStatus.Used)
                    {
                        this.DumpPages();
                        this.DumpPage(p);
                        KernelMessage.Path(DebugName, "Double Alloc pages={0} allocs={1} free={2} ptr={3:X8}", pages, (uint)_Requests, _FreePages, (uint)p);
                        Panic.Error("Double Alloc");
                    }
                    p->Status = PageStatus.Used;
                    FreeList  = tmpNextFree;
                    _FreePages--;
                }

                if (KConfig.Log.PageAllocation && TraceOptions.Enabled && pages >= TraceOptions.MinPages)
                {
                    KernelMessage.Path(DebugName, "Allocation done. Addr: {0:X8} Available: {1}", GetAddress(headPage), _FreePages);
                }

                _Requests++;

                CheckAllocation(headPage, pages);
                SelfCheck("SC2");

                return(headPage);
            }
            finally
            {
                UninterruptibleMonitor.Exit(this);
            }
        }