mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04: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:
		
							parent
							
								
									4989ce7264
								
							
						
					
					
						commit
						28f3915b73
					
				| @ -425,6 +425,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, | ||||
| { | ||||
| 	volatile PROC_HDR *procglobal = ProcGlobal; | ||||
| 	PGPROC	   *proc = MyProc; | ||||
| 	int			pgprocno = MyProcNumber; | ||||
| 	uint32		nextidx; | ||||
| 	uint32		wakeidx; | ||||
| 
 | ||||
| @ -458,7 +459,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, | ||||
| 		 * less efficiently. | ||||
| 		 */ | ||||
| 		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 | ||||
| @ -473,7 +474,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, | ||||
| 
 | ||||
| 		if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, | ||||
| 										   &nextidx, | ||||
| 										   (uint32) proc->pgprocno)) | ||||
| 										   (uint32) pgprocno)) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -284,7 +284,7 @@ TwoPhaseShmemInit(void) | ||||
| 			TwoPhaseState->freeGXacts = &gxacts[i]; | ||||
| 
 | ||||
| 			/* 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 | ||||
| @ -461,7 +461,6 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid, | ||||
| 
 | ||||
| 	/* Initialize the PGPROC entry */ | ||||
| 	MemSet(proc, 0, sizeof(PGPROC)); | ||||
| 	proc->pgprocno = gxact->pgprocno; | ||||
| 	dlist_node_init(&proc->links); | ||||
| 	proc->waitStatus = PROC_WAIT_STATUS_OK; | ||||
| 	if (LocalTransactionIdIsValid(MyProc->lxid)) | ||||
| @ -780,7 +779,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS) | ||||
| 	while (status->array != NULL && status->currIdx < status->ngxacts) | ||||
| 	{ | ||||
| 		GlobalTransaction gxact = &status->array[status->currIdx++]; | ||||
| 		PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno]; | ||||
| 		PGPROC	   *proc = GetPGProcByNumber(gxact->pgprocno); | ||||
| 		Datum		values[5] = {0}; | ||||
| 		bool		nulls[5] = {0}; | ||||
| 		HeapTuple	tuple; | ||||
| @ -935,7 +934,7 @@ TwoPhaseGetDummyProc(TransactionId xid, bool 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 | ||||
| StartPrepare(GlobalTransaction gxact) | ||||
| { | ||||
| 	PGPROC	   *proc = &ProcGlobal->allProcs[gxact->pgprocno]; | ||||
| 	PGPROC	   *proc = GetPGProcByNumber(gxact->pgprocno); | ||||
| 	TransactionId xid = gxact->xid; | ||||
| 	TwoPhaseFileHeader hdr; | ||||
| 	TransactionId *children; | ||||
| @ -1539,7 +1538,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit) | ||||
| 	 * try to commit the same GID at once. | ||||
| 	 */ | ||||
| 	gxact = LockGXact(gid, GetUserId()); | ||||
| 	proc = &ProcGlobal->allProcs[gxact->pgprocno]; | ||||
| 	proc = GetPGProcByNumber(gxact->pgprocno); | ||||
| 	xid = gxact->xid; | ||||
| 
 | ||||
| 	/*
 | ||||
|  | ||||
| @ -1379,7 +1379,7 @@ WALInsertLockAcquire(void) | ||||
| 	static int	lockToTry = -1; | ||||
| 
 | ||||
| 	if (lockToTry == -1) | ||||
| 		lockToTry = MyProc->pgprocno % NUM_XLOGINSERT_LOCKS; | ||||
| 		lockToTry = MyProcNumber % NUM_XLOGINSERT_LOCKS; | ||||
| 	MyLockNo = lockToTry; | ||||
| 
 | ||||
| 	/*
 | ||||
|  | ||||
| @ -326,7 +326,7 @@ BackgroundWriterMain(void) | ||||
| 		if (rc == WL_TIMEOUT && can_hibernate && prev_hibernate) | ||||
| 		{ | ||||
| 			/* Ask for notification at next buffer allocation */ | ||||
| 			StrategyNotifyBgWriter(MyProc->pgprocno); | ||||
| 			StrategyNotifyBgWriter(MyProcNumber); | ||||
| 			/* Sleep ... */ | ||||
| 			(void) WaitLatch(MyLatch, | ||||
| 							 WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, | ||||
|  | ||||
| @ -242,7 +242,7 @@ PgArchiverMain(void) | ||||
| 	 * Advertise our pgprocno so that backends can use our latch to wake us up | ||||
| 	 * while we're sleeping. | ||||
| 	 */ | ||||
| 	PgArch->pgprocno = MyProc->pgprocno; | ||||
| 	PgArch->pgprocno = MyProcNumber; | ||||
| 
 | ||||
| 	/* Create workspace for pgarch_readyXlog() */ | ||||
| 	arch_files = palloc(sizeof(struct arch_files_state)); | ||||
|  | ||||
| @ -248,7 +248,7 @@ WalSummarizerMain(void) | ||||
| 	/* Advertise ourselves. */ | ||||
| 	on_shmem_exit(WalSummarizerShutdown, (Datum) 0); | ||||
| 	LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE); | ||||
| 	WalSummarizerCtl->summarizer_pgprocno = MyProc->pgprocno; | ||||
| 	WalSummarizerCtl->summarizer_pgprocno = MyProcNumber; | ||||
| 	LWLockRelease(WALSummarizerLock); | ||||
| 
 | ||||
| 	/* Create and switch to a memory context that we can reset on error. */ | ||||
|  | ||||
| @ -4780,7 +4780,7 @@ UnlockBuffers(void) | ||||
| 		 * got a cancel/die interrupt before getting the signal. | ||||
| 		 */ | ||||
| 		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; | ||||
| 
 | ||||
| 		UnlockBufHdr(buf, buf_state); | ||||
| @ -4930,7 +4930,7 @@ LockBufferForCleanup(Buffer buffer) | ||||
| 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK); | ||||
| 			elog(ERROR, "multiple backends attempting to wait for pincount 1"); | ||||
| 		} | ||||
| 		bufHdr->wait_backend_pgprocno = MyProc->pgprocno; | ||||
| 		bufHdr->wait_backend_pgprocno = MyProcNumber; | ||||
| 		PinCountWaitBuf = bufHdr; | ||||
| 		buf_state |= BM_PIN_COUNT_WAITER; | ||||
| 		UnlockBufHdr(bufHdr, buf_state); | ||||
| @ -4994,7 +4994,7 @@ LockBufferForCleanup(Buffer buffer) | ||||
| 		 */ | ||||
| 		buf_state = LockBufHdr(bufHdr); | ||||
| 		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; | ||||
| 		UnlockBufHdr(bufHdr, buf_state); | ||||
| 
 | ||||
