v11-0002-Refactor-how-some-aux-processes-advertise-their-.patch
text/x-patch
Filename: v11-0002-Refactor-how-some-aux-processes-advertise-their-.patch
Type: text/x-patch
Part: 1
Message:
Re: Interrupts vs signals
Patch
Format: format-patch
Series: patch v11-0002
Subject: Refactor how some aux processes advertise their ProcNumber
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 1 | 2 |
| src/backend/postmaster/autovacuum.c | 10 | 9 |
| src/backend/postmaster/checkpointer.c | 4 | 10 |
| src/backend/postmaster/walwriter.c | 0 | 6 |
| src/backend/storage/lmgr/proc.c | 28 | 2 |
| src/include/storage/proc.h | 4 | 3 |
From 6dd10bba54c2f7bae7ea7bcaa7981d8a8c0a0eb6 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Fri, 13 Feb 2026 14:23:35 +0200
Subject: [PATCH v11 2/4] Refactor how some aux processes advertise their
ProcNumber
This moves the responsibility of setting the
ProcGlobal->walrewriterProc and checkpointerProc fields to
InitAuxiliaryProcess. Also switch to the same pattern to advertise the
autovacuum launcher's ProcNumber, replacing the ad hoc av_launcherpid
field in shared memory. This can easily be extended to other aux
processes in the future, if other processes need to find them.
Switch to pg_atomic_uint32 for the fields. Seems easier to reason
about than volatile pointers. There was some precedence for that, as
were already using pg_atomic_uint32 for the procArrayGroupFirst and
clogGroupFirst fields, which also store ProcNumbers.
TODO: could also replace WalRecv->procno with this
---
src/backend/access/transam/xlog.c | 3 +--
src/backend/postmaster/autovacuum.c | 19 +++++++++--------
src/backend/postmaster/checkpointer.c | 14 ++++---------
src/backend/postmaster/walwriter.c | 6 ------
src/backend/storage/lmgr/proc.c | 30 +++++++++++++++++++++++++--
src/include/storage/proc.h | 7 ++++---
6 files changed, 47 insertions(+), 32 deletions(-)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 13cce9b49f1..d12b1c02f3a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2653,8 +2653,7 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
if (wakeup)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
- ProcNumber walwriterProc = procglobal->walwriterProc;
+ ProcNumber walwriterProc = pg_atomic_read_u32(&ProcGlobal->walwriterProc);
if (walwriterProc != INVALID_PROC_NUMBER)
SetLatch(&GetPGProcByNumber(walwriterProc)->procLatch);
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 89c2b4f9500..0a730fb5b45 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -277,7 +277,6 @@ typedef struct AutoVacuumWorkItem
* struct and the array of WorkerInfo structs. This struct keeps:
*
* av_signal set by other processes to indicate various conditions
- * av_launcherpid the PID of the autovacuum launcher
* av_freeWorkers the WorkerInfo freelist
* av_runningWorkers the WorkerInfo non-free queue
* av_startingWorker pointer to WorkerInfo currently being started (cleared by
@@ -293,7 +292,6 @@ typedef struct AutoVacuumWorkItem
typedef struct
{
sig_atomic_t av_signal[AutoVacNumSignals];
- pid_t av_launcherpid;
dclist_head av_freeWorkers;
dlist_head av_runningWorkers;
WorkerInfo av_startingWorker;
@@ -563,8 +561,6 @@ AutoVacLauncherMain(const void *startup_data, size_t startup_data_len)
proc_exit(0); /* done */
}
- AutoVacuumShmem->av_launcherpid = MyProcPid;
-
/*
* Create the initial database list. The invariant we want this list to
* keep is that it's ordered by decreasing next_worker. As soon as an
@@ -798,8 +794,6 @@ AutoVacLauncherShutdown(void)
{
ereport(DEBUG1,
(errmsg_internal("autovacuum launcher shutting down")));
- AutoVacuumShmem->av_launcherpid = 0;
-
proc_exit(0); /* done */
}
@@ -1529,6 +1523,8 @@ AutoVacWorkerMain(const void *startup_data, size_t startup_data_len)
*/
if (AutoVacuumShmem->av_startingWorker != NULL)
{
+ ProcNumber launcherProc;
+
MyWorkerInfo = AutoVacuumShmem->av_startingWorker;
dbid = MyWorkerInfo->wi_dboid;
MyWorkerInfo->wi_proc = MyProc;
@@ -1547,8 +1543,14 @@ AutoVacWorkerMain(const void *startup_data, size_t startup_data_len)
on_shmem_exit(FreeWorkerInfo, 0);
/* wake up the launcher */
- if (AutoVacuumShmem->av_launcherpid != 0)
- kill(AutoVacuumShmem->av_launcherpid, SIGUSR2);
+ launcherProc = pg_atomic_read_u32(&ProcGlobal->avLauncherProc);
+ if (launcherProc != INVALID_PROC_NUMBER)
+ {
+ int pid = GetPGProcByNumber(launcherProc)->pid;
+
+ if (pid != 0)
+ kill(pid, SIGUSR2);
+ }
}
else
{
@@ -3391,7 +3393,6 @@ AutoVacuumShmemInit(void)
Assert(!found);
- AutoVacuumShmem->av_launcherpid = 0;
dclist_init(&AutoVacuumShmem->av_freeWorkers);
dlist_init(&AutoVacuumShmem->av_runningWorkers);
AutoVacuumShmem->av_startingWorker = NULL;
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 03aefa5b670..978a7d0e649 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -47,6 +47,7 @@
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "port/atomics.h"
#include "postmaster/auxprocess.h"
#include "postmaster/bgwriter.h"
#include "postmaster/interrupt.h"
@@ -343,12 +344,6 @@ CheckpointerMain(const void *startup_data, size_t startup_data_len)
*/
UpdateSharedMemoryConfig();
- /*
- * Advertise our proc number that backends can use to wake us up while
- * we're sleeping.
- */
- ProcGlobal->checkpointerProc = MyProcNumber;
-
/*
* Loop until we've been asked to write the shutdown checkpoint or
* terminate.
@@ -1120,7 +1115,7 @@ RequestCheckpoint(int flags)
for (ntries = 0;; ntries++)
{
volatile PROC_HDR *procglobal = ProcGlobal;
- ProcNumber checkpointerProc = procglobal->checkpointerProc;
+ ProcNumber checkpointerProc = pg_atomic_read_u32(&procglobal->checkpointerProc);
if (checkpointerProc == INVALID_PROC_NUMBER)
{
@@ -1261,8 +1256,7 @@ ForwardSyncRequest(const FileTag *ftag, SyncRequestType type)
/* ... but not till after we release the lock */
if (too_full)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
- ProcNumber checkpointerProc = procglobal->checkpointerProc;
+ ProcNumber checkpointerProc = pg_atomic_read_u32(&ProcGlobal->checkpointerProc);
if (checkpointerProc != INVALID_PROC_NUMBER)
SetLatch(&GetPGProcByNumber(checkpointerProc)->procLatch);
@@ -1543,7 +1537,7 @@ void
WakeupCheckpointer(void)
{
volatile PROC_HDR *procglobal = ProcGlobal;
- ProcNumber checkpointerProc = procglobal->checkpointerProc;
+ ProcNumber checkpointerProc = pg_atomic_read_u32(&procglobal->checkpointerProc);
if (checkpointerProc != INVALID_PROC_NUMBER)
SetLatch(&GetPGProcByNumber(checkpointerProc)->procLatch);
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 8ca7b07e947..1851417ad1b 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -200,12 +200,6 @@ WalWriterMain(const void *startup_data, size_t startup_data_len)
hibernating = false;
SetWalWriterSleeping(false);
- /*
- * Advertise our proc number that backends can use to wake us up while
- * we're sleeping.
- */
- ProcGlobal->walwriterProc = MyProcNumber;
-
/*
* Loop forever
*/
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index fd8318bdf3d..ba7eaed1a13 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -211,8 +211,9 @@ InitProcGlobal(void)
dlist_init(&ProcGlobal->bgworkerFreeProcs);
dlist_init(&ProcGlobal->walsenderFreeProcs);
ProcGlobal->startupBufferPinWaitBufId = -1;
- ProcGlobal->walwriterProc = INVALID_PROC_NUMBER;
- ProcGlobal->checkpointerProc = INVALID_PROC_NUMBER;
+ pg_atomic_init_u32(&ProcGlobal->avLauncherProc, INVALID_PROC_NUMBER);
+ pg_atomic_init_u32(&ProcGlobal->walwriterProc, INVALID_PROC_NUMBER);
+ pg_atomic_init_u32(&ProcGlobal->checkpointerProc, INVALID_PROC_NUMBER);
pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER);
pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
@@ -709,6 +710,14 @@ InitAuxiliaryProcess(void)
*/
PGSemaphoreReset(MyProc->sem);
+ /* Some aux processes are also advertised in ProcGlobal */
+ if (MyBackendType == B_AUTOVAC_LAUNCHER)
+ pg_atomic_write_u32(&ProcGlobal->avLauncherProc, MyProcNumber);
+ if (MyBackendType == B_WAL_WRITER)
+ pg_atomic_write_u32(&ProcGlobal->walwriterProc, MyProcNumber);
+ if (MyBackendType == B_CHECKPOINTER)
+ pg_atomic_write_u32(&ProcGlobal->checkpointerProc, MyProcNumber);
+
/*
* Arrange to clean up at process exit.
*/
@@ -1053,6 +1062,23 @@ AuxiliaryProcKill(int code, Datum arg)
SwitchBackToLocalLatch();
pgstat_reset_wait_event_storage();
+ /* If this was one of aux processes advertised in ProcGlobal, clear it */
+ if (MyBackendType == B_AUTOVAC_LAUNCHER)
+ {
+ Assert(pg_atomic_read_u32(&ProcGlobal->avLauncherProc) == MyProcNumber);
+ pg_atomic_write_u32(&ProcGlobal->avLauncherProc, INVALID_PROC_NUMBER);
+ }
+ if (MyBackendType == B_WAL_WRITER)
+ {
+ Assert(pg_atomic_read_u32(&ProcGlobal->walwriterProc) == MyProcNumber);
+ pg_atomic_write_u32(&ProcGlobal->walwriterProc, INVALID_PROC_NUMBER);
+ }
+ if (MyBackendType == B_CHECKPOINTER)
+ {
+ Assert(pg_atomic_read_u32(&ProcGlobal->checkpointerProc) == MyProcNumber);
+ pg_atomic_write_u32(&ProcGlobal->checkpointerProc, INVALID_PROC_NUMBER);
+ }
+
proc = MyProc;
MyProc = NULL;
MyProcNumber = INVALID_PROC_NUMBER;
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 23e5cd98161..1f1ab7d02ca 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -445,11 +445,12 @@ typedef struct PROC_HDR
pg_atomic_uint32 clogGroupFirst;
/*
- * Current slot numbers of some auxiliary processes. There can be only one
+ * Current proc numbers of some auxiliary processes. There can be only one
* of each of these running at a time.
*/
- ProcNumber walwriterProc;
- ProcNumber checkpointerProc;
+ pg_atomic_uint32 avLauncherProc;
+ pg_atomic_uint32 walwriterProc;
+ pg_atomic_uint32 checkpointerProc;
/* Current shared estimate of appropriate spins_per_delay value */
int spins_per_delay;
--
2.47.3