From a982fd9491c914c67d674a21e4ba0ac746807811 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Mon, 6 Apr 2026 10:43:18 +0530
Subject: [PATCH v20260406 2/6] Use smaps instead of status in
 resizable_shmem_used()

/proc/self/status gives memory usages across all the VMAs of a process.
/proc/self/smaps gives memory usages for each VMA separately. Hence use smaps to
accurately estimate the memory allocated in the main shared memory segment.
---
 .../resizable_shmem/resizable_shmem--1.0.sql  |  6 +-
 .../modules/resizable_shmem/resizable_shmem.c | 86 ++++++++-----------
 .../resizable_shmem/t/001_resizable_shmem.pl  |  2 +-
 3 files changed, 41 insertions(+), 53 deletions(-)

diff --git a/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql b/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql
index c1bcb6117b6..b4b07336dc3 100644
--- a/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql
+++ b/src/test/modules/resizable_shmem/resizable_shmem--1.0.sql
@@ -25,8 +25,10 @@ RETURNS boolean
 AS 'MODULE_PATHNAME'
 LANGUAGE C STRICT;
 
--- Function to report memory usage statistics of the calling backend
-CREATE FUNCTION resizable_shmem_usage(OUT rss_anon bigint, OUT rss_file bigint, OUT rss_shmem bigint, OUT vm_size bigint)
+-- Function to report memory mapped against the main shared memory segment in
+-- the backend where this function runs.
+CREATE FUNCTION resizable_shmem_usage()
+RETURNS bigint
 AS 'MODULE_PATHNAME'
 LANGUAGE C STRICT;
 
diff --git a/src/test/modules/resizable_shmem/resizable_shmem.c b/src/test/modules/resizable_shmem/resizable_shmem.c
index 5ae2d2e2d1d..2063d05053f 100644
--- a/src/test/modules/resizable_shmem/resizable_shmem.c
+++ b/src/test/modules/resizable_shmem/resizable_shmem.c
@@ -10,19 +10,17 @@
  */
 #include "postgres.h"
 
+#include <limits.h>
+#include <stdio.h>
+
 #include "commands/extension.h"
 #include "fmgr.h"
-#include "funcapi.h"
 #include "miscadmin.h"
 #include "storage/shmem.h"
 #include "storage/spin.h"
 #include "utils/builtins.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
-#include "utils/timestamp.h"
-#include "access/htup_details.h"
-
-#include <stdio.h>
 
 PG_MODULE_MAGIC;
 
@@ -252,68 +250,56 @@ resizable_shmem_read(PG_FUNCTION_ARGS)
 }
 
 /*
- * Report multiple memory usage statistics of the calling backend process
- * as reported by the kernel.
- * Returns RssAnon, RssFile, RssShmem, VmSize from /proc/self/status as a record.
+ * Return the memory mapped against the main shared memory segment in this
+ * backend.
  *
- * The function assumes that these values will be available in
- * /proc/self/status, any system which also support madvise with MADV_REMOVE and
- * MADV_POPULATE_WRITE.
+ * The VMA containing our resizable_shmem pointer is used to determine the main
+ * memory segment.  RSS + Swap (in bytes) for that VMS from  /proc/self/smaps is
+ * returned.
  */
 Datum
 resizable_shmem_usage(PG_FUNCTION_ARGS)
 {
 	FILE	   *f;
 	char		line[256];
-	int64		rss_anon_kb = -1;
-	int64		rss_file_kb = -1;
-	int64		rss_shmem_kb = -1;
-	int64		vm_size_kb = -1;
-	int			found = 0;
-	TupleDesc	tupdesc;
-	Datum		values[4];
-	bool		nulls[4];
-	HeapTuple	tuple;
-
-	/* Open /proc/self/status to read memory information */
-	f = fopen("/proc/self/status", "r");
+	int64		rss_kb = -1;
+	int64		swap_kb = -1;
+	uintptr_t	target = (uintptr_t) resizable_shmem;
+	bool		in_target_vma = false;
+	size_t		result;
+
+	f = fopen("/proc/self/smaps", "r");
 	if (f == NULL)
 		ereport(ERROR,
 				(errcode_for_file_access(),
-				 errmsg("could not open /proc/self/status: %m")));
+				 errmsg("could not open /proc/self/smaps: %m")));
 
-	/* Look for the memory usage lines */
-	while (fgets(line, sizeof(line), f) != NULL && found < 4)
+	while (fgets(line, sizeof(line), f) != NULL)
 	{
-		if (rss_anon_kb == -1 && sscanf(line, "RssAnon: %ld kB", &rss_anon_kb) == 1)
-			found++;
-		else if (rss_file_kb == -1 && sscanf(line, "RssFile: %ld kB", &rss_file_kb) == 1)
-			found++;
-		else if (rss_shmem_kb == -1 && sscanf(line, "RssShmem: %ld kB", &rss_shmem_kb) == 1)
-			found++;
-		else if (vm_size_kb == -1 && sscanf(line, "VmSize: %ld kB", &vm_size_kb) == 1)
-			found++;
+		unsigned long start;
+		unsigned long end;
+
+		if (sscanf(line, "%lx-%lx", &start, &end) == 2)
+		{
+			in_target_vma = (target >= start && target < end);
+		}
+		else if (in_target_vma)
+		{
+			if (rss_kb == -1)
+				sscanf(line, "Rss: %ld kB", &rss_kb);
+			if (swap_kb == -1)
+				sscanf(line, "Swap: %ld kB", &swap_kb);
+			if (rss_kb >= 0 && swap_kb >= 0)
+				break;
+		}
 	}
 
 	fclose(f);
 
-	/* Build tuple descriptor for our result type */
-	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
-		ereport(ERROR,
-				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("function returning record called in context "
-						"that cannot accept a record")));
-
-	/* Build the result tuple */
-	values[0] = Int64GetDatum(rss_anon_kb >= 0 ? rss_anon_kb * 1024 : 0);
-	values[1] = Int64GetDatum(rss_file_kb >= 0 ? rss_file_kb * 1024 : 0);
-	values[2] = Int64GetDatum(rss_shmem_kb >= 0 ? rss_shmem_kb * 1024 : 0);
-	values[3] = Int64GetDatum(vm_size_kb >= 0 ? vm_size_kb * 1024 : 0);
-
-	nulls[0] = nulls[1] = nulls[2] = nulls[3] = false;
+	result = rss_kb >= 0 ? mul_size(rss_kb, 1024) : 0;
+	result = add_size(result, swap_kb >= 0 ? mul_size(swap_kb, 1024) : 0);
 
-	tuple = heap_form_tuple(tupdesc, values, nulls);
-	PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
+	PG_RETURN_INT64(result);
 }
 
 /*
diff --git a/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl b/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl
index 6d45b1eccdc..a172cd0fd19 100644
--- a/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl
+++ b/src/test/modules/resizable_shmem/t/001_resizable_shmem.pl
@@ -19,7 +19,7 @@ sub check_shmem_usage
 {
 	my ($session, $label, $node) = @_;
 
-	my $rss_shmem = $session->query_safe('SELECT rss_shmem FROM resizable_shmem_usage();',
+	my $rss_shmem = $session->query_safe('SELECT resizable_shmem_usage();',
 										 verbose => 0);
 	my $total_alloc = $node->safe_psql('postgres',
 									   "SELECT sum(allocated_size) FROM pg_shmem_allocations;");
-- 
2.34.1

