diff options
| author | Tom Lane | 2006-07-23 03:07:58 +0000 |
|---|---|---|
| committer | Tom Lane | 2006-07-23 03:07:58 +0000 |
| commit | 10b9ca3d054a75e3c361b12388c50a11c828aa24 (patch) | |
| tree | d88ef489ce71f6bd2ca5aa6cf90006212e536bcc /contrib/pg_buffercache | |
| parent | 51ee9fa1574e1826dde4012ecb07455d73fb1444 (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.c | 23 |
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; |
