From f3176f831a110fc23c4d897f893e31400834a6a8 Mon Sep 17 00:00:00 2001 From: zhanyi Date: Fri, 7 May 2021 04:22:50 +0800 Subject: [PATCH] use pgxactoff as the value of index in ProcArrayRemove() pgxactoff is always the index of pgprocno in procArray->pgprocnos. --- src/backend/storage/ipc/procarray.c | 84 +++++++++++++++++------------ 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 5ff8cab394..d7cf4bdff0 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -511,6 +511,28 @@ ProcArrayAdd(PGPROC *proc) LWLockRelease(ProcArrayLock); } +#ifdef USE_ASSERT_CHECKING +static int +find(int *array, int size, int val) +{ + for (int idx = 0; idx < size; ++idx) + { + if (array[idx] == val) + return idx; + } + return -1; +} + +static int +find_ex(int *array, int size, int start, int val) +{ + int ret = find(array + start, size - start, val); + if (ret >= 0) + ret += start; + return ret; +} +#endif + /* * Remove the specified PGPROC from the shared array. * @@ -559,47 +581,39 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid) Assert(!TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff])); } - Assert(TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff] == 0)); - Assert(TransactionIdIsValid(ProcGlobal->subxidStates[proc->pgxactoff].count == 0)); - Assert(TransactionIdIsValid(ProcGlobal->subxidStates[proc->pgxactoff].overflowed == false)); + Assert(!TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff])); + Assert(ProcGlobal->subxidStates[proc->pgxactoff].count == 0); + Assert(ProcGlobal->subxidStates[proc->pgxactoff].overflowed == false); ProcGlobal->statusFlags[proc->pgxactoff] = 0; - for (index = 0; index < arrayP->numProcs; index++) - { - if (arrayP->pgprocnos[index] == proc->pgprocno) - { - /* Keep the PGPROC array sorted. See notes above */ - memmove(&arrayP->pgprocnos[index], &arrayP->pgprocnos[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*arrayP->pgprocnos)); - memmove(&ProcGlobal->xids[index], &ProcGlobal->xids[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->xids)); - memmove(&ProcGlobal->subxidStates[index], &ProcGlobal->subxidStates[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->subxidStates)); - memmove(&ProcGlobal->statusFlags[index], &ProcGlobal->statusFlags[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->statusFlags)); - - arrayP->pgprocnos[arrayP->numProcs - 1] = -1; /* for debugging */ - arrayP->numProcs--; - - /* adjust for removed PGPROC */ - for (; index < arrayP->numProcs; index++) - allProcs[arrayP->pgprocnos[index]].pgxactoff--; + index = proc->pgxactoff; + Assert(find(arrayP->pgprocnos, arrayP->numProcs, proc->pgprocno) == index); + Assert(find_ex(arrayP->pgprocnos, arrayP->numProcs, index + 1, proc->pgprocno) == -1); - /* - * Release in reversed acquisition order, to reduce frequency of - * having to wait for XidGenLock while holding ProcArrayLock. - */ - LWLockRelease(XidGenLock); - LWLockRelease(ProcArrayLock); - return; - } - } + /* Keep the PGPROC array sorted. See notes above */ + memmove(&arrayP->pgprocnos[index], &arrayP->pgprocnos[index + 1], + (arrayP->numProcs - index - 1) * sizeof(*arrayP->pgprocnos)); + memmove(&ProcGlobal->xids[index], &ProcGlobal->xids[index + 1], + (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->xids)); + memmove(&ProcGlobal->subxidStates[index], &ProcGlobal->subxidStates[index + 1], + (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->subxidStates)); + memmove(&ProcGlobal->statusFlags[index], &ProcGlobal->statusFlags[index + 1], + (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->statusFlags)); - /* Oops */ + arrayP->pgprocnos[arrayP->numProcs - 1] = -1; /* for debugging */ + arrayP->numProcs--; + + /* adjust for removed PGPROC */ + for (; index < arrayP->numProcs; index++) + allProcs[arrayP->pgprocnos[index]].pgxactoff--; + + /* + * Release in reversed acquisition order, to reduce frequency of + * having to wait for XidGenLock while holding ProcArrayLock. + */ LWLockRelease(XidGenLock); LWLockRelease(ProcArrayLock); - - elog(LOG, "failed to find proc %p in ProcArray", proc); + return; } -- 2.26.2