From f3176f831a110fc23c4d897f893e31400834a6a8 Mon Sep 17 00:00:00 2001
From: zhanyi <w@hidva.com>
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

