"Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
> bufmgr.s file coming in separate (off-list) email.
Yup, here is the smoking gun! This code in PinBuffer
LockBufHdr_NoHoldoff(buf); buf->refcount++; result = (buf->flags & BM_VALID) != 0;
UnlockBufHdr_NoHoldoff(buf);
is translated as
movb $1, %alcmpb $0,28(%ebx) jne 1f lock xchgb %al,28(%ebx) <-- acquire
spinlock
1: testb %al, %aljne .L228 <-- (failure case is out-of-line)
.L221:movl 20(%ebx), %ecx <-- fetch refcountmovw 16(%ebx), %axincl %ecx <-- increment
refcountmovb $0, 28(%ebx) <-- release spinlockshrl %eaxmovl %ecx, 20(%ebx) <-- store back
refcountandl $1, %eaxmovl %eax, %edi
For comparison, gcc 4.0.1 on my Fedora machine produces
movb $1, %alcmpb $0,28(%ebx) jne 1f lock xchgb %al,28(%ebx) <-- acquire
spinlock
1: testb %al, %aljne .L117incl 20(%ebx) <-- increment refcountmovw 16(%ebx), %axmovb $0, 28(%ebx)
<-- release spinlockmovl %eax, %edishrl %ediandl $1, %edimovl PrivateRefCount, %eax
which is safe.
What we probably need to do is insert some "volatile" qualifiers
to force the compiler to behave better. What happens to the code
if you change PinBuffer to be declared as
static bool
PinBuffer(volatile BufferDesc *buf)
?
regards, tom lane