88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.103 2001/01/12 21:53:57 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.104 2001/01/14 05:08:15 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -92,6 +92,7 @@ static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
9292bool bufferLockHeld );
9393static BufferDesc * BufferAlloc (Relation reln ,BlockNumber blockNum ,
9494bool * foundPtr ,bool bufferLockHeld );
95+ static int ReleaseBufferWithBufferLock (Buffer buffer );
9596static int BufferReplace (BufferDesc * bufHdr );
9697void PrintBufferDescs (void );
9798
@@ -687,10 +688,14 @@ ReleaseAndReadBuffer(Buffer buffer,
687688{
688689bufHdr = & BufferDescriptors [buffer - 1 ];
689690Assert (PrivateRefCount [buffer - 1 ]> 0 );
690- PrivateRefCount [buffer - 1 ]-- ;
691- if (PrivateRefCount [buffer - 1 ]== 0 )
691+ if (PrivateRefCount [buffer - 1 ]> 1 )
692+ {
693+ PrivateRefCount [buffer - 1 ]-- ;
694+ }
695+ else
692696{
693697SpinAcquire (BufMgrLock );
698+ PrivateRefCount [buffer - 1 ]= 0 ;
694699Assert (bufHdr -> refcount > 0 );
695700bufHdr -> refcount -- ;
696701if (bufHdr -> refcount == 0 )
@@ -1185,10 +1190,7 @@ DropRelationBuffers(Relation rel)
11851190/* Assert checks that buffer will actually get freed! */
11861191Assert (PrivateRefCount [i - 1 ]== 1 &&
11871192bufHdr -> refcount == 1 );
1188- /* ReleaseBuffer expects we do not hold the lock at entry */
1189- SpinRelease (BufMgrLock );
1190- ReleaseBuffer (i );
1191- SpinAcquire (BufMgrLock );
1193+ ReleaseBufferWithBufferLock (i );
11921194}
11931195/*
11941196 * And mark the buffer as no longer occupied by this rel.
@@ -1270,10 +1272,7 @@ DropRelFileNodeBuffers(RelFileNode rnode)
12701272/* Assert checks that buffer will actually get freed! */
12711273Assert (PrivateRefCount [i - 1 ]== 1 &&
12721274bufHdr -> refcount == 1 );
1273- /* ReleaseBuffer expects we do not hold the lock at entry */
1274- SpinRelease (BufMgrLock );
1275- ReleaseBuffer (i );
1276- SpinAcquire (BufMgrLock );
1275+ ReleaseBufferWithBufferLock (i );
12771276}
12781277/*
12791278 * And mark the buffer as no longer occupied by this rel.
@@ -1624,10 +1623,14 @@ ReleaseBuffer(Buffer buffer)
16241623bufHdr = & BufferDescriptors [buffer - 1 ];
16251624
16261625Assert (PrivateRefCount [buffer - 1 ]> 0 );
1627- PrivateRefCount [buffer - 1 ]-- ;
1628- if (PrivateRefCount [buffer - 1 ]== 0 )
1626+ if (PrivateRefCount [buffer - 1 ]> 1 )
1627+ {
1628+ PrivateRefCount [buffer - 1 ]-- ;
1629+ }
1630+ else
16291631{
16301632SpinAcquire (BufMgrLock );
1633+ PrivateRefCount [buffer - 1 ]= 0 ;
16311634Assert (bufHdr -> refcount > 0 );
16321635bufHdr -> refcount -- ;
16331636if (bufHdr -> refcount == 0 )
@@ -1641,6 +1644,48 @@ ReleaseBuffer(Buffer buffer)
16411644return STATUS_OK ;
16421645}
16431646
1647+ /*
1648+ * ReleaseBufferWithBufferLock
1649+ *Same as ReleaseBuffer except we hold the lock
1650+ */
1651+ static int
1652+ ReleaseBufferWithBufferLock (Buffer buffer )
1653+ {
1654+ BufferDesc * bufHdr ;
1655+
1656+ if (BufferIsLocal (buffer ))
1657+ {
1658+ Assert (LocalRefCount [- buffer - 1 ]> 0 );
1659+ LocalRefCount [- buffer - 1 ]-- ;
1660+ return STATUS_OK ;
1661+ }
1662+
1663+ if (BAD_BUFFER_ID (buffer ))
1664+ return STATUS_ERROR ;
1665+
1666+ bufHdr = & BufferDescriptors [buffer - 1 ];
1667+
1668+ Assert (PrivateRefCount [buffer - 1 ]> 0 );
1669+ if (PrivateRefCount [buffer - 1 ]> 1 )
1670+ {
1671+ PrivateRefCount [buffer - 1 ]-- ;
1672+ }
1673+ else
1674+ {
1675+ PrivateRefCount [buffer - 1 ]= 0 ;
1676+ Assert (bufHdr -> refcount > 0 );
1677+ bufHdr -> refcount -- ;
1678+ if (bufHdr -> refcount == 0 )
1679+ {
1680+ AddBufferToFreelist (bufHdr );
1681+ bufHdr -> flags |=BM_FREE ;
1682+ }
1683+ }
1684+
1685+ return STATUS_OK ;
1686+ }
1687+
1688+
16441689#ifdef NOT_USED
16451690void
16461691IncrBufferRefCount_Debug (char * file ,int line ,Buffer buffer )
@@ -2217,9 +2262,9 @@ MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer))
22172262SpinRelease (BufMgrLock );
22182263
22192264LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
2220- PrivateRefCount [buffer - 1 ]-- ;
22212265
22222266SpinAcquire (BufMgrLock );
2267+ PrivateRefCount [buffer - 1 ]= 0 ;
22232268Assert (bufHdr -> refcount > 0 );
22242269bufHdr -> flags |= (BM_DIRTY |BM_JUST_DIRTIED );
22252270bufHdr -> CleanupFunc = CleanupFunc ;