Lockless StrategyGetBuffer clock sweep hotpath.
StrategyGetBuffer() has proven to be a bottleneck in a number of
buffer acquisition heavy workloads. To some degree this has already
been alleviated by
5d7962c6, but it's still can be quite a heavy
bottleneck. The problem is that in unfortunate usage patterns a
single StrategyGetBuffer() call will have to look at a large number of
buffers - in turn making it likely that the process will be put to
sleep while still holding the spinlock.
Replace most of the buffer_strategy_lock for the clock sweep by a
atomic nextVictimBuffer variable. That variable, modulo NBuffers, is
the current hand of the clock sweep. The buffer clock-sweep only needs
to acquire the spinlock after a wraparound. And even then, only in the
process wrapping around. That alleviates nearly all the contention in
the relevant spinlock.
Reviewed-By: Robert Haas and Amit Kapila