"Kevin Grittner" <[EMAIL PROTECTED]> 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, %al
        cmpb    $0,28(%ebx)     
        jne     1f              
        lock                    
        xchgb   %al,28(%ebx)            <-- acquire spinlock
1: 
        testb   %al, %al
        jne     .L228                   <-- (failure case is out-of-line)
.L221:
        movl    20(%ebx), %ecx          <-- fetch refcount
        movw    16(%ebx), %ax
        incl    %ecx                    <-- increment refcount
        movb    $0, 28(%ebx)            <-- release spinlock
        shrl    %eax
        movl    %ecx, 20(%ebx)          <-- store back refcount
        andl    $1, %eax
        movl    %eax, %edi

For comparison, gcc 4.0.1 on my Fedora machine produces

        movb    $1, %al
        cmpb    $0,28(%ebx)     
        jne     1f              
        lock                    
        xchgb   %al,28(%ebx)            <-- acquire spinlock
1: 
        testb   %al, %al
        jne     .L117
        incl    20(%ebx)                <-- increment refcount
        movw    16(%ebx), %ax
        movb    $0, 28(%ebx)            <-- release spinlock
        movl    %eax, %edi
        shrl    %edi
        andl    $1, %edi
        movl    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

---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to