Compare commits

..

No commits in common. "5f6ec27a64774b10ff8522bc745e5e993503011d" and "7a7c8c98a610418ed0118e22a1793bf27e55783a" have entirely different histories.

7 changed files with 30 additions and 46 deletions

View File

@ -482,7 +482,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid,
proc->roleId = owner; proc->roleId = owner;
proc->tempNamespaceId = InvalidOid; proc->tempNamespaceId = InvalidOid;
proc->isBackgroundWorker = false; proc->isBackgroundWorker = false;
proc->lwWaiting = LW_WS_NOT_WAITING; proc->lwWaiting = false;
proc->lwWaitMode = 0; proc->lwWaitMode = 0;
proc->waitLock = NULL; proc->waitLock = NULL;
proc->waitProcLock = NULL; proc->waitProcLock = NULL;

View File

@ -298,7 +298,6 @@ pgwin32_socket(int af, int type, int protocol)
if (ioctlsocket(s, FIONBIO, &on)) if (ioctlsocket(s, FIONBIO, &on))
{ {
TranslateSocketError(); TranslateSocketError();
closesocket(s);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
errno = 0; errno = 0;

View File

@ -993,15 +993,6 @@ LWLockWakeup(LWLock *lock)
wokeup_somebody = true; wokeup_somebody = true;
} }
/*
* Signal that the process isn't on the wait list anymore. This allows
* LWLockDequeueSelf() to remove itself of the waitlist with a
* proclist_delete(), rather than having to check if it has been
* removed from the list.
*/
Assert(waiter->lwWaiting == LW_WS_WAITING);
waiter->lwWaiting = LW_WS_PENDING_WAKEUP;
/* /*
* Once we've woken up an exclusive lock, there's no point in waking * Once we've woken up an exclusive lock, there's no point in waking
* up anybody else. * up anybody else.
@ -1059,7 +1050,7 @@ LWLockWakeup(LWLock *lock)
* another lock. * another lock.
*/ */
pg_write_barrier(); pg_write_barrier();
waiter->lwWaiting = LW_WS_NOT_WAITING; waiter->lwWaiting = false;
PGSemaphoreUnlock(waiter->sem); PGSemaphoreUnlock(waiter->sem);
} }
} }
@ -1080,7 +1071,7 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
if (MyProc == NULL) if (MyProc == NULL)
elog(PANIC, "cannot wait without a PGPROC structure"); elog(PANIC, "cannot wait without a PGPROC structure");
if (MyProc->lwWaiting != LW_WS_NOT_WAITING) if (MyProc->lwWaiting)
elog(PANIC, "queueing for lock while waiting on another one"); elog(PANIC, "queueing for lock while waiting on another one");
LWLockWaitListLock(lock); LWLockWaitListLock(lock);
@ -1088,7 +1079,7 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
/* setting the flag is protected by the spinlock */ /* setting the flag is protected by the spinlock */
pg_atomic_fetch_or_u32(&lock->state, LW_FLAG_HAS_WAITERS); pg_atomic_fetch_or_u32(&lock->state, LW_FLAG_HAS_WAITERS);
MyProc->lwWaiting = LW_WS_WAITING; MyProc->lwWaiting = true;
MyProc->lwWaitMode = mode; MyProc->lwWaitMode = 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 */
@ -1116,7 +1107,8 @@ LWLockQueueSelf(LWLock *lock, LWLockMode mode)
static void static void
LWLockDequeueSelf(LWLock *lock) LWLockDequeueSelf(LWLock *lock)
{ {
bool on_waitlist; bool found = false;
proclist_mutable_iter iter;
#ifdef LWLOCK_STATS #ifdef LWLOCK_STATS
lwlock_stats *lwstats; lwlock_stats *lwstats;
@ -1129,13 +1121,18 @@ LWLockDequeueSelf(LWLock *lock)
LWLockWaitListLock(lock); LWLockWaitListLock(lock);
/* /*
* Remove ourselves from the waitlist, unless we've already been * Can't just remove ourselves from the list, but we need to iterate over
* removed. The removal happens with the wait list lock held, so there's * all entries as somebody else could have dequeued us.
* no race in this check.
*/ */
on_waitlist = MyProc->lwWaiting == LW_WS_WAITING; proclist_foreach_modify(iter, &lock->waiters, lwWaitLink)
if (on_waitlist) {
proclist_delete(&lock->waiters, MyProc->pgprocno, lwWaitLink); if (iter.cur == MyProc->pgprocno)
{
found = true;
proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
break;
}
}
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)
@ -1147,8 +1144,8 @@ LWLockDequeueSelf(LWLock *lock)
LWLockWaitListUnlock(lock); LWLockWaitListUnlock(lock);
/* clear waiting state again, nice for debugging */ /* clear waiting state again, nice for debugging */
if (on_waitlist) if (found)
MyProc->lwWaiting = LW_WS_NOT_WAITING; MyProc->lwWaiting = false;
else else
{ {
int extraWaits = 0; int extraWaits = 0;
@ -1172,7 +1169,7 @@ LWLockDequeueSelf(LWLock *lock)
for (;;) for (;;)
{ {
PGSemaphoreLock(MyProc->sem); PGSemaphoreLock(MyProc->sem);
if (MyProc->lwWaiting == LW_WS_NOT_WAITING) if (!MyProc->lwWaiting)
break; break;
extraWaits++; extraWaits++;
} }
@ -1323,7 +1320,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
for (;;) for (;;)
{ {
PGSemaphoreLock(proc->sem); PGSemaphoreLock(proc->sem);
if (proc->lwWaiting == LW_WS_NOT_WAITING) if (!proc->lwWaiting)
break; break;
extraWaits++; extraWaits++;
} }
@ -1488,7 +1485,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
for (;;) for (;;)
{ {
PGSemaphoreLock(proc->sem); PGSemaphoreLock(proc->sem);
if (proc->lwWaiting == LW_WS_NOT_WAITING) if (!proc->lwWaiting)
break; break;
extraWaits++; extraWaits++;
} }
@ -1704,7 +1701,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
for (;;) for (;;)
{ {
PGSemaphoreLock(proc->sem); PGSemaphoreLock(proc->sem);
if (proc->lwWaiting == LW_WS_NOT_WAITING) if (!proc->lwWaiting)
break; break;
extraWaits++; extraWaits++;
} }
@ -1782,10 +1779,6 @@ LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
proclist_delete(&lock->waiters, iter.cur, lwWaitLink); proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
proclist_push_tail(&wakeup, iter.cur, lwWaitLink); proclist_push_tail(&wakeup, iter.cur, lwWaitLink);
/* see LWLockWakeup() */
Assert(waiter->lwWaiting == LW_WS_WAITING);
waiter->lwWaiting = LW_WS_PENDING_WAKEUP;
} }
/* We are done updating shared state of the lock itself. */ /* We are done updating shared state of the lock itself. */
@ -1801,7 +1794,7 @@ LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
proclist_delete(&wakeup, iter.cur, lwWaitLink); proclist_delete(&wakeup, iter.cur, lwWaitLink);
/* check comment in LWLockWakeup() about this barrier */ /* check comment in LWLockWakeup() about this barrier */
pg_write_barrier(); pg_write_barrier();
waiter->lwWaiting = LW_WS_NOT_WAITING; waiter->lwWaiting = false;
PGSemaphoreUnlock(waiter->sem); PGSemaphoreUnlock(waiter->sem);
} }
} }

