v3-0003-Add-GUC.patch
text/x-patch
Filename: v3-0003-Add-GUC.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v3-0003
Subject: Add GUC
| File | + | − |
|---|---|---|
| src/backend/postmaster/postmaster.c | 11 | 0 |
| src/backend/tcop/postgres.c | 11 | 0 |
| src/backend/utils/init/postinit.c | 0 | 3 |
| src/backend/utils/misc/guc_parameters.dat | 7 | 0 |
| src/backend/utils/misc/guc_tables.c | 10 | 0 |
| src/bin/pgbench/pgbench.c | 1 | 1 |
| src/bin/pg_test_timing/pg_test_timing.c | 1 | 1 |
| src/bin/psql/startup.c | 1 | 1 |
| src/common/instr_time.c | 11 | 0 |
| src/include/portability/instr_time.h | 15 | 12 |
| src/include/utils/guc_tables.h | 1 | 0 |
From 1b9f9b97d5ca74532620cb51c8f8beb23500537f Mon Sep 17 00:00:00 2001
From: David Geier <geidav.pg@gmail.com>
Date: Fri, 5 Dec 2025 08:58:18 +0100
Subject: [PATCH v3 3/3] Add GUC
---
src/backend/postmaster/postmaster.c | 11 +++++++++
src/backend/tcop/postgres.c | 11 +++++++++
src/backend/utils/init/postinit.c | 3 ---
src/backend/utils/misc/guc_parameters.dat | 7 ++++++
src/backend/utils/misc/guc_tables.c | 10 +++++++++
src/bin/pg_test_timing/pg_test_timing.c | 2 +-
src/bin/pgbench/pgbench.c | 2 +-
src/bin/psql/startup.c | 2 +-
src/common/instr_time.c | 11 +++++++++
src/include/portability/instr_time.h | 27 +++++++++++++----------
src/include/utils/guc_tables.h | 1 +
11 files changed, 69 insertions(+), 18 deletions(-)
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 921d73226d6..a6dfaf356ee 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1005,6 +1005,17 @@ PostmasterMain(int argc, char *argv[])
*/
CreateSharedMemoryAndSemaphores();
+ /*
+ * Initialize high-precision interval timing.
+ * Raise FATAL error if RDTSC is requested but not available.
+ */
+ INSTR_TIME_INITIALIZE(true);
+
+#if defined(__x86_64__) && defined(__linux__)
+ if (fast_clock_source == FAST_CLOCK_SOURCE_RDTSC && (!has_rdtsc || !has_rdtscp))
+ ereport(FATAL, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("TSC is not supported as fast clock source")));
+#endif
+
/*
* Estimate number of openable files. This must happen after setting up
* semaphores, because on some platforms semaphores count as open files.
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index e54bf1e760f..e882220b9a0 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -4152,6 +4152,17 @@ PostgresSingleUserMain(int argc, char *argv[],
*/
CreateSharedMemoryAndSemaphores();
+ /*
+ * Initialize high-precision interval timing.
+ * Raise FATAL error if RDTSC is requested but not available.
+ */
+ INSTR_TIME_INITIALIZE(true);
+
+#if defined(__x86_64__) && defined(__linux__)
+ if (fast_clock_source == FAST_CLOCK_SOURCE_RDTSC && (!has_rdtsc || !has_rdtscp))
+ ereport(FATAL, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("TSC is not supported as fast clock source")));
+#endif
+
/*
* Estimate number of openable files. This must happen after setting up
* semaphores, because on some platforms semaphores count as open files.
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index c339c35b25d..3f401faf3de 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -809,9 +809,6 @@ InitPostgres(const char *in_dbname, Oid dboid,
/* Initialize portal manager */
EnablePortalManager();
- /* initialize high-precision interval timing */
- INSTR_TIME_INITIALIZE();
-
/*
* Load relcache entries for the shared system catalogs. This must create
* at least entries for pg_database and catalogs used for authentication.
diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat
index 7c60b125564..c68b3ff1184 100644
--- a/src/backend/utils/misc/guc_parameters.dat
+++ b/src/backend/utils/misc/guc_parameters.dat
@@ -1041,6 +1041,13 @@
max => '3',
},
+{ name => 'fast_clock_source', type => 'enum', context => 'PGC_POSTMASTER', group => 'RESOURCES_TIME',
+ short_desc => 'Use of fast clock source.',
+ variable => 'fast_clock_source',
+ boot_val => 'FAST_CLOCK_SOURCE_TRY',
+ options => 'fast_clock_source_options',
+},
+
{ name => 'file_copy_method', type => 'enum', context => 'PGC_USERSET', group => 'RESOURCES_DISK',
short_desc => 'Selects the file copy method.',
variable => 'file_copy_method',
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 73ff6ad0a32..3614aaf1876 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -90,6 +90,7 @@
#include "tcop/tcopprot.h"
#include "tsearch/ts_cache.h"
#include "utils/builtins.h"
+#include "portability/instr_time.h"
#include "utils/bytea.h"
#include "utils/float.h"
#include "utils/guc_hooks.h"
@@ -371,6 +372,15 @@ static const struct config_enum_entry huge_pages_options[] = {
{NULL, 0, false}
};
+static const struct config_enum_entry fast_clock_source_options[] = {
+ {"try", FAST_CLOCK_SOURCE_TRY, false},
+ {"off", FAST_CLOCK_SOURCE_OFF, false},
+#if defined(__x86_64__) && defined(__linux__)
+ {"rdtsc", FAST_CLOCK_SOURCE_RDTSC, false},
+#endif
+ {NULL, 0, false}
+};
+
static const struct config_enum_entry huge_pages_status_options[] = {
{"off", HUGE_PAGES_OFF, false},
{"on", HUGE_PAGES_ON, false},
diff --git a/src/bin/pg_test_timing/pg_test_timing.c b/src/bin/pg_test_timing/pg_test_timing.c
index 62e308dd965..3ffa95769a5 100644
--- a/src/bin/pg_test_timing/pg_test_timing.c
+++ b/src/bin/pg_test_timing/pg_test_timing.c
@@ -174,7 +174,7 @@ test_timing(unsigned int duration, bool fast_timing)
char *time_source = NULL;
bool fast_timing_available = false;
- INSTR_TIME_INITIALIZE();
+ INSTR_TIME_INITIALIZE(true);
#if !defined(WIN32) && defined(__x86_64__) && defined(__linux__)
if (fast_timing && has_rdtsc)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 7b64fdaed34..78e5b40a7bb 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -7335,7 +7335,7 @@ main(int argc, char **argv)
}
/* initialize high-precision interval timing */
- INSTR_TIME_INITIALIZE();
+ INSTR_TIME_INITIALIZE(false);
/* opening connection... */
con = doConnect();
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index a0b3bafe20c..ec8748002d8 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -329,7 +329,7 @@ main(int argc, char *argv[])
PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
/* initialize high-precision interval timing */
- INSTR_TIME_INITIALIZE();
+ INSTR_TIME_INITIALIZE(false);
SyncVariables();
diff --git a/src/common/instr_time.c b/src/common/instr_time.c
index fdf47699f20..02b57edfb9b 100644
--- a/src/common/instr_time.c
+++ b/src/common/instr_time.c
@@ -24,6 +24,17 @@
#include "portability/instr_time.h"
+int fast_clock_source = FAST_CLOCK_SOURCE_TRY;
+
+void
+pg_initialize_timing(bool try_fast)
+{
+#if defined(__x86_64__) && defined(__linux__)
+ if (try_fast)
+ pg_initialize_rdtsc();
+#endif
+}
+
#ifndef WIN32
/*
* Stores what the number of cycles needs to be multiplied with to end up
diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h
index 33e506f3526..22ee991d2c9 100644
--- a/src/include/portability/instr_time.h
+++ b/src/include/portability/instr_time.h
@@ -81,6 +81,14 @@ typedef struct instr_time
#define NS_PER_MS INT64CONST(1000000)
#define NS_PER_US INT64CONST(1000)
+typedef enum
+{
+ FAST_CLOCK_SOURCE_TRY,
+ FAST_CLOCK_SOURCE_OFF,
+ FAST_CLOCK_SOURCE_RDTSC
+} FastClockSourceType;
+
+extern int fast_clock_source;
#ifndef WIN32
@@ -147,7 +155,7 @@ static inline instr_time
pg_get_ticks_fast(void)
{
#if defined(__x86_64__) && defined(__linux__)
- if (has_rdtsc)
+ if (likely(has_rdtsc && fast_clock_source != FAST_CLOCK_SOURCE_OFF))
{
instr_time now;
@@ -163,7 +171,7 @@ static inline instr_time
pg_get_ticks(void)
{
#if defined(__x86_64__) && defined(__linux__)
- if (has_rdtscp)
+ if (likely(has_rdtscp && fast_clock_source != FAST_CLOCK_SOURCE_OFF))
{
instr_time now;
uint32 unused;
@@ -212,16 +220,11 @@ pg_ticks_to_ns(int64 ticks)
return ns;
}
-static inline void
-pg_initialize_get_ticks()
-{
-#if defined(__x86_64__) && defined(__linux__)
- pg_initialize_rdtsc();
-#endif
-}
+extern void
+pg_initialize_timing(bool try_fast);
-#define INSTR_TIME_INITIALIZE() \
- pg_initialize_get_ticks()
+#define INSTR_TIME_INITIALIZE(try_fast) \
+ pg_initialize_timing(try_fast)
#define INSTR_TIME_SET_CURRENT_FAST(t) \
((t) = pg_get_ticks_fast())
@@ -260,7 +263,7 @@ GetTimerFrequency(void)
return (double) f.QuadPart;
}
-#define INSTR_TIME_INITIALIZE()
+#define INSTR_TIME_INITIALIZE(try_fast)
#define INSTR_TIME_SET_CURRENT_FAST(t) \
((t) = pg_query_performance_counter())
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index 71a80161961..63440b8e36c 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -60,6 +60,7 @@ enum config_group
CONN_AUTH_TCP,
CONN_AUTH_AUTH,
CONN_AUTH_SSL,
+ RESOURCES_TIME,
RESOURCES_MEM,
RESOURCES_DISK,
RESOURCES_KERNEL,
--
2.51.0