1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-11 20:28:21 +03:00

Remove superfluous 'pgprocno' field from PGPROC

It was always just the index of the PGPROC entry from the beginning of
the proc array. Introduce a macro to compute it from the pointer
instead.

Reviewed-by: Andres Freund
Discussion: https://www.postgresql.org/message-id/8171f1aa-496f-46a6-afc3-c46fe7a9b407@iki.fi
This commit is contained in:
Heikki Linnakangas
2024-02-22 01:21:34 +02:00
parent 4989ce7264
commit 28f3915b73
14 changed files with 46 additions and 43 deletions

View File

@ -425,6 +425,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
{ {
volatile PROC_HDR *procglobal = ProcGlobal; volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc; PGPROC *proc = MyProc;
int pgprocno = MyProcNumber;
uint32 nextidx; uint32 nextidx;
uint32 wakeidx; uint32 wakeidx;
@ -458,7 +459,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* less efficiently. * less efficiently.
*/ */
if (nextidx != INVALID_PGPROCNO && if (nextidx != INVALID_PGPROCNO &&
ProcGlobal->allProcs[nextidx].clogGroupMemberPage != proc->clogGroupMemberPage) GetPGProcByNumber(nextidx)->clogGroupMemberPage != proc->clogGroupMemberPage)
{ {
/* /*
* Ensure that this proc is not a member of any clog group that * Ensure that this proc is not a member of any clog group that
@ -473,7 +474,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
&nextidx, &nextidx,
(uint32) proc->pgprocno)) (uint32) pgprocno))
break; break;
} }

View File

@ -284,7 +284,7 @@ TwoPhaseShmemInit(void)
TwoPhaseState->freeGXacts = &gxacts[i]; TwoPhaseState->freeGXacts = &gxacts[i];
/* associate it with a PGPROC assigned by InitProcGlobal */ /* associate it with a PGPROC assigned by InitProcGlobal */
gxacts[i].pgprocno = PreparedXactProcs[i].pgprocno; gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]);
/* /*
* Assign a unique ID for each dummy proc, so that the range of * Assign a unique ID for each dummy proc, so that the range of
@ -461,7 +461,6 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
/* Initialize the PGPROC entry */ /* Initialize the PGPROC entry */
MemSet(proc, 0, sizeof(PGPROC)); MemSet(proc, 0, sizeof(PGPROC));
proc->pgprocno = gxact->pgprocno;
dlist_node_init(&proc->links); dlist_node_init(&proc->links);
proc->waitStatus = PROC_WAIT_STATUS_OK; proc->waitStatus = PROC_WAIT_STATUS_OK;
if (LocalTransactionIdIsValid(MyProc->lxid)) if (LocalTransactionIdIsValid(MyProc->lxid))
@ -780,7 +779,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
while (status->array != NULL && status->currIdx < status->ngxacts) while (status->array != NULL && status->currIdx < status->ngxacts)
{ {
GlobalTransaction gxact = &status->array[status->currIdx++]; GlobalTransaction gxact = &status->array[status->currIdx++];
PGPROC *proc = &ProcGlobal->allProcs[gxact->pgprocno]; PGPROC *proc = GetPGProcByNumber(gxact->pgprocno);
Datum values[5] = {0}; Datum values[5] = {0};
bool nulls[5] = {0}; bool nulls[5] = {0};
HeapTuple tuple; HeapTuple tuple;
@ -935,7 +934,7 @@ TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
{ {
GlobalTransaction gxact = TwoPhaseGetGXact(xid, lock_held); GlobalTransaction gxact = TwoPhaseGetGXact(xid, lock_held);
return &ProcGlobal->allProcs[gxact->pgprocno]; return GetPGProcByNumber(gxact->pgprocno);
} }
/************************************************************************/ /************************************************************************/
@ -1080,7 +1079,7 @@ save_state_data(const void *data, uint32 len)
void void
StartPrepare(GlobalTransaction gxact) StartPrepare(GlobalTransaction gxact)
{ {
PGPROC *proc = &ProcGlobal->allProcs[gxact->pgprocno]; PGPROC *proc = GetPGProcByNumber(gxact->pgprocno);
TransactionId xid = gxact->xid; TransactionId xid = gxact->xid;
TwoPhaseFileHeader hdr; TwoPhaseFileHeader hdr;
TransactionId *children; TransactionId *children;
@ -1539,7 +1538,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
* try to commit the same GID at once. * try to commit the same GID at once.
*/ */
gxact = LockGXact(gid, GetUserId()); gxact = LockGXact(gid, GetUserId());
proc = &ProcGlobal->allProcs[gxact->pgprocno]; proc = GetPGProcByNumber(gxact->pgprocno);
xid = gxact->xid; xid = gxact->xid;
/* /*

View File

@ -1379,7 +1379,7 @@ WALInsertLockAcquire(void)
static int lockToTry = -1; static int lockToTry = -1;
if (lockToTry == -1) if (lockToTry == -1)
lockToTry = MyProc->pgprocno % NUM_XLOGINSERT_LOCKS; lockToTry = MyProcNumber % NUM_XLOGINSERT_LOCKS;
MyLockNo = lockToTry; MyLockNo = lockToTry;
/* /*

View File

@ -326,7 +326,7 @@ BackgroundWriterMain(void)
if (rc == WL_TIMEOUT && can_hibernate && prev_hibernate) if (rc == WL_TIMEOUT && can_hibernate && prev_hibernate)
{ {
/* Ask for notification at next buffer allocation */ /* Ask for notification at next buffer allocation */
StrategyNotifyBgWriter(MyProc->pgprocno); StrategyNotifyBgWriter(MyProcNumber);
/* Sleep ... */ /* Sleep ... */
(void) WaitLatch(MyLatch, (void) WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,

View File

@ -242,7 +242,7 @@ PgArchiverMain(void)
* Advertise our pgprocno so that backends can use our latch to wake us up * Advertise our pgprocno so that backends can use our latch to wake us up
* while we're sleeping. * while we're sleeping.
*/ */
PgArch->pgprocno = MyProc->pgprocno; PgArch->pgprocno = MyProcNumber;
/* Create workspace for pgarch_readyXlog() */ /* Create workspace for pgarch_readyXlog() */
arch_files = palloc(sizeof(struct arch_files_state)); arch_files = palloc(sizeof(struct arch_files_state));

View File

@ -248,7 +248,7 @@ WalSummarizerMain(void)
/* Advertise ourselves. */ /* Advertise ourselves. */
on_shmem_exit(WalSummarizerShutdown, (Datum) 0); on_shmem_exit(WalSummarizerShutdown, (Datum) 0);
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE); LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
WalSummarizerCtl->summarizer_pgprocno = MyProc->pgprocno; WalSummarizerCtl->summarizer_pgprocno = MyProcNumber;
LWLockRelease(WALSummarizerLock); LWLockRelease(WALSummarizerLock);
/* Create and switch to a memory context that we can reset on error. */ /* Create and switch to a memory context that we can reset on error. */

View File

@ -4780,7 +4780,7 @@ UnlockBuffers(void)
* got a cancel/die interrupt before getting the signal. * got a cancel/die interrupt before getting the signal.
*/ */
if ((buf_state & BM_PIN_COUNT_WAITER) != 0 && if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
buf->wait_backend_pgprocno == MyProc->pgprocno) buf->wait_backend_pgprocno == MyProcNumber)
buf_state &= ~BM_PIN_COUNT_WAITER; buf_state &= ~BM_PIN_COUNT_WAITER;
UnlockBufHdr(buf, buf_state); UnlockBufHdr(buf, buf_state);
@ -4930,7 +4930,7 @@ LockBufferForCleanup(Buffer buffer)
LockBuffer(buffer, BUFFER_LOCK_UNLOCK); LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
elog(ERROR, "multiple backends attempting to wait for pincount 1"); elog(ERROR, "multiple backends attempting to wait for pincount 1");
} }
bufHdr->wait_backend_pgprocno = MyProc->pgprocno; bufHdr->wait_backend_pgprocno = MyProcNumber;
PinCountWaitBuf = bufHdr; PinCountWaitBuf = bufHdr;
buf_state |= BM_PIN_COUNT_WAITER; buf_state |= BM_PIN_COUNT_WAITER;
UnlockBufHdr(bufHdr, buf_state); UnlockBufHdr(bufHdr, buf_state);
@ -4994,7 +4994,7 @@ LockBufferForCleanup(Buffer buffer)
*/ */
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if ((buf_state & BM_PIN_COUNT_WAITER) != 0 && if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
bufHdr->wait_backend_pgprocno == MyProc->pgprocno) bufHdr->wait_backend_pgprocno == MyProcNumber)
buf_state &= ~BM_PIN_COUNT_WAITER; buf_state &= ~BM_PIN_COUNT_WAITER;
UnlockBufHdr(bufHdr, buf_state); UnlockBufHdr(bufHdr, buf_state);

View File

@ -468,6 +468,7 @@ CreateSharedProcArray(void)
void void
ProcArrayAdd(PGPROC *proc) ProcArrayAdd(PGPROC *proc)
{ {
int pgprocno = GetNumberFromPGProc(proc);
ProcArrayStruct *arrayP = procArray; ProcArrayStruct *arrayP = procArray;
int index; int index;
int movecount; int movecount;
@ -499,13 +500,13 @@ ProcArrayAdd(PGPROC *proc)
*/ */
for (index = 0; index < arrayP->numProcs; index++) for (index = 0; index < arrayP->numProcs; index++)
{ {
int procno PG_USED_FOR_ASSERTS_ONLY = arrayP->pgprocnos[index]; int this_procno = arrayP->pgprocnos[index];
Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS)); Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
Assert(allProcs[procno].pgxactoff == index); Assert(allProcs[this_procno].pgxactoff == index);
/* If we have found our right position in the array, break */ /* If we have found our right position in the array, break */
if (arrayP->pgprocnos[index] > proc->pgprocno) if (this_procno > pgprocno)
break; break;
} }
@ -523,7 +524,7 @@ ProcArrayAdd(PGPROC *proc)
&ProcGlobal->statusFlags[index], &ProcGlobal->statusFlags[index],
movecount * sizeof(*ProcGlobal->statusFlags)); movecount * sizeof(*ProcGlobal->statusFlags));
arrayP->pgprocnos[index] = proc->pgprocno; arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
proc->pgxactoff = index; proc->pgxactoff = index;
ProcGlobal->xids[index] = proc->xid; ProcGlobal->xids[index] = proc->xid;
ProcGlobal->subxidStates[index] = proc->subxidStatus; ProcGlobal->subxidStates[index] = proc->subxidStatus;
@ -791,6 +792,7 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
static void static void
ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
{ {
int pgprocno = GetNumberFromPGProc(proc);
PROC_HDR *procglobal = ProcGlobal; PROC_HDR *procglobal = ProcGlobal;
uint32 nextidx; uint32 nextidx;
uint32 wakeidx; uint32 wakeidx;
@ -808,7 +810,7 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
if (pg_atomic_compare_exchange_u32(&procglobal->procArrayGroupFirst, if (pg_atomic_compare_exchange_u32(&procglobal->procArrayGroupFirst,
&nextidx, &nextidx,
(uint32) proc->pgprocno)) (uint32) pgprocno))
break; break;
} }