View File

@ -400,7 +400,7 @@ InitProcess(void)
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */ /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
if (IsAutoVacuumWorkerProcess()) if (IsAutoVacuumWorkerProcess())
MyProc->statusFlags |= PROC_IS_AUTOVACUUM; MyProc->statusFlags |= PROC_IS_AUTOVACUUM;
MyProc->lwWaiting = LW_WS_NOT_WAITING; MyProc->lwWaiting = false;
MyProc->lwWaitMode = 0; MyProc->lwWaitMode = 0;
MyProc->waitLock = NULL; MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL; MyProc->waitProcLock = NULL;
@ -583,7 +583,7 @@ InitAuxiliaryProcess(void)
MyProc->delayChkpt = false; MyProc->delayChkpt = false;
MyProc->delayChkptEnd = false; MyProc->delayChkptEnd = false;
MyProc->statusFlags = 0; MyProc->statusFlags = 0;
MyProc->lwWaiting = LW_WS_NOT_WAITING; MyProc->lwWaiting = false;
MyProc->lwWaitMode = 0; MyProc->lwWaitMode = 0;
MyProc->waitLock = NULL; MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL; MyProc->waitProcLock = NULL;

View File

@ -263,9 +263,9 @@ pgstat_beinit(void)
* Assign the MyBEEntry for an auxiliary process. Since it doesn't * Assign the MyBEEntry for an auxiliary process. Since it doesn't
* have a BackendId, the slot is statically allocated based on the * have a BackendId, the slot is statically allocated based on the
* auxiliary process type (MyAuxProcType). Backends use slots indexed * auxiliary process type (MyAuxProcType). Backends use slots indexed
* in the range from 0 to MaxBackends (exclusive), so we use * in the range from 1 to MaxBackends (inclusive), so we use
* MaxBackends + AuxProcType as the index of the slot for an auxiliary * MaxBackends + AuxBackendType + 1 as the index of the slot for an
* process. * auxiliary process.
*/ */
MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType]; MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType];
} }

View File

@ -23,14 +23,6 @@
struct PGPROC; struct PGPROC;
/* what state of the wait process is a backend in */
typedef enum LWLockWaitState
{
LW_WS_NOT_WAITING, /* not currently waiting / woken up */
LW_WS_WAITING, /* currently waiting */
LW_WS_PENDING_WAKEUP /* removed from waitlist, but not yet signalled */
} LWLockWaitState;
/* /*
* Code outside of lwlock.c should not manipulate the contents of this * Code outside of lwlock.c should not manipulate the contents of this
* structure directly, but we have to declare it here to allow LWLocks to be * structure directly, but we have to declare it here to allow LWLocks to be

View File

@ -180,7 +180,7 @@ struct PGPROC
bool recoveryConflictPending; bool recoveryConflictPending;
/* Info about LWLock the process is currently waiting for, if any. */ /* Info about LWLock the process is currently waiting for, if any. */
uint8 lwWaiting; /* see LWLockWaitState */ bool lwWaiting; /* true if waiting for an LW lock */
uint8 lwWaitMode; /* lwlock mode being waited for */ uint8 lwWaitMode; /* lwlock mode being waited for */
proclist_node lwWaitLink; /* position in LW lock wait list */ proclist_node lwWaitLink; /* position in LW lock wait list */