From 4aea1eb60fad306e172ce7acc834f417a9d8468d Mon Sep 17 00:00:00 2001
From: Jianghua Yang <yjhjstz@gmail.com>
Date: Thu, 27 Mar 2025 07:48:43 +0800
Subject: [PATCH] Add optional support for CLOCK_MONOTONIC_COARSE via configure
 switch

This patch introduces a new configure option --with-clock-monotonic-coarse
that allows users to build PostgreSQL with CLOCK_MONOTONIC_COARSE as the
default clock source for PG_INSTR_CLOCK, if available.

This can improve performance for some code paths where high precision
timing is not critical, at the cost of reduced timing resolution.

The default behavior remains unchanged unless the new configure option is
explicitly specified.
---
 configure.ac                         | 20 ++++++++++++++++++++
 src/include/pg_config.h.in           |  3 +++
 src/include/portability/instr_time.h | 22 +++++++++++++++++-----
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 82b46401931..46105377361 100644
--- a/configure.ac
+++ b/configure.ac
@@ -230,6 +230,26 @@ if test -z "$GENHTML"; then
 fi])
 AC_SUBST(enable_coverage)
 
+AC_ARG_WITH([clock-monotonic-coarse],
+  [AS_HELP_STRING([--with-clock-monotonic-coarse], [use CLOCK_MONOTONIC_COARSE for PG_INSTR_CLOCK if available])],
+  [use_clock_monotonic_coarse=yes],
+  [use_clock_monotonic_coarse=auto])
+
+if test "$use_clock_monotonic_coarse" = yes || test "$use_clock_monotonic_coarse" = auto; then
+  AC_MSG_CHECKING([for CLOCK_MONOTONIC_COARSE])
+  AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([#include <time.h>], [(void)CLOCK_MONOTONIC_COARSE;])],
+    [have_clock_monotonic_coarse=yes],
+    [have_clock_monotonic_coarse=no])
+  AC_MSG_RESULT([$have_clock_monotonic_coarse])
+
+  if test "$have_clock_monotonic_coarse" = yes; then
+    AC_DEFINE([USE_CLOCK_MONOTONIC_COARSE], 1, [Define to use CLOCK_MONOTONIC_COARSE if available])
+  elif test "$use_clock_monotonic_coarse" = yes; then
+    AC_MSG_ERROR([--with-clock-monotonic-coarse was specified, but CLOCK_MONOTONIC_COARSE is not available])
+  fi
+fi
+
 #
 # DTrace
 #
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 2397d90b465..49ad76f4fca 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -695,6 +695,9 @@
 /* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */
 #undef USE_BSD_AUTH
 
+/* Define to use CLOCK_MONOTONIC_COARSE if available */
+#undef USE_CLOCK_MONOTONIC_COARSE
+
 /* Define to build with ICU support. (--with-icu) */
 #undef USE_ICU
 
diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h
index a6fc1922f20..a9fc71b186a 100644
--- a/src/include/portability/instr_time.h
+++ b/src/include/portability/instr_time.h
@@ -98,12 +98,24 @@ typedef struct instr_time
  * CLOCK_MONOTONIC_RAW which is both faster to read and higher resolution than
  * their version of CLOCK_MONOTONIC.
  */
-#if defined(__darwin__) && defined(CLOCK_MONOTONIC_RAW)
-#define PG_INSTR_CLOCK	CLOCK_MONOTONIC_RAW
-#elif defined(CLOCK_MONOTONIC)
-#define PG_INSTR_CLOCK	CLOCK_MONOTONIC
+#ifdef USE_CLOCK_MONOTONIC_COARSE
+  #ifdef CLOCK_MONOTONIC_COARSE
+    #define PG_INSTR_CLOCK CLOCK_MONOTONIC_COARSE
+  #elif defined(__darwin__) && defined(CLOCK_MONOTONIC_RAW)
+    #define PG_INSTR_CLOCK CLOCK_MONOTONIC_RAW
+  #elif defined(CLOCK_MONOTONIC)
+    #define PG_INSTR_CLOCK CLOCK_MONOTONIC
+  #else
+    #define PG_INSTR_CLOCK CLOCK_REALTIME
+  #endif
 #else
-#define PG_INSTR_CLOCK	CLOCK_REALTIME
+  #if defined(__darwin__) && defined(CLOCK_MONOTONIC_RAW)
+    #define PG_INSTR_CLOCK CLOCK_MONOTONIC_RAW
+  #elif defined(CLOCK_MONOTONIC)
+    #define PG_INSTR_CLOCK CLOCK_MONOTONIC
+  #else
+    #define PG_INSTR_CLOCK CLOCK_REALTIME
+  #endif
 #endif
 
 /* helper for INSTR_TIME_SET_CURRENT */
-- 
2.25.1