View File

@ -57,7 +57,7 @@ ConditionVariableInit(ConditionVariable *cv)
void void
ConditionVariablePrepareToSleep(ConditionVariable *cv) ConditionVariablePrepareToSleep(ConditionVariable *cv)
{ {
int pgprocno = MyProc->pgprocno; int pgprocno = MyProcNumber;
/* /*
* If some other sleep is already prepared, cancel it; this is necessary * If some other sleep is already prepared, cancel it; this is necessary
@ -181,10 +181,10 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
* guarantee not to return spuriously, we'll avoid this obvious case. * guarantee not to return spuriously, we'll avoid this obvious case.
*/ */
SpinLockAcquire(&cv->mutex); SpinLockAcquire(&cv->mutex);
if (!proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink)) if (!proclist_contains(&cv->wakeup, MyProcNumber, cvWaitLink))
{ {
done = true; done = true;
proclist_push_tail(&cv->wakeup, MyProc->pgprocno, cvWaitLink); proclist_push_tail(&cv->wakeup, MyProcNumber, cvWaitLink);
} }
SpinLockRelease(&cv->mutex); SpinLockRelease(&cv->mutex);
@ -236,8 +236,8 @@ ConditionVariableCancelSleep(void)
return false; return false;
SpinLockAcquire(&cv->mutex); SpinLockAcquire(&cv->mutex);
if (proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink)) if (proclist_contains(&cv->wakeup, MyProcNumber, cvWaitLink))
proclist_delete(&cv->wakeup, MyProc->pgprocno, cvWaitLink); proclist_delete(&cv->wakeup, MyProcNumber, cvWaitLink);
else else
signaled = true; signaled = true;
SpinLockRelease(&cv->mutex); SpinLockRelease(&cv->mutex);
@ -281,7 +281,7 @@ ConditionVariableSignal(ConditionVariable *cv)
void void
ConditionVariableBroadcast(ConditionVariable *cv) ConditionVariableBroadcast(ConditionVariable *cv)
{ {
int pgprocno = MyProc->pgprocno; int pgprocno = MyProcNumber;
PGPROC *proc = NULL; PGPROC *proc = NULL;
bool have_sentinel = false; bool have_sentinel = false;

View File

@ -1056,9 +1056,9 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
/* LW_WAIT_UNTIL_FREE waiters are always at the front of the queue */ /* LW_WAIT_UNTIL_FREE waiters are always at the front of the queue */
if (mode == LW_WAIT_UNTIL_FREE) if (mode == LW_WAIT_UNTIL_FREE)
proclist_push_head(&lock->waiters, MyProc->pgprocno, lwWaitLink); proclist_push_head(&lock->waiters, MyProcNumber, lwWaitLink);
else else
proclist_push_tail(&lock->waiters, MyProc->pgprocno, lwWaitLink); proclist_push_tail(&lock->waiters, MyProcNumber, lwWaitLink);
/* Can release the mutex now */ /* Can release the mutex now */
LWLockWaitListUnlock(lock); LWLockWaitListUnlock(lock);
@ -1097,7 +1097,7 @@ LWLockDequeueSelf(LWLock *lock)
*/ */
on_waitlist = MyProc->lwWaiting == LW_WS_WAITING; on_waitlist = MyProc->lwWaiting == LW_WS_WAITING;
if (on_waitlist) if (on_waitlist)
proclist_delete(&lock->waiters, MyProc->pgprocno, lwWaitLink); proclist_delete(&lock->waiters, MyProcNumber, lwWaitLink);
if (proclist_is_empty(&lock->waiters) && if (proclist_is_empty(&lock->waiters) &&
(pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS) != 0) (pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS) != 0)

View File

@ -1830,7 +1830,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
sxact->finishedBefore = InvalidTransactionId; sxact->finishedBefore = InvalidTransactionId;
sxact->xmin = snapshot->xmin; sxact->xmin = snapshot->xmin;
sxact->pid = MyProcPid; sxact->pid = MyProcPid;
sxact->pgprocno = MyProc->pgprocno; sxact->pgprocno = MyProcNumber;
dlist_init(&sxact->predicateLocks); dlist_init(&sxact->predicateLocks);
dlist_node_init(&sxact->finishedLink); dlist_node_init(&sxact->finishedLink);
sxact->flags = 0; sxact->flags = 0;

View File

@ -65,6 +65,7 @@ bool log_lock_waits = false;
/* Pointer to this process's PGPROC struct, if any */ /* Pointer to this process's PGPROC struct, if any */
PGPROC *MyProc = NULL; PGPROC *MyProc = NULL;
int MyProcNumber = INVALID_PGPROCNO;
/* /*
* This spinlock protects the freelist of recycled PGPROC structures. * This spinlock protects the freelist of recycled PGPROC structures.
@ -228,7 +229,6 @@ InitProcGlobal(void)
InitSharedLatch(&(proc->procLatch)); InitSharedLatch(&(proc->procLatch));
LWLockInitialize(&(proc->fpInfoLock), LWTRANCHE_LOCK_FASTPATH); LWLockInitialize(&(proc->fpInfoLock), LWTRANCHE_LOCK_FASTPATH);
} }
proc->pgprocno = i;
/* /*
* Newly created PGPROCs for normal backends, autovacuum and bgworkers * Newly created PGPROCs for normal backends, autovacuum and bgworkers
@ -353,6 +353,7 @@ InitProcess(void)
(errcode(ERRCODE_TOO_MANY_CONNECTIONS), (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
errmsg("sorry, too many clients already"))); errmsg("sorry, too many clients already")));
} }
MyProcNumber = GetNumberFromPGProc(MyProc);
/* /*
* Cross-check that the PGPROC is of the type we expect; if this were not * Cross-check that the PGPROC is of the type we expect; if this were not
@ -566,6 +567,8 @@ InitAuxiliaryProcess(void)
SpinLockRelease(ProcStructLock); SpinLockRelease(ProcStructLock);
MyProcNumber = GetNumberFromPGProc(MyProc);
/* /*
* Initialize all fields of MyProc, except for those previously * Initialize all fields of MyProc, except for those previously
* initialized by InitProcGlobal. * initialized by InitProcGlobal.
@ -907,6 +910,7 @@ ProcKill(int code, Datum arg)
proc = MyProc; proc = MyProc;
MyProc = NULL; MyProc = NULL;
MyProcNumber = INVALID_PGPROCNO;
DisownLatch(&proc->procLatch); DisownLatch(&proc->procLatch);
procgloballist = proc->procgloballist; procgloballist = proc->procgloballist;
@ -978,6 +982,7 @@ AuxiliaryProcKill(int code, Datum arg)
proc = MyProc; proc = MyProc;
MyProc = NULL; MyProc = NULL;
MyProcNumber = INVALID_PGPROCNO;
DisownLatch(&proc->procLatch); DisownLatch(&proc->procLatch);
SpinLockAcquire(ProcStructLock); SpinLockAcquire(ProcStructLock);
@ -1903,10 +1908,9 @@ BecomeLockGroupMember(PGPROC *leader, int pid)
/* /*
* Get lock protecting the group fields. Note LockHashPartitionLockByProc * Get lock protecting the group fields. Note LockHashPartitionLockByProc
* accesses leader->pgprocno in a PGPROC that might be free. This is safe * calculates the proc number based on the PGPROC slot without looking at
* because all PGPROCs' pgprocno fields are set during shared memory * its contents, so we will acquire the correct lock even if the leader
* initialization and never change thereafter; so we will acquire the * PGPROC is in process of being recycled.
* correct lock even if the leader PGPROC is in process of being recycled.
*/ */
leader_lwlock = LockHashPartitionLockByProc(leader); leader_lwlock = LockHashPartitionLockByProc(leader);
LWLockAcquire(leader_lwlock, LW_EXCLUSIVE); LWLockAcquire(leader_lwlock, LW_EXCLUSIVE);

View File

@ -540,7 +540,7 @@ typedef enum
* used for a given lock group is determined by the group leader's pgprocno. * used for a given lock group is determined by the group leader's pgprocno.
*/ */
#define LockHashPartitionLockByProc(leader_pgproc) \ #define LockHashPartitionLockByProc(leader_pgproc) \
LockHashPartitionLock((leader_pgproc)->pgprocno) LockHashPartitionLock(GetNumberFromPGProc(leader_pgproc))
/* /*
* function prototypes * function prototypes

View File

@ -194,11 +194,6 @@ struct PGPROC
int pgxactoff; /* offset into various ProcGlobal->arrays with int pgxactoff; /* offset into various ProcGlobal->arrays with
* data mirrored from this PGPROC */ * data mirrored from this PGPROC */
int pgprocno; /* Number of this PGPROC in
* ProcGlobal->allProcs array. This is set
* once by InitProcGlobal().
* ProcGlobal->allProcs[n].pgprocno == n */
/* These fields are zero while a backend is still starting up: */ /* These fields are zero while a backend is still starting up: */
BackendId backendId; /* This backend's backend ID (if assigned) */ BackendId backendId; /* This backend's backend ID (if assigned) */
Oid databaseId; /* OID of database this backend is using */ Oid databaseId; /* OID of database this backend is using */
@ -307,6 +302,7 @@ struct PGPROC
extern PGDLLIMPORT PGPROC *MyProc; extern PGDLLIMPORT PGPROC *MyProc;
extern PGDLLIMPORT int MyProcNumber; /* same as GetNumberFromPGProc(MyProc) */
/* /*
* There is one ProcGlobal struct for the whole database cluster. * There is one ProcGlobal struct for the whole database cluster.
@ -410,8 +406,9 @@ extern PGDLLIMPORT PROC_HDR *ProcGlobal;
extern PGDLLIMPORT PGPROC *PreparedXactProcs; extern PGDLLIMPORT PGPROC *PreparedXactProcs;
/* Accessor for PGPROC given a pgprocno. */ /* Accessor for PGPROC given a pgprocno, and vice versa. */
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)]) #define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
#define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])
/* /*
* We set aside some extra PGPROC structures for auxiliary processes, * We set aside some extra PGPROC structures for auxiliary processes,