Esempio n. 1
0
 private void AbortPageFault(Exception throwable, int[] chunk, long chunkOffset, LatchMap.Latch latch, PageFaultEvent faultEvent)
 {
     UnsafeUtil.putIntVolatile(chunk, chunkOffset, UNMAPPED_TTE);
     latch.Release();
     faultEvent.Done(throwable);
     PinEvent.done();
 }
Esempio n. 2
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private boolean uncommonPin(long filePageId, long chunkOffset, int[] chunk) throws java.io.IOException
        private bool UncommonPin(long filePageId, long chunkOffset, int[] chunk)
        {
            if (NoFault)
            {
                // The only page state that needs to be cleared is the currentPageId, since it was set prior to pin.
                CurrentPageIdConflict = UNBOUND_PAGE_ID;
                return(true);
            }
            // Looks like there's no mapping, so we'd like to do a page fault.
            LatchMap.Latch latch = PagedFile.pageFaultLatches.takeOrAwaitLatch(filePageId);
            if (latch != null)
            {
                // We managed to inject our latch, so we now own the right to perform the page fault. We also
                // have a duty to eventually release and remove the latch, no matter what happens now.
                // However, we first have to double-check that a page fault did not complete in-between our initial
                // check in the translation table, and us getting a latch.
                if (UnsafeUtil.getIntVolatile(chunk, chunkOffset) == UNMAPPED_TTE)
                {
                    // Sweet, we didn't race with any other fault on this translation table entry.
                    long pageRef = PageFault(filePageId, Swapper, chunkOffset, chunk, latch);
                    PinCursorToPage(pageRef, filePageId, Swapper);
                    return(true);
                }
                // Oops, looks like we raced with another page fault on this file page.
                // Let's release our latch and retry the pin.
                latch.Release();
            }
            // We found a latch, so someone else is already doing a page fault for this page.
            // The `takeOrAwaitLatch` already waited for this latch to be released on our behalf,
            // so now we just have to do another iteration of the loop to see what's in the translation table now.
            return(false);
        }
Esempio n. 3
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private long pageFault(long filePageId, org.neo4j.io.pagecache.PageSwapper swapper, long chunkOffset, int[] chunk, LatchMap.Latch latch) throws java.io.IOException
        private long PageFault(long filePageId, PageSwapper swapper, long chunkOffset, int[] chunk, LatchMap.Latch latch)
        {
            // We are page faulting. This is a critical time, because we currently have the given latch in the chunk array
            // slot that we are faulting into. We MUST make sure to release that latch, and remove it from the chunk, no
            // matter what happens. Otherwise other threads will get stuck waiting forever for our page fault to finish.
            // If we manage to get a free page to fault into, then we will also be taking a write lock on that page, to
            // protect it against concurrent eviction as we assigning a binding to the page. If anything goes wrong, then
            // we must make sure to release that write lock as well.
            PageFaultEvent faultEvent = PinEvent.beginPageFault();
            long           pageRef;

            try
            {
                // The grabFreePage method might throw.
                pageRef = PagedFile.grabFreeAndExclusivelyLockedPage(faultEvent);

                // We got a free page, and we know that we have race-free access to it. Well, it's not entirely race
                // free, because other paged files might have it in their translation tables (or rather, their reads of
                // their translation tables might race with eviction) and try to pin it.
                // However, they will all fail because when they try to pin, because the page will be exclusively locked
                // and possibly bound to our page.
            }
            catch (Exception throwable)
            {
                // Make sure to unstuck the page fault latch.
                AbortPageFault(throwable, chunk, chunkOffset, latch, faultEvent);
                throw throwable;
            }
            try
            {
                // Check if we're racing with unmapping. We have the page lock
                // here, so the unmapping would have already happened. We do this
                // check before page.fault(), because that would otherwise reopen
                // the file channel.
                AssertPagedFileStillMappedAndGetIdOfLastPage();
                PagedFile.initBuffer(pageRef);
                PagedFile.fault(pageRef, swapper, PagedFile.swapperId, filePageId, faultEvent);
            }
            catch (Exception throwable)
            {
                // Make sure to unlock the page, so the eviction thread can pick up our trash.
                PagedFile.unlockExclusive(pageRef);
                // Make sure to unstuck the page fault latch.
                AbortPageFault(throwable, chunk, chunkOffset, latch, faultEvent);
                throw throwable;
            }
            // Put the page in the translation table before we undo the exclusive lock, as we could otherwise race with
            // eviction, and the onEvict callback expects to find a MuninnPage object in the table.
            UnsafeUtil.putIntVolatile(chunk, chunkOffset, PagedFile.toId(pageRef));
            // Once we page has been published to the translation table, we can convert our exclusive lock to whatever we
            // need for the page cursor.
            ConvertPageFaultLock(pageRef);
            latch.Release();
            faultEvent.Done();
            return(pageRef);
        }