From 45333e9dabe1e55ccfe8830054b202e4182bb6ef Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sun, 1 Feb 2026 14:41:39 +0700
Subject: [PATCH v7 4/5] Test module for popcount plus bitmapset RDTSC

---
 src/test/modules/Makefile                     |   1 +
 src/test/modules/test_popcount/Makefile       |  21 ++++
 .../test_popcount/test_popcount--1.0.sql      |   3 +
 .../modules/test_popcount/test_popcount.c     | 108 ++++++++++++++++++
 .../test_popcount/test_popcount.control       |   4 +
 5 files changed, 137 insertions(+)
 create mode 100644 src/test/modules/test_popcount/Makefile
 create mode 100644 src/test/modules/test_popcount/test_popcount--1.0.sql
 create mode 100644 src/test/modules/test_popcount/test_popcount.c
 create mode 100644 src/test/modules/test_popcount/test_popcount.control

diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index 44c7163c1cd..db6bfaec026 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -5,6 +5,7 @@ top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
 SUBDIRS = \
+		  test_popcount \
 		  brin \
 		  commit_ts \
 		  delay_execution \
diff --git a/src/test/modules/test_popcount/Makefile b/src/test/modules/test_popcount/Makefile
new file mode 100644
index 00000000000..8a49d1ccfc8
--- /dev/null
+++ b/src/test/modules/test_popcount/Makefile
@@ -0,0 +1,21 @@
+MODULE_big = test_popcount
+OBJS = test_popcount.o
+PGFILEDESC = "test"
+EXTENSION = test_popcount
+DATA = test_popcount--1.0.sql
+
+first: all
+
+# needed?
+test_popcount.o: test_popcount.c
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_popcount
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_popcount/test_popcount--1.0.sql b/src/test/modules/test_popcount/test_popcount--1.0.sql
new file mode 100644
index 00000000000..51896eb751c
--- /dev/null
+++ b/src/test/modules/test_popcount/test_popcount--1.0.sql
@@ -0,0 +1,3 @@
+CREATE FUNCTION drive_popcount  (count int, num int) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C;
+CREATE FUNCTION drive_popcount64(count int, num int) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C;
+CREATE FUNCTION drive_bms_num_members(count int, num int) RETURNS float8 AS 'MODULE_PATHNAME' LANGUAGE C;
diff --git a/src/test/modules/test_popcount/test_popcount.c b/src/test/modules/test_popcount/test_popcount.c
new file mode 100644
index 00000000000..5da1ffae188
--- /dev/null
+++ b/src/test/modules/test_popcount/test_popcount.c
@@ -0,0 +1,108 @@
+/* select drive_popcount(1000000, 1024); */
+
+#include <x86intrin.h>
+
+#include "postgres.h"
+
+#include "fmgr.h"
+
+#include "port/pg_bitutils.h"
+#include "nodes/bitmapset.h"
+
+PG_MODULE_MAGIC;
+
+#ifndef PG_POPCOUNT64
+#define PG_POPCOUNT32(word) pg_popcount32(word)
+#define PG_POPCOUNT64(word) pg_popcount64(word)
+#endif
+
+
+/*
+ * drive_popcount64(count int, num int) returns bigint
+ *
+ * num is the number of 64-bit words to use
+ */
+PG_FUNCTION_INFO_V1(drive_popcount64);
+Datum
+drive_popcount64(PG_FUNCTION_ARGS)
+{
+
+	int			count = PG_GETARG_INT32(0);
+	int			num   = PG_GETARG_INT32(1);
+
+	int			len = num * sizeof(uint64);
+	uint64 	   *words	= palloc(len);
+	int64		popcount = 0;
+
+	for (int i = 0; i < num; i++)
+		words[i] = i;
+
+	while (count--)
+	{
+		popcount = 0;
+		for (int i = 0; i < num; i++)
+			popcount += PG_POPCOUNT64(words[i]);
+	}
+
+	PG_RETURN_INT64(popcount);
+}
+
+/*
+ * drive_popcount(count int, len int) returns bigint
+ *
+ * num is the number of 64-bit words to use
+ */
+PG_FUNCTION_INFO_V1(drive_popcount);
+Datum
+drive_popcount(PG_FUNCTION_ARGS)
+{
+
+	int			count = PG_GETARG_INT32(0);
+	int			num   = PG_GETARG_INT32(1);
+
+	int			len = num * sizeof(uint64);
+	uint64	   *words	= palloc(len);
+	int64		popcount = 0;
+
+	for (int i = 0; i < num; i++)
+		words[i] = i;
+
+	while (count--)
+		popcount = pg_popcount((const char*) words, len);
+
+	PG_RETURN_INT64(popcount);
+}
+
+/*
+ * drive_bms_num_members(count int, len int) returns bigint
+ *
+ * num is the number of bitmap words to use
+ */
+PG_FUNCTION_INFO_V1(drive_bms_num_members);
+Datum
+drive_bms_num_members(PG_FUNCTION_ARGS)
+{
+
+	const int			count = PG_GETARG_INT32(0);
+	int countdown = count;
+	int			num   = PG_GETARG_INT32(1);
+	Bitmapset * b;
+	uint64_t start, finish;
+	double ticks = 0;
+
+	b = bms_make_singleton(1);
+	for (int i=0; i < num * BITS_PER_BITMAPWORD; i++)
+		b = bms_add_member(b, i);
+
+	start = __rdtsc();
+	while (countdown--)
+	{
+		bms_num_members(b);
+	}
+	finish = __rdtsc();
+	ticks += finish - start;
+
+	bms_free(b);
+
+	PG_RETURN_FLOAT8(ticks / count);
+}
diff --git a/src/test/modules/test_popcount/test_popcount.control b/src/test/modules/test_popcount/test_popcount.control
new file mode 100644
index 00000000000..6837d724b4d
--- /dev/null
+++ b/src/test/modules/test_popcount/test_popcount.control
@@ -0,0 +1,4 @@
+comment = 'test'
+default_version = '1.0'
+module_pathname = '$libdir/test_popcount'
+relocatable = true
-- 
2.52.0

