• Andres Freund's avatar
    Fix various shortcomings of the new PrivateRefCount infrastructure. · 2d115e47
    Andres Freund authored
    As noted by Tom Lane the improvements in 4b4b680c had the problem
    that in some situations we searched, entered and modified entries in
    the private refcount hash while holding a spinlock. I had tried to
    keep the logic entirely local to PinBuffer_Locked(), but that's not
    really possible given it's called with a spinlock held...
    
    Besides being disadvantageous from a performance point of view, this
    also has problems with error handling safety. If we failed inserting
    an entry into the hashtable due to an out of memory error, we'd error
    out with a held spinlock. Not good.
    
    Change the way private refcounts are manipulated: Before a buffer can
    be tracked an entry has to be reserved using
    ReservePrivateRefCountEntry(); then, if a entry is not found using
    GetPrivateRefCountEntry(), it can be entered with
    NewPrivateRefCountEntry().
    
    Also take advantage of the fact that PinBuffer_Locked() currently is
    never called for buffers that already have been pinned by the current
    backend and don't search the private refcount entries for preexisting
    local pins. That results in a small, but measurable, performance
    improvement.
    
    Additionally make ReleaseBuffer() always call UnpinBuffer() for shared
    buffers. That avoids duplicating work in an eventual UnpinBuffer()
    call that already has been done in ReleaseBuffer() and also saves some
    code.
    
    Per discussion with Tom Lane.
    
    Discussion: 15028.1418772313@sss.pgh.pa.us
    2d115e47
bufmgr.c 105 KB