Skip to content

Commit a9c546a

Browse files
committed
Use ProcNumbers instead of direct Latch pointers to address other procs
This is in preparation for replacing Latches with a new abstraction. That's still work in progress, but this seems a little tidier anyway, so let's get this refactoring out of the way already. Discussion: https://www.postgresql.org/message-id/391abe21-413e-4d91-a650-b663af49500c%40iki.fi
1 parent e819bbb commit a9c546a

File tree

11 files changed

+72
-55
lines changed

11 files changed

+72
-55
lines changed

src/backend/access/transam/xlog.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,8 +2671,14 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
26712671
wakeup = true;
26722672
}
26732673

2674-
if (wakeup && ProcGlobal->walwriterLatch)
2675-
SetLatch(ProcGlobal->walwriterLatch);
2674+
if (wakeup)
2675+
{
2676+
volatile PROC_HDR *procglobal = ProcGlobal;
2677+
ProcNumber walwriterProc = procglobal->walwriterProc;
2678+
2679+
if (walwriterProc != INVALID_PROC_NUMBER)
2680+
SetLatch(&GetPGProcByNumber(walwriterProc)->procLatch);
2681+
}
26762682
}
26772683

26782684
/*

src/backend/access/transam/xlogwait.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ addLSNWaiter(XLogRecPtr lsn)
112112

113113
Assert(!procInfo->inHeap);
114114

115-
procInfo->latch = MyLatch;
115+
procInfo->procno = MyProcNumber;
116116
procInfo->waitLSN = lsn;
117117

118118
pairingheap_add(&waitLSNState->waitersHeap, &procInfo->phNode);
@@ -154,16 +154,17 @@ void
154154
WaitLSNSetLatches(XLogRecPtr currentLSN)
155155
{
156156
int i;
157-
Latch **wakeUpProcLatches;
157+
ProcNumber *wakeUpProcs;
158158
int numWakeUpProcs = 0;
159159

160-
wakeUpProcLatches = palloc(sizeof(Latch *) * MaxBackends);
160+
wakeUpProcs = palloc(sizeof(ProcNumber) * MaxBackends);
161161

162162
LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
163163

164164
/*
165165
* Iterate the pairing heap of waiting processes till we find LSN not yet
166-
* replayed. Record the process latches to set them later.
166+
* replayed. Record the process numbers to wake up, but to avoid holding
167+
* the lock for too long, send the wakeups only after releasing the lock.
167168
*/
168169
while (!pairingheap_is_empty(&waitLSNState->waitersHeap))
169170
{
@@ -174,7 +175,7 @@ WaitLSNSetLatches(XLogRecPtr currentLSN)
174175
procInfo->waitLSN > currentLSN)
175176
break;
176177

177-
wakeUpProcLatches[numWakeUpProcs++] = procInfo->latch;
178+
wakeUpProcs[numWakeUpProcs++] = procInfo->procno;
178179
(void) pairingheap_remove_first(&waitLSNState->waitersHeap);
179180
procInfo->inHeap = false;
180181
}
@@ -191,9 +192,9 @@ WaitLSNSetLatches(XLogRecPtr currentLSN)
191192
*/
192193
for (i = 0; i < numWakeUpProcs; i++)
193194
{
194-
SetLatch(wakeUpProcLatches[i]);
195+
SetLatch(&GetPGProcByNumber(wakeUpProcs[i])->procLatch);
195196
}
196-
pfree(wakeUpProcLatches);
197+
pfree(wakeUpProcs);
197198
}
198199

199200
/*

src/backend/postmaster/checkpointer.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@ CheckpointerMain(char *startup_data, size_t startup_data_len)
324324
UpdateSharedMemoryConfig();
325325

326326
/*
327-
* Advertise our latch that backends can use to wake us up while we're
328-
* sleeping.
327+
* Advertise our proc number that backends can use to wake us up while
328+
* we're sleeping.
329329
*/
330-
ProcGlobal->checkpointerLatch = &MyProc->procLatch;
330+
ProcGlobal->checkpointerProc = MyProcNumber;
331331

332332
/*
333333
* Loop forever
@@ -1139,8 +1139,14 @@ ForwardSyncRequest(const FileTag *ftag, SyncRequestType type)
11391139
LWLockRelease(CheckpointerCommLock);
11401140

11411141
/* ... but not till after we release the lock */
1142-
if (too_full && ProcGlobal->checkpointerLatch)
1143-
SetLatch(ProcGlobal->checkpointerLatch);
1142+
if (too_full)
1143+
{
1144+
volatile PROC_HDR *procglobal = ProcGlobal;
1145+
ProcNumber checkpointerProc = procglobal->checkpointerProc;
1146+
1147+
if (checkpointerProc != INVALID_PROC_NUMBER)
1148+
SetLatch(&GetPGProcByNumber(checkpointerProc)->procLatch);
1149+
}
11441150

