internal unsafe void VisitSpecialData(DirectReferenceVisitor visitor) { HandlePage *limit = null; HandlePage *began; do { // Repeat this loop as long as new pages appear. // REVIEW: I'm not sure this is needed, the write barrier might // take care of this for us. began = pages; for (HandlePage *page = began; page != limit; page = page->next) { // Get the bounds. HandleEntry *entry = ((HandleEntry *)(page + 1)); HandleEntry *elimit = entry + handlesPerPage; for (; entry < elimit; entry++) { entry->Visit(visitor); } } limit = pages; } while (pages != began); }
internal unsafe UIntPtr FreeAllPages() { // We assume that external code has insured thread safety. freeList = null; for (HandlePage *next; pages != null; pages = next) { next = pages->next; MemoryManager.KernelFree((UIntPtr)pages, 1, process); } return((UIntPtr)pageCount * MemoryManager.PageSize); }
internal unsafe HandleEntry *AllocateEntry() { HandleEntry *entry = AllocateExisting(); if (entry != null) { return(entry); } #if SINGULARITY_KERNEL Kernel.Waypoint(830); #endif // SINGULARITY_KERNEL // Need to allocate a new page. HandlePage *page = (HandlePage *)MemoryManager.KernelAllocate( 1, process, 0, PageType.Shared); #if SINGULARITY_KERNEL Kernel.Waypoint(831); #endif // SINGULARITY_KERNEL if (page == null) { return(null); } // Get the bounds. HandleEntry *beg = ((HandleEntry *)(page + 1)); HandleEntry *end = beg + handlesPerPage - 1; // Save off the first entry to return. entry = beg++; entry->Set(null); entry->next = null; // Initialize the free list in the rest of the entries. for (HandleEntry *step = beg; step < end; step++) { step->Set(null); step->next = step + 1; } end->Set(null); end->next = null; // Initialize the page header and insert into the page list. page->SetTable(this); page->next = null; HandlePage *last; do { last = pages; page->next = last; // Interlocked.CompareExchange only updates pages if it hasn't // changed within this loop. } while (last != Interlocked.CompareExchange(ref pages, page, last)); // Then insert into the free list. HandleEntry *next; do { next = freeList; end->next = next; // Interlocked.CompareExchange only updates freeList if it hasn't // changed with this loop. } while (next != Interlocked.CompareExchange(ref freeList, beg, next)); Interlocked.Increment(ref pageCount); return(entry); }
internal unsafe HandleTable(Process process) { pages = null; freeList = null; }
internal static unsafe HandleTable FindOwner(HandleEntry *entry) { HandlePage *page = (HandlePage *)MemoryManager.PageAlign((UIntPtr)entry); return(page->GetTable()); }