summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/storage/ipc/dsm_registry.c25
-rw-r--r--src/backend/utils/mmgr/dsa.c35
2 files changed, 44 insertions, 16 deletions
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index ef6533b1100..66240318e83 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -463,26 +463,19 @@ pg_get_dsm_registry_allocations(PG_FUNCTION_ARGS)
Datum vals[3];
bool nulls[3] = {0};
- /* Do not show partially-initialized entries. */
- if (entry->type == DSMR_ENTRY_TYPE_DSM &&
- entry->dsm.handle == DSM_HANDLE_INVALID)
- continue;
- if (entry->type == DSMR_ENTRY_TYPE_DSA &&
- entry->dsa.handle == DSA_HANDLE_INVALID)
- continue;
- if (entry->type == DSMR_ENTRY_TYPE_DSH &&
- entry->dsh.dsa_handle == DSA_HANDLE_INVALID)
- continue;
-
vals[0] = CStringGetTextDatum(entry->name);
vals[1] = CStringGetTextDatum(DSMREntryTypeNames[entry->type]);
- /*
- * Since we can't know the size of DSA/dshash entries without first
- * attaching to them, return NULL for those.
- */
- if (entry->type == DSMR_ENTRY_TYPE_DSM)
+ /* Be careful to only return the sizes of initialized entries. */
+ if (entry->type == DSMR_ENTRY_TYPE_DSM &&
+ entry->dsm.handle != DSM_HANDLE_INVALID)
vals[2] = Int64GetDatum(entry->dsm.size);
+ else if (entry->type == DSMR_ENTRY_TYPE_DSA &&
+ entry->dsa.handle != DSA_HANDLE_INVALID)
+ vals[2] = Int64GetDatum(dsa_get_total_size_from_handle(entry->dsa.handle));
+ else if (entry->type == DSMR_ENTRY_TYPE_DSH &&
+ entry->dsh.dsa_handle !=DSA_HANDLE_INVALID)
+ vals[2] = Int64GetDatum(dsa_get_total_size_from_handle(entry->dsh.dsa_handle));
else
nulls[2] = true;
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index be43e9351c3..c8a72686177 100644
--- a/src/backend/utils/mmgr/dsa.c
+++ b/src/backend/utils/mmgr/dsa.c
@@ -1051,6 +1051,41 @@ dsa_get_total_size(dsa_area *area)
}
/*
+ * Same as dsa_get_total_size(), but accepts a DSA handle. The area must have
+ * been created with dsa_create (not dsa_create_in_place).
+ */
+size_t
+dsa_get_total_size_from_handle(dsa_handle handle)
+{
+ size_t size;
+ bool already_attached;
+ dsm_segment *segment;
+ dsa_area_control *control;
+
+ already_attached = dsa_is_attached(handle);
+ if (already_attached)
+ segment = dsm_find_mapping(handle);
+ else
+ segment = dsm_attach(handle);
+
+ if (segment == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not attach to dynamic shared area")));
+
+ control = (dsa_area_control *) dsm_segment_address(segment);
+
+ LWLockAcquire(&control->lock, LW_EXCLUSIVE);
+ size = control->total_segment_size;
+ LWLockRelease(&control->lock);
+
+ if (!already_attached)
+ dsm_detach(segment);
+
+ return size;
+}
+
+/*
* Aggressively free all spare memory in the hope of returning DSM segments to
* the operating system.
*/