On 06/27/2014 08:15 PM, Robert Haas wrote:
> On Thu, Jun 26, 2014 at 3:04 PM, Andres Freund <andres@2ndquadrant.com> wrote:
>> I don't really see usecases where it's not related data that's being
>> touched, but: The point is that the fastpath (not using a spinlock) might
>> touch the atomic variable, even while the slowpath has acquired the
>> spinlock. So the slowpath can't just use non-atomic operations on the
>> atomic variable.
>> Imagine something like releasing a buffer pin while somebody else is
>> doing something that requires holding the buffer header spinlock.
>
> If the atomic variable can be manipulated without the spinlock under
> *any* circumstances, then how is it a good idea to ever manipulate it
> with the spinlock?
With the WALInsertLock scaling stuff in 9.4, there are now two variables
protected by a spinlock: the current WAL insert location, and the prev
pointer (CurrBytePos and PrevBytePos). To insert a new WAL record, you
need to grab the spinlock to update both of them atomically. But to just
read the WAL insert pointer, you could do an atomic read of CurrBytePos
if the architecture supports it - now you have to grab the spinlock.
Admittedly that's just an atomic read, not an atomic compare and
exchange or fetch-and-add. Or if the architecture has an atomic 128-bit
compare & exchange op you could replace the spinlock with that. But it's
not hard to imagine similar situations where you sometimes need to lock
a larger data structure to modify it atomically, but sometimes you just
need to modify part of it and an atomic op would suffice.
I thought Andres' LWLock patch also did something like that. If the lock
is not contended, you can acquire it with an atomic compare & exchange
to increment the exclusive/shared counter. But to manipulate the wait
queue, you need the spinlock.
- Heikki