internal virtual void AddFreePageToFreelist(long pageRef) { object current; FreePage freePage = new FreePage(pageRef); do { current = FreelistHead; if (current is AtomicInteger && (( AtomicInteger )current).get() > Pages.PageCount) { current = null; } freePage.Next = current; } while (!CompareAndSetFreelistHead(current, freePage)); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: long grabFreeAndExclusivelyLockedPage(org.neo4j.io.pagecache.tracing.PageFaultEvent faultEvent) throws java.io.IOException internal virtual long GrabFreeAndExclusivelyLockedPage(PageFaultEvent faultEvent) { // Review the comment on the freelist field before making changes to // this part of the code. // Whatever the case, we're going to the head-pointer of the freelist, // and in doing so, we can discover a number of things. // We can discover a MuninnPage object, in which case we can try to // CAS the freelist pointer to the value of the MuninnPage.nextFree // pointer, and if this succeeds then we've grabbed that page. // We can discover a FreePage object, in which case we'll do a similar // dance by attempting to CAS the freelist to the FreePage objects next // pointer, and again, if we succeed then we've grabbed the MuninnPage // given by the FreePage object. // We can discover a null-pointer, in which case the freelist has just // been emptied for whatever it contained before. New FreePage objects // are eventually going to be added to the freelist, but we are not // going to wait around for that to happen. If the freelist is empty, // then we do our own eviction to get a free page. // If we find a FreePage object on the freelist, then it is important // to check and see if it is the shutdownSignal instance. If that's the // case, then the page cache has been shut down, and we should throw an // exception from our page fault routine. object current; for ( ;;) { AssertHealthy(); current = FreelistHead; if (current == null) { UnparkEvictor(); long pageRef = CooperativelyEvict(faultEvent); if (pageRef != 0) { return(pageRef); } } else if (current is AtomicInteger) { int pageCount = Pages.PageCount; AtomicInteger counter = ( AtomicInteger )current; int pageId = counter.get(); if (pageId < pageCount && counter.compareAndSet(pageId, pageId + 1)) { return(Pages.deref(pageId)); } if (pageId >= pageCount) { CompareAndSetFreelistHead(current, null); } } else if (current is FreePage) { FreePage freePage = ( FreePage )current; if (freePage == _shutdownSignal) { throw new System.InvalidOperationException("The PageCache has been shut down."); } if (CompareAndSetFreelistHead(freePage, freePage.NextConflict)) { return(freePage.PageRef); } } } }