Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)