<structfield>size</structfield> <type>int8</type>
</para>
<para>
- Size of the allocation in bytes. NULL for entries of type
- <literal>area</literal> and <literal>hash</literal>.
+ Size of the allocation in bytes. NULL for entries that failed
+ initialization.
</para></entry>
</row>
</tbody>
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;
return size;
}
+/*
+ * 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.
extern void dsa_free(dsa_area *area, dsa_pointer dp);
extern void *dsa_get_address(dsa_area *area, dsa_pointer dp);
extern size_t dsa_get_total_size(dsa_area *area);
+extern size_t dsa_get_total_size_from_handle(dsa_handle handle);
extern void dsa_trim(dsa_area *area);
extern void dsa_dump(dsa_area *area);
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size_ok
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;
- name | type | size
-------+------+------
+ name | type | size_ok
+------+------+---------
(0 rows)
CREATE EXTENSION test_dsm_registry;
(1 row)
\c
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size_ok
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;
- name | type | size
-------------------------+---------+------
+ name | type | size_ok
+------------------------+---------+---------
test_dsm_registry_dsa | area | t
test_dsm_registry_dsm | segment | t
test_dsm_registry_hash | hash | t
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size_ok
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;
CREATE EXTENSION test_dsm_registry;
SELECT get_val_in_shmem();
SELECT get_val_in_hash('test');
\c
-SELECT name, type, size IS DISTINCT FROM 0 AS size
+SELECT name, type, size > 0 AS size_ok
FROM pg_dsm_registry_allocations
WHERE name like 'test_dsm_registry%' ORDER BY name;