* PinBuffer -- make buffer unavailable for replacement. * * For the default access strategy, the buffer's usage_count is incremented * when we first pin it; for other strategies we just make sure the usage_count * isn't zero. (The idea of the latter is that we don't want synchronized * heap scans to inflate the count, but we need it to not be zero to discourage * other backends from stealin
| 1799 | * some callers to avoid an extra spinlock cycle. |
| 1800 | */ |
| 1801 | static bool |
| 1802 | PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy) |
| 1803 | { |
| 1804 | Buffer b = BufferDescriptorGetBuffer(buf); |
| 1805 | bool result; |
| 1806 | PrivateRefCountEntry *ref; |
| 1807 | |
| 1808 | ref = GetPrivateRefCountEntry(b, true); |
| 1809 | |
| 1810 | if (ref == NULL) |
| 1811 | { |
| 1812 | uint32 buf_state; |
| 1813 | uint32 old_buf_state; |
| 1814 | |
| 1815 | ReservePrivateRefCountEntry(); |
| 1816 | ref = NewPrivateRefCountEntry(b); |
| 1817 | |
| 1818 | old_buf_state = pg_atomic_read_u32(&buf->state); |
| 1819 | for (;;) |
| 1820 | { |
| 1821 | if (old_buf_state & BM_LOCKED) |
| 1822 | old_buf_state = WaitBufHdrUnlocked(buf); |
| 1823 | |
| 1824 | buf_state = old_buf_state; |
| 1825 | |
| 1826 | /* increase refcount */ |
| 1827 | buf_state += BUF_REFCOUNT_ONE; |
| 1828 | |
| 1829 | if (strategy == NULL) |
| 1830 | { |
| 1831 | /* Default case: increase usagecount unless already max. */ |
| 1832 | if (BUF_STATE_GET_USAGECOUNT(buf_state) < BM_MAX_USAGE_COUNT) |
| 1833 | buf_state += BUF_USAGECOUNT_ONE; |
| 1834 | } |
| 1835 | else |
| 1836 | { |
| 1837 | /* |
| 1838 | * Ring buffers shouldn't evict others from pool. Thus we |
| 1839 | * don't make usagecount more than 1. |
| 1840 | */ |
| 1841 | if (BUF_STATE_GET_USAGECOUNT(buf_state) == 0) |
| 1842 | buf_state += BUF_USAGECOUNT_ONE; |
| 1843 | } |
| 1844 | |
| 1845 | if (pg_atomic_compare_exchange_u32(&buf->state, &old_buf_state, |
| 1846 | buf_state)) |
| 1847 | { |
| 1848 | result = (buf_state & BM_VALID) != 0; |
| 1849 | |
| 1850 | /* |
| 1851 | * Assume that we acquired a buffer pin for the purposes of |
| 1852 | * Valgrind buffer client checks (even in !result case) to |
| 1853 | * keep things simple. Buffers that are unsafe to access are |
| 1854 | * not generally guaranteed to be marked undefined or |
| 1855 | * non-accessible in any case. |
| 1856 | */ |
| 1857 | VALGRIND_MAKE_MEM_DEFINED(BufHdrGetBlock(buf), BLCKSZ); |
| 1858 | break; |
no test coverage detected