|  | ||||
| @ -468,6 +468,7 @@ CreateSharedProcArray(void) | ||||
| void | ||||
| ProcArrayAdd(PGPROC *proc) | ||||
| { | ||||
| 	int			pgprocno = GetNumberFromPGProc(proc); | ||||
| 	ProcArrayStruct *arrayP = procArray; | ||||
| 	int			index; | ||||
| 	int			movecount; | ||||
| @ -499,13 +500,13 @@ ProcArrayAdd(PGPROC *proc) | ||||
| 	 */ | ||||
| 	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(allProcs[procno].pgxactoff == index); | ||||
| 		Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS)); | ||||
| 		Assert(allProcs[this_procno].pgxactoff == index); | ||||
| 
 | ||||
| 		/* If we have found our right position in the array, break */ | ||||
| 		if (arrayP->pgprocnos[index] > proc->pgprocno) | ||||
| 		if (this_procno > pgprocno) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| @ -523,7 +524,7 @@ ProcArrayAdd(PGPROC *proc) | ||||
| 			&ProcGlobal->statusFlags[index], | ||||
| 			movecount * sizeof(*ProcGlobal->statusFlags)); | ||||
| 
 | ||||
| 	arrayP->pgprocnos[index] = proc->pgprocno; | ||||
| 	arrayP->pgprocnos[index] = GetNumberFromPGProc(proc); | ||||
| 	proc->pgxactoff = index; | ||||
| 	ProcGlobal->xids[index] = proc->xid; | ||||
| 	ProcGlobal->subxidStates[index] = proc->subxidStatus; | ||||
| @ -791,6 +792,7 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid) | ||||
| static void | ||||
| ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) | ||||
| { | ||||
| 	int			pgprocno = GetNumberFromPGProc(proc); | ||||
| 	PROC_HDR   *procglobal = ProcGlobal; | ||||
| 	uint32		nextidx; | ||||
| 	uint32		wakeidx; | ||||
| @ -808,7 +810,7 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) | ||||
| 
 | ||||
