0001-Associate-names-to-created-dynamic-shared-memory-seg.patch
text/x-patch
Filename: 0001-Associate-names-to-created-dynamic-shared-memory-seg.patch
Type: text/x-patch
Part: 0
Message:
Re: pg_shmem_allocations view
Patch
Format: unified
Series: patch 0001
| File | + | − |
|---|---|---|
| contrib/test_shm_mq/setup.c | 1 | 1 |
| src/backend/storage/ipc/dsm.c | 37 | 23 |
| src/include/storage/dsm.h | 1 | 1 |
>From c219c03a173fef962c1caba9f016d5d87448fd8f Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 6 May 2014 19:42:36 +0200
Subject: [PATCH 1/4] Associate names to created dynamic shared memory
segments.
At some later point we want to add a view show all allocated dynamic
shared memory segments so admins can understand resource usage. To
avoid breaking the API in 9.5 add the necessary name now.
---
contrib/test_shm_mq/setup.c | 2 +-
src/backend/storage/ipc/dsm.c | 60 ++++++++++++++++++++++++++-----------------
src/include/storage/dsm.h | 2 +-
3 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/contrib/test_shm_mq/setup.c b/contrib/test_shm_mq/setup.c
index 572cf88..897c47b 100644
--- a/contrib/test_shm_mq/setup.c
+++ b/contrib/test_shm_mq/setup.c
@@ -125,7 +125,7 @@ setup_dynamic_shared_memory(int64 queue_size, int nworkers,
segsize = shm_toc_estimate(&e);
/* Create the shared memory segment and establish a table of contents. */
- seg = dsm_create(shm_toc_estimate(&e));
+ seg = dsm_create("test_shm_mq", shm_toc_estimate(&e));
toc = shm_toc_create(PG_TEST_SHM_MQ_MAGIC, dsm_segment_address(seg),
segsize);
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index a5c0084..c8fdf6e 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -80,8 +80,10 @@ struct dsm_segment
/* Shared-memory state for a dynamic shared memory segment. */
typedef struct dsm_control_item
{
- dsm_handle handle;
+ dsm_handle handle; /* segment identifier */
uint32 refcnt; /* 2+ = active, 1 = moribund, 0 = gone */
+ Size size; /* current size */
+ char name[SHMEM_INDEX_KEYSIZE]; /* informational name */
} dsm_control_item;
/* Layout of the dynamic shared memory control segment. */
@@ -454,14 +456,16 @@ dsm_set_control_handle(dsm_handle h)
* Create a new dynamic shared memory segment.
*/
dsm_segment *
-dsm_create(Size size)
+dsm_create(const char *name, Size size)
{
dsm_segment *seg = dsm_create_descriptor();
- uint32 i;
- uint32 nitems;
+ dsm_control_item *item;
+ uint32 slot;
/* Unsafe in postmaster (and pointless in a stand-alone backend). */
Assert(IsUnderPostmaster);
+ Assert(name != NULL && strlen(name) > 0 &&
+ strlen(name) < SHMEM_INDEX_KEYSIZE - 1);
if (!dsm_init_done)
dsm_backend_startup();
@@ -479,33 +483,39 @@ dsm_create(Size size)
/* Lock the control segment so we can register the new segment. */
LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE);
- /* Search the control segment for an unused slot. */
- nitems = dsm_control->nitems;
- for (i = 0; i < nitems; ++i)
+ /*
+ * Search the control segment for an unused slot that's previously been
+ * used. If we don't find one initialize a new one if there's still space.
+ */
+ for (slot = 0; slot < dsm_control->nitems; ++slot)
{
- if (dsm_control->item[i].refcnt == 0)
- {
- dsm_control->item[i].handle = seg->handle;
- /* refcnt of 1 triggers destruction, so start at 2 */
- dsm_control->item[i].refcnt = 2;
- seg->control_slot = i;
- LWLockRelease(DynamicSharedMemoryControlLock);
- return seg;
- }
+ if (dsm_control->item[slot].refcnt == 0)
+ break;
}
- /* Verify that we can support an additional mapping. */
- if (nitems >= dsm_control->maxitems)
+ /* Verify that we can support the mapping. */
+ if (slot >= dsm_control->maxitems)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("too many dynamic shared memory segments")));
- /* Enter the handle into a new array slot. */
- dsm_control->item[nitems].handle = seg->handle;
+ item = &dsm_control->item[slot];
+ item->handle = seg->handle;
/* refcnt of 1 triggers destruction, so start at 2 */
- dsm_control->item[nitems].refcnt = 2;
- seg->control_slot = nitems;
- dsm_control->nitems++;
+ item->refcnt = 2;
+ item->size = size;
+ strncpy(item->name, name, SHMEM_INDEX_KEYSIZE);
+ item->name[SHMEM_INDEX_KEYSIZE - 1] = 0;
+
+ seg->control_slot = slot;
+
+ /*
+ * Increase number of initilized slots if we didn't reuse a previously
+ * used one.
+ */
+ if (slot >= dsm_control->nitems)
+ dsm_control->nitems++;
+
LWLockRelease(DynamicSharedMemoryControlLock);
return seg;
@@ -658,6 +668,10 @@ dsm_resize(dsm_segment *seg, Size size)
Assert(seg->control_slot != INVALID_CONTROL_SLOT);
dsm_impl_op(DSM_OP_RESIZE, seg->handle, size, &seg->impl_private,
&seg->mapped_address, &seg->mapped_size, ERROR);
+
+ /* persist the changed size */
+ dsm_control->item[seg->control_slot].size = size;
+
return seg->mapped_address;
}
diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h
index 1d0110d..3dbe53b 100644
--- a/src/include/storage/dsm.h
+++ b/src/include/storage/dsm.h
@@ -29,7 +29,7 @@ extern void dsm_set_control_handle(dsm_handle h);
#endif
/* Functions that create, update, or remove mappings. */
-extern dsm_segment *dsm_create(Size size);
+extern dsm_segment *dsm_create(const char *name, Size size);
extern dsm_segment *dsm_attach(dsm_handle h);
extern void *dsm_resize(dsm_segment *seg, Size size);
extern void *dsm_remap(dsm_segment *seg);
--
1.8.3.251.g1462b67