11451151
return true;
11461152
}

src/backend/postmaster/walwriter.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,10 @@ WalWriterMain(char *startup_data, size_t startup_data_len)
208208
SetWalWriterSleeping(false);
209209

210210
/*
211-
* Advertise our latch that backends can use to wake us up while we're
212-
* sleeping.
211+
* Advertise our proc number that backends can use to wake us up while
212+
* we're sleeping.
213213
*/
214-
ProcGlobal->walwriterLatch = &MyProc->procLatch;
214+
ProcGlobal->walwriterProc = MyProcNumber;
215215

216216
/*
217217
* Loop forever

src/backend/replication/libpqwalreceiver/libpqwalreceiver.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "pgstat.h"
3131
#include "pqexpbuffer.h"
3232
#include "replication/walreceiver.h"
33+
#include "storage/latch.h"
3334
#include "utils/builtins.h"
3435
#include "utils/memutils.h"
3536
#include "utils/pg_lsn.h"

src/backend/replication/walreceiver.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ WalReceiverMain(char *startup_data, size_t startup_data_len)
266266
walrcv->lastMsgSendTime =
267267
walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = now;
268268

269-
/* Report the latch to use to awaken this process */
270-
walrcv->latch = &MyProc->procLatch;
269+
/* Report our proc number so that others can wake us up */
270+
walrcv->procno = MyProcNumber;
271271

272272
SpinLockRelease(&walrcv->mutex);
273273

@@ -819,8 +819,8 @@ WalRcvDie(int code, Datum arg)
819819
Assert(walrcv->pid == MyProcPid);
820820
walrcv->walRcvState = WALRCV_STOPPED;
821821
walrcv->pid = 0;
822+
walrcv->procno = INVALID_PROC_NUMBER;
822823
walrcv->ready_to_display = false;
823-
walrcv->latch = NULL;
824824
SpinLockRelease(&walrcv->mutex);
825825

826826
ConditionVariableBroadcast(&walrcv->walRcvStoppedCV);
@@ -1358,15 +1358,15 @@ WalRcvComputeNextWakeup(WalRcvWakeupReason reason, TimestampTz now)
13581358
void
13591359
WalRcvForceReply(void)
13601360
{
1361-
Latch *latch;
1361+
ProcNumber procno;
13621362

13631363
WalRcv->force_reply = true;
1364-
/* fetching the latch pointer might not be atomic, so use spinlock */
1364+
/* fetching the proc number is probably atomic, but don't rely on it */
13651365
SpinLockAcquire(&WalRcv->mutex);
1366-
latch = WalRcv->latch;
1366+
procno = WalRcv->procno;
13671367
SpinLockRelease(&WalRcv->mutex);
1368-
if (latch)
1369-
SetLatch(latch);
1368+
if (procno != INVALID_PROC_NUMBER)
1369+
SetLatch(&GetPGProcByNumber(procno)->procLatch);
13701370
}
13711371

