{
volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
+ int pgprocno = MyProcNumber;
uint32 nextidx;
uint32 wakeidx;
* 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
if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
&nextidx,
- (uint32) proc->pgprocno))
+ (uint32) pgprocno))
break;
}
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
/* 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))
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;
{
GlobalTransaction gxact = TwoPhaseGetGXact(xid, lock_held);
- return &ProcGlobal->allProcs[gxact->pgprocno];
+ return GetPGProcByNumber(gxact->pgprocno);
}
/************************************************************************/
void
StartPrepare(GlobalTransaction gxact)
{
- PGPROC *proc = &ProcGlobal->allProcs[gxact->pgprocno];
+ PGPROC *proc = GetPGProcByNumber(gxact->pgprocno);
TransactionId xid = gxact->xid;
TwoPhaseFileHeader hdr;
TransactionId *children;
* try to commit the same GID at once.
*/
gxact = LockGXact(gid, GetUserId());
- proc = &ProcGlobal->allProcs[gxact->pgprocno];
+ proc = GetPGProcByNumber(gxact->pgprocno);
xid = gxact->xid;
/*
static int lockToTry = -1;
if (lockToTry == -1)
- lockToTry = MyProc->pgprocno % NUM_XLOGINSERT_LOCKS;
+ lockToTry = MyProcNumber % NUM_XLOGINSERT_LOCKS;
MyLockNo = lockToTry;
/*
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,
* 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));
/* 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. */
* 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);
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);
*/
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);
void
ProcArrayAdd(PGPROC *proc)
{
+ int pgprocno = GetNumberFromPGProc(proc);
ProcArrayStruct *arrayP = procArray;
int index;
int movecount;
*/
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;
}
&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;
static void
ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
{
+ int pgprocno = GetNumberFromPGProc(proc);
PROC_HDR *procglobal = ProcGlobal;
uint32 nextidx;
uint32 wakeidx;
if (pg_atomic_compare_exchange_u32(&procglobal->procArrayGroupFirst,
&nextidx,
- (uint32) proc->pgprocno))
+ (uint32) pgprocno))
break;
}
void
ConditionVariablePrepareToSleep(ConditionVariable *cv)
{
- int pgprocno = MyProc->pgprocno;
+ int pgprocno = MyProcNumber;
/*
* If some other sleep is already prepared, cancel it; this is necessary
* 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);
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);
void
ConditionVariableBroadcast(ConditionVariable *cv)
{
- int pgprocno = MyProc->pgprocno;
+ int pgprocno = MyProcNumber;
PGPROC *proc = NULL;
bool have_sentinel = false;
/* 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);
*/
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)
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;
/* 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.
InitSharedLatch(&(proc->procLatch));
LWLockInitialize(&(proc->fpInfoLock), LWTRANCHE_LOCK_FASTPATH);
}
- proc->pgprocno = i;
/*
* Newly created PGPROCs for normal backends, autovacuum and bgworkers
(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
SpinLockRelease(ProcStructLock);
+ MyProcNumber = GetNumberFromPGProc(MyProc);
+
/*
* Initialize all fields of MyProc, except for those previously
* initialized by InitProcGlobal.
proc = MyProc;
MyProc = NULL;
+ MyProcNumber = INVALID_PGPROCNO;
DisownLatch(&proc->procLatch);
procgloballist = proc->procgloballist;
proc = MyProc;
MyProc = NULL;
+ MyProcNumber = INVALID_PGPROCNO;
DisownLatch(&proc->procLatch);
SpinLockAcquire(ProcStructLock);
/*
* 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);
* 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
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 */
extern PGDLLIMPORT PGPROC *MyProc;
+extern PGDLLIMPORT int MyProcNumber; /* same as GetNumberFromPGProc(MyProc) */
/*
* There is one ProcGlobal struct for the whole database cluster.
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,