summaryrefslogtreecommitdiff
path: root/contrib/pg_buffercache
diff options
context:
space:
mode:
authorTom Lane2006-07-23 03:07:58 +0000
committerTom Lane2006-07-23 03:07:58 +0000
commit10b9ca3d054a75e3c361b12388c50a11c828aa24 (patch)
treed88ef489ce71f6bd2ca5aa6cf90006212e536bcc /contrib/pg_buffercache
parent51ee9fa1574e1826dde4012ecb07455d73fb1444 (diff)
Split the buffer mapping table into multiple separately lockable
partitions, as per discussion. Passes functionality checks, but I don't have any performance data yet.
Diffstat (limited to 'contrib/pg_buffercache')
-rw-r--r--contrib/pg_buffercache/pg_buffercache_pages.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index a2811eb001..2d7392884e 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -3,7 +3,7 @@
* pg_buffercache_pages.c
* display some contents of the buffer cache
*
- * $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.7 2006/05/30 22:12:13 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.8 2006/07/23 03:07:57 tgl Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
@@ -74,7 +74,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
if (SRF_IS_FIRSTCALL())
{
- uint32 i;
+ int i;
volatile BufferDesc *bufHdr;
funcctx = SRF_FIRSTCALL_INIT();
@@ -108,7 +108,6 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
funcctx->max_calls = NBuffers;
funcctx->user_fctx = fctx;
-
/* Allocate NBuffers worth of BufferCachePagesRec records. */
fctx->record = (BufferCachePagesRec *) palloc(sizeof(BufferCachePagesRec) * NBuffers);
@@ -120,17 +119,21 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
fctx->values[4] = (char *) palloc(3 * sizeof(uint32) + 1);
fctx->values[5] = (char *) palloc(2);
-
/* Return to original context when allocating transient memory */
MemoryContextSwitchTo(oldcontext);
-
/*
- * Lock Buffer map and scan though all the buffers, saving the
- * relevant fields in the fctx->record structure.
+ * To get a consistent picture of the buffer state, we must lock
+ * all partitions of the buffer map. Needless to say, this is
+ * horrible for concurrency...
*/
- LWLockAcquire(BufMappingLock, LW_SHARED);
+ for (i = 0; i < NUM_BUFFER_PARTITIONS; i++)
+ LWLockAcquire(FirstBufMappingLock + i, LW_SHARED);
+ /*
+ * Scan though all the buffers, saving the relevant fields in the
+ * fctx->record structure.
+ */
for (i = 0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++)
{
/* Lock each buffer header before inspecting. */
@@ -157,7 +160,8 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
}
/* Release Buffer map. */
- LWLockRelease(BufMappingLock);
+ for (i = 0; i < NUM_BUFFER_PARTITIONS; i++)
+ LWLockRelease(FirstBufMappingLock + i);
}
funcctx = SRF_PERCALL_SETUP();
@@ -165,7 +169,6 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
/* Get the saved state */
fctx = funcctx->user_fctx;
-
if (funcctx->call_cntr < funcctx->max_calls)
{
uint32 i = funcctx->call_cntr;