13721372
/*

src/backend/replication/walreceiverfuncs.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "pgstat.h"
2828
#include "replication/walreceiver.h"
2929
#include "storage/pmsignal.h"
30+
#include "storage/proc.h"
3031
#include "storage/shmem.h"
3132
#include "utils/timestamp.h"
3233

@@ -66,7 +67,7 @@ WalRcvShmemInit(void)
6667
ConditionVariableInit(&WalRcv->walRcvStoppedCV);
6768
SpinLockInit(&WalRcv->mutex);
6869
pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
69-
WalRcv->latch = NULL;
70+
WalRcv->procno = INVALID_PROC_NUMBER;
7071
}
7172
}
7273

@@ -248,7 +249,7 @@ RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo,
248249
WalRcvData *walrcv = WalRcv;
249250
bool launch = false;
250251
pg_time_t now = (pg_time_t) time(NULL);
251-
Latch *latch;
252+
ProcNumber walrcv_proc;
252253

253254
/*
254255
* We always start at the beginning of the segment. That prevents a broken
@@ -309,14 +310,14 @@ RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo,
309310
walrcv->receiveStart = recptr;
310311
walrcv->receiveStartTLI = tli;
311312

312-
latch = walrcv->latch;
313+
walrcv_proc = walrcv->procno;
313314

314315
SpinLockRelease(&walrcv->mutex);
315316

316317
if (launch)
317318
SendPostmasterSignal(PMSIGNAL_START_WALRECEIVER);
318-
else if (latch)
319-
SetLatch(latch);
319+
else if (walrcv_proc != INVALID_PROC_NUMBER)
320+
SetLatch(&GetPGProcByNumber(walrcv_proc)->procLatch);
320321
}
321322

322323
/*

src/backend/storage/lmgr/proc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ InitProcGlobal(void)
194194
dlist_init(&ProcGlobal->bgworkerFreeProcs);
195195
dlist_init(&ProcGlobal->walsenderFreeProcs);
196196
ProcGlobal->startupBufferPinWaitBufId = -1;
197-
ProcGlobal->walwriterLatch = NULL;
198-
ProcGlobal->checkpointerLatch = NULL;
197+
ProcGlobal->walwriterProc = INVALID_PROC_NUMBER;
198+
ProcGlobal->checkpointerProc = INVALID_PROC_NUMBER;
199199
pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER);
200200
pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
201201

src/include/access/xlogwait.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "lib/pairingheap.h"
1616
#include "postgres.h"
1717
#include "port/atomics.h"
18-
#include "storage/latch.h"
18+
#include "storage/procnumber.h"
1919
#include "storage/spin.h"
2020
#include "tcop/dest.h"
2121

@@ -29,11 +29,8 @@ typedef struct WaitLSNProcInfo
2929
/* LSN, which this process is waiting for */
3030
XLogRecPtr waitLSN;
3131

32-
/*
33-
* A pointer to the latch, which should be set once the waitLSN is
34-
* replayed.
35-
*/
36-
Latch *latch;
32+
/* Process to wake up once the waitLSN is replayed */
33+
ProcNumber procno;
3734

3835
/* A pairing heap node for participation in waitLSNState->waitersHeap */
3936
pairingheap_node phNode;

src/include/replication/walreceiver.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "replication/logicalproto.h"
2222
#include "replication/walsender.h"
2323
#include "storage/condition_variable.h"
24-
#include "storage/latch.h"
2524
#include "storage/spin.h"
2625
#include "utils/tuplestore.h"
2726

@@ -58,13 +57,24 @@ typedef enum
5857
typedef struct
5958
{
6059
/*
61-
* PID of currently active walreceiver process, its current state and
62-
* start time (actually, the time at which it was requested to be
63-
* started).
60+
* Currently active walreceiver process's proc number and PID.
61+
*
62+
* The startup process uses the proc number to wake it up after telling it
63+
* where to start streaming (after setting receiveStart and
64+
* receiveStartTLI), and also to tell it to send apply feedback to the
65+
* primary whenever specially marked commit records are applied.
6466
*/
67+
ProcNumber procno;
6568
pid_t pid;
69+
70+
/* Its current state */
6671
WalRcvState walRcvState;
6772
ConditionVariable walRcvStoppedCV;
73+
74+
/*
75+
* Its start time (actually, the time at which it was requested to be
76+
* started).
77+
*/
6878
pg_time_t startTime;
6979

7080
/*
@@ -134,15 +144,6 @@ typedef struct
134144
/* set true once conninfo is ready to display (obfuscated pwds etc) */
135145
bool ready_to_display;
136146

137-
/*
138-
* Latch used by startup process to wake up walreceiver after telling it
139-
* where to start streaming (after setting receiveStart and
140-
* receiveStartTLI), and also to tell it to send apply feedback to the
141-
* primary whenever specially marked commit records are applied. This is
142-
* normally mapped to procLatch when walreceiver is running.
143-
*/
144-
Latch *latch;
145-
146147
slock_t mutex; /* locks shared variables shown above */
147148

148149
/*

src/include/storage/proc.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,10 +418,14 @@ typedef struct PROC_HDR
418418
pg_atomic_uint32 procArrayGroupFirst;
419419
/* First pgproc waiting for group transaction status update */
420420
pg_atomic_uint32 clogGroupFirst;
421-
/* WALWriter process's latch */
422-
Latch *walwriterLatch;
423-
/* Checkpointer process's latch */
424-
Latch *checkpointerLatch;
421+
422+
/*
423+
* Current slot numbers of some auxiliary processes. There can be only one
424+
* of each of these running at a time.
425+
*/
426+
ProcNumber walwriterProc;
427+
ProcNumber checkpointerProc;
428+
425429
/* Current shared estimate of appropriate spins_per_delay value */
426430
int spins_per_delay;
427431
/* Buffer id of the buffer that Startup process waits for pin on, or -1 */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy