Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a13db0e

Browse files
committed
Change ProcSendSignal() to take pgprocno.
Instead of referring to target backends by pid, use pgprocno. This means that we don't have to scan the ProcArray and we can drop some special case code for dealing with the startup process. Discussion: https://postgr.es/m/CA%2BhUKGLYRyDaneEwz5Uya_OgFLMx5BgJfkQSD%3Dq9HmwsfRRb-w%40mail.gmail.com Reviewed-by: Soumyadeep Chakraborty <soumyadeep2007@gmail.com> Reviewed-by: Ashwin Agrawal <ashwinstar@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de>
1 parent bbc227e commit a13db0e

File tree

8 files changed

+23
-64
lines changed

8 files changed

+23
-64
lines changed

src/backend/access/transam/xlog.c

-3
Original file line numberDiff line numberDiff line change
@@ -7519,9 +7519,6 @@ StartupXLOG(void)
75197519
/* Also ensure XLogReceiptTime has a sane value */
75207520
XLogReceiptTime = GetCurrentTimestamp();
75217521

7522-
/* Allow ProcSendSignal() to find us, for buffer pin wakeups. */
7523-
PublishStartupProcessInformation();
7524-
75257522
/*
75267523
* Let postmaster know we've started redo now, so that it can launch
75277524
* the archiver if necessary.

src/backend/storage/buffer/buf_init.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "storage/buf_internals.h"
1818
#include "storage/bufmgr.h"
19+
#include "storage/proc.h"
1920

2021
BufferDescPadded *BufferDescriptors;
2122
char *BufferBlocks;
@@ -118,7 +119,7 @@ InitBufferPool(void)
118119
CLEAR_BUFFERTAG(buf->tag);
119120

120121
pg_atomic_init_u32(&buf->state, 0);
121-
buf->wait_backend_pid = 0;
122+
buf->wait_backend_pgprocno = INVALID_PGPROCNO;
122123

123124
buf->buf_id = i;
124125

src/backend/storage/buffer/bufmgr.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -1899,11 +1899,11 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner)
18991899
BUF_STATE_GET_REFCOUNT(buf_state) == 1)
19001900
{
19011901
/* we just released the last pin other than the waiter's */
1902-
int wait_backend_pid = buf->wait_backend_pid;
1902+
int wait_backend_pgprocno = buf->wait_backend_pgprocno;
19031903

19041904
buf_state &= ~BM_PIN_COUNT_WAITER;
19051905
UnlockBufHdr(buf, buf_state);
1906-
ProcSendSignal(wait_backend_pid);
1906+
ProcSendSignal(wait_backend_pgprocno);
19071907
}
19081908
else
19091909
UnlockBufHdr(buf, buf_state);
@@ -3980,7 +3980,7 @@ UnlockBuffers(void)
39803980
* got a cancel/die interrupt before getting the signal.
39813981
*/
39823982
if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
3983-
buf->wait_backend_pid == MyProcPid)
3983+
buf->wait_backend_pgprocno == MyProc->pgprocno)
39843984
buf_state &= ~BM_PIN_COUNT_WAITER;
39853985

39863986
UnlockBufHdr(buf, buf_state);
@@ -4116,7 +4116,7 @@ LockBufferForCleanup(Buffer buffer)
41164116
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
41174117
elog(ERROR, "multiple backends attempting to wait for pincount 1");
41184118
}
4119-
bufHdr->wait_backend_pid = MyProcPid;
4119+
bufHdr->wait_backend_pgprocno = MyProc->pgprocno;
41204120
PinCountWaitBuf = bufHdr;
41214121
buf_state |= BM_PIN_COUNT_WAITER;
41224122
UnlockBufHdr(bufHdr, buf_state);
@@ -4187,7 +4187,7 @@ LockBufferForCleanup(Buffer buffer)
41874187
*/
41884188
buf_state = LockBufHdr(bufHdr);
41894189
if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
4190-
bufHdr->wait_backend_pid == MyProcPid)
4190+
bufHdr->wait_backend_pgprocno == MyProc->pgprocno)
41914191
buf_state &= ~BM_PIN_COUNT_WAITER;
41924192
UnlockBufHdr(bufHdr, buf_state);
41934193

src/backend/storage/lmgr/predicate.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,7 @@ InitPredicateLocks(void)
12771277
PredXact->OldCommittedSxact->xmin = InvalidTransactionId;
12781278
PredXact->OldCommittedSxact->flags = SXACT_FLAG_COMMITTED;
12791279
PredXact->OldCommittedSxact->pid = 0;
1280+
PredXact->OldCommittedSxact->pgprocno = INVALID_PGPROCNO;
12801281
}
12811282
/* This never changes, so let's keep a local copy. */
12821283
OldCommittedSxact = PredXact->OldCommittedSxact;
@@ -1876,6 +1877,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
18761877
sxact->finishedBefore = InvalidTransactionId;
18771878
sxact->xmin = snapshot->xmin;
18781879
sxact->pid = MyProcPid;
1880+
sxact->pgprocno = MyProc->pgprocno;
18791881
SHMQueueInit(&(sxact->predicateLocks));
18801882
SHMQueueElemInit(&(sxact->finishedLink));
18811883
sxact->flags = 0;
@@ -3669,7 +3671,7 @@ ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
36693671
*/
36703672
if (SxactIsDeferrableWaiting(roXact) &&
36713673
(SxactIsROUnsafe(roXact) || SxactIsROSafe(roXact)))
3672-
ProcSendSignal(roXact->pid);
3674+
ProcSendSignal(roXact->pgprocno);
36733675

36743676
possibleUnsafeConflict = nextConflict;
36753677
}
@@ -5006,6 +5008,7 @@ PostPrepare_PredicateLocks(TransactionId xid)
50065008
Assert(SxactIsPrepared(MySerializableXact));
50075009

50085010
MySerializableXact->pid = 0;
5011+
MySerializableXact->pgprocno = INVALID_PGPROCNO;
50095012

50105013
hash_destroy(LocalPredicateLockHash);
50115014
LocalPredicateLockHash = NULL;
@@ -5081,6 +5084,7 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
50815084
sxact->vxid.backendId = InvalidBackendId;
50825085
sxact->vxid.localTransactionId = (LocalTransactionId) xid;
50835086
sxact->pid = 0;
5087+
sxact->pgprocno = INVALID_PGPROCNO;
50845088

50855089
/* a prepared xact hasn't committed yet */
50865090
sxact->prepareSeqNo = RecoverySerCommitSeqNo;

src/backend/storage/lmgr/proc.c

+5-45
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,6 @@ InitProcGlobal(void)
177177
ProcGlobal->autovacFreeProcs = NULL;
178178
ProcGlobal->bgworkerFreeProcs = NULL;
179179
ProcGlobal->walsenderFreeProcs = NULL;
180-
ProcGlobal->startupProc = NULL;
181-
ProcGlobal->startupProcPid = 0;
182180
ProcGlobal->startupBufferPinWaitBufId = -1;
183181
ProcGlobal->walwriterLatch = NULL;
184182
ProcGlobal->checkpointerLatch = NULL;
@@ -624,21 +622,6 @@ InitAuxiliaryProcess(void)
624622
on_shmem_exit(AuxiliaryProcKill, Int32GetDatum(proctype));
625623
}
626624

627-
/*
628-
* Record the PID and PGPROC structures for the Startup process, for use in
629-
* ProcSendSignal(). See comments there for further explanation.
630-
*/
631-
void
632-
PublishStartupProcessInformation(void)
633-
{
634-
SpinLockAcquire(ProcStructLock);
635-
636-
ProcGlobal->startupProc = MyProc;
637-
ProcGlobal->startupProcPid = MyProcPid;
638-
639-
SpinLockRelease(ProcStructLock);
640-
}
641-
642625
/*
643626
* Used from bufmgr to share the value of the buffer that Startup waits on,
644627
* or to reset the value to "not waiting" (-1). This allows processing
@@ -1903,38 +1886,15 @@ ProcWaitForSignal(uint32 wait_event_info)
19031886
}
19041887

19051888
/*
1906-
* ProcSendSignal - send a signal to a backend identified by PID
1889+
* ProcSendSignal - set the latch of a backend identified by pgprocno
19071890
*/
19081891
void
1909-
ProcSendSignal(int pid)
1892+
ProcSendSignal(int pgprocno)
19101893
{
1911-
PGPROC *proc = NULL;
1894+
if (pgprocno < 0 || pgprocno >= ProcGlobal->allProcCount)
1895+
elog(ERROR, "pgprocno out of range");
19121896

1913-
if (RecoveryInProgress())
1914-
{
1915-
SpinLockAcquire(ProcStructLock);
1916-
1917-
/*
1918-
* Check to see whether it is the Startup process we wish to signal.
1919-
* This call is made by the buffer manager when it wishes to wake up a
1920-
* process that has been waiting for a pin in so it can obtain a
1921-
* cleanup lock using LockBufferForCleanup(). Startup is not a normal
1922-
* backend, so BackendPidGetProc() will not return any pid at all. So
1923-
* we remember the information for this special case.
1924-
*/
1925-
if (pid == ProcGlobal->startupProcPid)
1926-
proc = ProcGlobal->startupProc;
1927-
1928-
SpinLockRelease(ProcStructLock);
1929-
}
1930-
1931-
if (proc == NULL)
1932-
proc = BackendPidGetProc(pid);
1933-
1934-
if (proc != NULL)
1935-
{
1936-
SetLatch(&proc->procLatch);
1937-
}
1897+
SetLatch(&ProcGlobal->allProcs[pgprocno].procLatch);
19381898
}
19391899

19401900
/*

src/include/storage/buf_internals.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ typedef struct buftag
136136
* BufferDesc -- shared descriptor/state data for a single shared buffer.
137137
*
138138
* Note: Buffer header lock (BM_LOCKED flag) must be held to examine or change
139-
* the tag, state or wait_backend_pid fields. In general, buffer header lock
139+
* tag, state or wait_backend_pgprocno fields. In general, buffer header lock
140140
* is a spinlock which is combined with flags, refcount and usagecount into
141141
* single atomic variable. This layout allow us to do some operations in a
142142
* single atomic operation, without actually acquiring and releasing spinlock;
@@ -161,8 +161,8 @@ typedef struct buftag
161161
*
162162
* We can't physically remove items from a disk page if another backend has
163163
* the buffer pinned. Hence, a backend may need to wait for all other pins
164-
* to go away. This is signaled by storing its own PID into
165-
* wait_backend_pid and setting flag bit BM_PIN_COUNT_WAITER. At present,
164+
* to go away. This is signaled by storing its own pgprocno into
165+
* wait_backend_pgprocno and setting flag bit BM_PIN_COUNT_WAITER. At present,
166166
* there can be only one such waiter per buffer.
167167
*
168168
* We use this same struct for local buffer headers, but the locks are not
@@ -187,7 +187,7 @@ typedef struct BufferDesc
187187
/* state of the tag, containing flags, refcount and usagecount */
188188
pg_atomic_uint32 state;
189189

190-
int wait_backend_pid; /* backend PID of pin-count waiter */
190+
int wait_backend_pgprocno; /* backend of pin-count waiter */
191191
int freeNext; /* link in freelist chain */
192192
LWLock content_lock; /* to lock access to buffer contents */
193193
} BufferDesc;

src/include/storage/predicate_internals.h

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ typedef struct SERIALIZABLEXACT
113113
TransactionId xmin; /* the transaction's snapshot xmin */
114114
uint32 flags; /* OR'd combination of values defined below */
115115
int pid; /* pid of associated process */
116+
int pgprocno; /* pgprocno of associated process */
116117
} SERIALIZABLEXACT;
117118

118119
#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */

src/include/storage/proc.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,6 @@ typedef struct PROC_HDR
359359
Latch *checkpointerLatch;
360360
/* Current shared estimate of appropriate spins_per_delay value */
361361
int spins_per_delay;
362-
/* The proc of the Startup process, since not in ProcArray */
363-
PGPROC *startupProc;
364-
int startupProcPid;
365362
/* Buffer id of the buffer that Startup process waits for pin on, or -1 */
366363
int startupBufferPinWaitBufId;
367364
} PROC_HDR;
@@ -402,7 +399,6 @@ extern void InitProcess(void);
402399
extern void InitProcessPhase2(void);
403400
extern void InitAuxiliaryProcess(void);
404401

405-
extern void PublishStartupProcessInformation(void);
406402
extern void SetStartupBufferPinWaitBufId(int bufid);
407403
extern int GetStartupBufferPinWaitBufId(void);
408404

@@ -418,7 +414,7 @@ extern bool IsWaitingForLock(void);
418414
extern void LockErrorCleanup(void);
419415

420416
extern void ProcWaitForSignal(uint32 wait_event_info);
421-
extern void ProcSendSignal(int pid);
417+
extern void ProcSendSignal(int pgprocno);
422418

423419
extern PGPROC *AuxiliaryPidGetProc(int pid);
424420

0 commit comments

Comments
 (0)