| 		if (pg_atomic_compare_exchange_u32(&procglobal->procArrayGroupFirst, | ||||
| 										   &nextidx, | ||||
| 										   (uint32) proc->pgprocno)) | ||||
| 										   (uint32) pgprocno)) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -57,7 +57,7 @@ ConditionVariableInit(ConditionVariable *cv) | ||||
| void | ||||
| ConditionVariablePrepareToSleep(ConditionVariable *cv) | ||||
| { | ||||
| 	int			pgprocno = MyProc->pgprocno; | ||||
| 	int			pgprocno = MyProcNumber; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 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. | ||||
| 		 */ | ||||
| 		SpinLockAcquire(&cv->mutex); | ||||
| 		if (!proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink)) | ||||
| 		if (!proclist_contains(&cv->wakeup, MyProcNumber, cvWaitLink)) | ||||
| 		{ | ||||
| 			done = true; | ||||
| 			proclist_push_tail(&cv->wakeup, MyProc->pgprocno, cvWaitLink); | ||||
| 			proclist_push_tail(&cv->wakeup, MyProcNumber, cvWaitLink); | ||||
| 		} | ||||
| 		SpinLockRelease(&cv->mutex); | ||||
| 
 | ||||
| @ -236,8 +236,8 @@ ConditionVariableCancelSleep(void) | ||||
| 		return false; | ||||
| 
 | ||||
| 	SpinLockAcquire(&cv->mutex); | ||||
| 	if (proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink)) | ||||
| 		proclist_delete(&cv->wakeup, MyProc->pgprocno, cvWaitLink); | ||||
| 	if (proclist_contains(&cv->wakeup, MyProcNumber, cvWaitLink)) | ||||
| 		proclist_delete(&cv->wakeup, MyProcNumber, cvWaitLink); | ||||
| 	else | ||||
| 		signaled = true; | ||||
| 	SpinLockRelease(&cv->mutex); | ||||
| @ -281,7 +281,7 @@ ConditionVariableSignal(ConditionVariable *cv) | ||||
| void | ||||
| ConditionVariableBroadcast(ConditionVariable *cv) | ||||
| { | ||||
| 	int			pgprocno = MyProc->pgprocno; | ||||
| 	int			pgprocno = MyProcNumber; | ||||
| 	PGPROC	   *proc = NULL; | ||||
| 	bool		have_sentinel = false; | ||||
| 
 | ||||
|  | ||||
| @ -1056,9 +1056,9 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode) | ||||
| 
 | ||||
| 	/* LW_WAIT_UNTIL_FREE waiters are always at the front of the queue */ | ||||
| 	if (mode == LW_WAIT_UNTIL_FREE) | ||||
| 		proclist_push_head(&lock->waiters, MyProc->pgprocno, lwWaitLink); | ||||
| 		proclist_push_head(&lock->waiters, MyProcNumber, lwWaitLink); | ||||
| 	else | ||||
| 		proclist_push_tail(&lock->waiters, MyProc->pgprocno, lwWaitLink); | ||||
| 		proclist_push_tail(&lock->waiters, MyProcNumber, lwWaitLink); | ||||
| 
 | ||||
| 	/* Can release the mutex now */ | ||||
| 	LWLockWaitListUnlock(lock); | ||||
| @ -1097,7 +1097,7 @@ LWLockDequeueSelf(LWLock *lock) | ||||
| 	 */ | ||||
| 	on_waitlist = MyProc->lwWaiting == LW_WS_WAITING; | ||||
| 	if (on_waitlist) | ||||
| 		proclist_delete(&lock->waiters, MyProc->pgprocno, lwWaitLink); | ||||
| 		proclist_delete(&lock->waiters, MyProcNumber, lwWaitLink); | ||||
| 
 | ||||
| 	if (proclist_is_empty(&lock->waiters) && | ||||
| 		(pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS) != 0) | ||||
|  | ||||
| @ -1830,7 +1830,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot, | ||||
| 	sxact->finishedBefore = InvalidTransactionId; | ||||
| 	sxact->xmin = snapshot->xmin; | ||||
| 	sxact->pid = MyProcPid; | ||||
| 	sxact->pgprocno = MyProc->pgprocno; | ||||
| 	sxact->pgprocno = MyProcNumber; | ||||
| 	dlist_init(&sxact->predicateLocks); | ||||
| 	dlist_node_init(&sxact->finishedLink); | ||||
| 	sxact->flags = 0; | ||||
|  | ||||
| @ -65,6 +65,7 @@ bool		log_lock_waits = false; | ||||
| 
 | ||||
| /* Pointer to this process's PGPROC struct, if any */ | ||||
| PGPROC	   *MyProc = NULL; | ||||
| int			MyProcNumber = INVALID_PGPROCNO; | ||||
| 
 | ||||
