Important Note: Pin returns a raw pointer to the frame. This is potentially very dangerous and trusts the caller is going to protect this memory space. Important responsibilities for the caller are: (1) The caller should know the page size and not read/write beyond these boundaries. (2) If the given FileHandle is not a (temporary) in-memory file and the caller writes to the frame, caller should ma
| 122 | // (3) If multiple threads are writing to the page, they should coordinate separately because they |
| 123 | // both get access to the same piece of memory. |
| 124 | uint8_t* BufferManager::pin(FileHandle& fileHandle, page_idx_t pageIdx, |
| 125 | PageReadPolicy pageReadPolicy) { |
| 126 | auto pageState = fileHandle.getPageState(pageIdx); |
| 127 | while (true) { |
| 128 | auto currStateAndVersion = pageState->getStateAndVersion(); |
| 129 | switch (PageState::getState(currStateAndVersion)) { |
| 130 | case PageState::EVICTED: { |
| 131 | if (pageState->tryLock(currStateAndVersion)) { |
| 132 | if (!claimAFrame(fileHandle, pageIdx, pageReadPolicy)) { |
| 133 | pageState->resetToEvicted(); |
| 134 | throw BufferManagerException("Unable to allocate memory! The buffer pool is " |
| 135 | "full and no memory could be freed!"); |
| 136 | } |
| 137 | if (!evictionQueue.insert(fileHandle.getFileIndex(), pageIdx)) { |
| 138 | throw BufferManagerException( |
| 139 | "Eviction queue is full! This should be impossible."); |
| 140 | } |
| 141 | #if BM_MALLOC |
| 142 | DASSERT(pageState->getPage()); |
| 143 | return pageState->getPage(); |
| 144 | #else |
| 145 | return getFrame(fileHandle, pageIdx); |
| 146 | #endif |
| 147 | } |
| 148 | } break; |
| 149 | case PageState::UNLOCKED: |
| 150 | case PageState::MARKED: { |
| 151 | if (pageState->tryLock(currStateAndVersion)) { |
| 152 | return getFrame(fileHandle, pageIdx); |
| 153 | } |
| 154 | } break; |
| 155 | case PageState::LOCKED: { |
| 156 | continue; |
| 157 | } |
| 158 | default: { |
| 159 | UNREACHABLE_CODE; |
| 160 | } |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | #if defined(WIN32) |
| 166 | class AccessViolation : public std::exception { |
no test coverage detected