| /*
 | ||||
|  * This spinlock protects the freelist of recycled PGPROC structures. | ||||
| @ -228,7 +229,6 @@ InitProcGlobal(void) | ||||
| 			InitSharedLatch(&(proc->procLatch)); | ||||
| 			LWLockInitialize(&(proc->fpInfoLock), LWTRANCHE_LOCK_FASTPATH); | ||||
| 		} | ||||
| 		proc->pgprocno = i; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Newly created PGPROCs for normal backends, autovacuum and bgworkers | ||||
| @ -353,6 +353,7 @@ InitProcess(void) | ||||
| 				(errcode(ERRCODE_TOO_MANY_CONNECTIONS), | ||||
| 				 errmsg("sorry, too many clients already"))); | ||||
| 	} | ||||
| 	MyProcNumber = GetNumberFromPGProc(MyProc); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Cross-check that the PGPROC is of the type we expect; if this were not | ||||
| @ -566,6 +567,8 @@ InitAuxiliaryProcess(void) | ||||
| 
 | ||||
| 	SpinLockRelease(ProcStructLock); | ||||
| 
 | ||||
| 	MyProcNumber = GetNumberFromPGProc(MyProc); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Initialize all fields of MyProc, except for those previously | ||||
| 	 * initialized by InitProcGlobal. | ||||
| @ -907,6 +910,7 @@ ProcKill(int code, Datum arg) | ||||
| 
 | ||||
| 	proc = MyProc; | ||||
| 	MyProc = NULL; | ||||
| 	MyProcNumber = INVALID_PGPROCNO; | ||||
| 	DisownLatch(&proc->procLatch); | ||||
| 
 | ||||
| 	procgloballist = proc->procgloballist; | ||||
| @ -978,6 +982,7 @@ AuxiliaryProcKill(int code, Datum arg) | ||||
| 
 | ||||
| 	proc = MyProc; | ||||
| 	MyProc = NULL; | ||||
| 	MyProcNumber = INVALID_PGPROCNO; | ||||
| 	DisownLatch(&proc->procLatch); | ||||
| 
 | ||||
| 	SpinLockAcquire(ProcStructLock); | ||||
| @ -1903,10 +1908,9 @@ BecomeLockGroupMember(PGPROC *leader, int pid) | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Get lock protecting the group fields.  Note LockHashPartitionLockByProc | ||||
| 	 * accesses leader->pgprocno in a PGPROC that might be free.  This is safe | ||||
| 	 * because all PGPROCs' pgprocno fields are set during shared memory | ||||
| 	 * initialization and never change thereafter; so we will acquire the | ||||
| 	 * correct lock even if the leader PGPROC is in process of being recycled. | ||||
| 	 * calculates the proc number based on the PGPROC slot without looking at | ||||
| 	 * its contents, so we will acquire the correct lock even if the leader | ||||
| 	 * PGPROC is in process of being recycled. | ||||
| 	 */ | ||||
| 	leader_lwlock = LockHashPartitionLockByProc(leader); | ||||
| 	LWLockAcquire(leader_lwlock, LW_EXCLUSIVE); | ||||
|  | ||||
| @ -540,7 +540,7 @@ typedef enum | ||||
|  * used for a given lock group is determined by the group leader's pgprocno. | ||||
|  */ | ||||
| #define LockHashPartitionLockByProc(leader_pgproc) \ | ||||
| 	LockHashPartitionLock((leader_pgproc)->pgprocno) | ||||
| 	LockHashPartitionLock(GetNumberFromPGProc(leader_pgproc)) | ||||
| 
 | ||||
| /*
 | ||||
|  * function prototypes | ||||
|  | ||||
| @ -194,11 +194,6 @@ struct PGPROC | ||||
| 	int			pgxactoff;		/* offset into various ProcGlobal->arrays with
 | ||||
| 								 * 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: */ | ||||
| 	BackendId	backendId;		/* This backend's backend ID (if assigned) */ | ||||
| 	Oid			databaseId;		/* OID of database this backend is using */ | ||||
| @ -307,6 +302,7 @@ struct PGPROC | ||||
| 
 | ||||
| 
 | ||||
| extern PGDLLIMPORT PGPROC *MyProc; | ||||
| extern PGDLLIMPORT int MyProcNumber;	/* same as GetNumberFromPGProc(MyProc) */ | ||||
| 
 | ||||
| /*
 | ||||
|  * There is one ProcGlobal struct for the whole database cluster. | ||||
| @ -410,8 +406,9 @@ extern PGDLLIMPORT PROC_HDR *ProcGlobal; | ||||
| 
 | ||||
| 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 GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0]) | ||||
| 
 | ||||
| /*
 | ||||
|  * We set aside some extra PGPROC structures for auxiliary processes, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user