aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/storage/lmgr/lwlock.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 7ffa87d914b..303e99c65b2 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -84,6 +84,7 @@
#include "storage/ipc.h"
#include "storage/predicate.h"
#include "storage/proc.h"
+#include "storage/proclist.h"
#include "storage/spin.h"
#include "utils/memutils.h"
@@ -717,7 +718,7 @@ LWLockInitialize(LWLock *lock, int tranche_id)
pg_atomic_init_u32(&lock->nwaiters, 0);
#endif
lock->tranche = tranche_id;
- dlist_init(&lock->waiters);
+ proclist_init(&lock->waiters);
}
/*
@@ -920,25 +921,25 @@ LWLockWakeup(LWLock *lock)
{
bool new_release_ok;
bool wokeup_somebody = false;
- dlist_head wakeup;
- dlist_mutable_iter iter;
+ proclist_head wakeup;
+ proclist_mutable_iter iter;
- dlist_init(&wakeup);
+ proclist_init(&wakeup);
new_release_ok = true;
/* lock wait list while collecting backends to wake up */
LWLockWaitListLock(lock);
- dlist_foreach_modify(iter, &lock->waiters)
+ proclist_foreach_modify(iter, &lock->waiters, lwWaitLink)
{
- PGPROC *waiter = dlist_container(PGPROC, lwWaitLink, iter.cur);
+ PGPROC *waiter = GetPGProcByNumber(iter.cur);
if (wokeup_somebody && waiter->lwWaitMode == LW_EXCLUSIVE)
continue;
- dlist_delete(&waiter->lwWaitLink);
- dlist_push_tail(&wakeup, &waiter->lwWaitLink);
+ proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
+ proclist_push_tail(&wakeup, iter.cur, lwWaitLink);
if (waiter->lwWaitMode != LW_WAIT_UNTIL_FREE)
{
@@ -963,7 +964,7 @@ LWLockWakeup(LWLock *lock)
break;
}
- Assert(dlist_is_empty(&wakeup) || pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS);
+ Assert(proclist_is_empty(&wakeup) || pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS);
/* unset required flags, and release lock, in one fell swoop */
{
@@ -982,7 +983,7 @@ LWLockWakeup(LWLock *lock)
else
desired_state &= ~LW_FLAG_RELEASE_OK;
- if (dlist_is_empty(&wakeup))
+ if (proclist_is_empty(&wakeup))
desired_state &= ~LW_FLAG_HAS_WAITERS;
desired_state &= ~LW_FLAG_LOCKED; /* release lock */
@@ -994,12 +995,12 @@ LWLockWakeup(LWLock *lock)
}
/* Awaken any waiters I removed from the queue. */
- dlist_foreach_modify(iter, &wakeup)
+ proclist_foreach_modify(iter, &wakeup, lwWaitLink)
{
- PGPROC *waiter = dlist_container(PGPROC, lwWaitLink, iter.cur);
+ PGPROC *waiter = GetPGProcByNumber(iter.cur);
LOG_LWDEBUG("LWLockRelease", lock, "release waiter");
- dlist_delete(&waiter->lwWaitLink);
+ proclist_delete(&wakeup, iter.cur, lwWaitLink);
/*
* Guarantee that lwWaiting being unset only becomes visible once the
@@ -1046,9 +1047,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)
- dlist_push_head(&lock->waiters, &MyProc->lwWaitLink);
+ proclist_push_head(&lock->waiters, MyProc->pgprocno, lwWaitLink);
else
- dlist_push_tail(&lock->waiters, &MyProc->lwWaitLink);
+ proclist_push_tail(&lock->waiters, MyProc->pgprocno, lwWaitLink);
/* Can release the mutex now */
LWLockWaitListUnlock(lock);
@@ -1070,7 +1071,7 @@ static void
LWLockDequeueSelf(LWLock *lock)
{
bool found = false;
- dlist_mutable_iter iter;
+ proclist_mutable_iter iter;
#ifdef LWLOCK_STATS
lwlock_stats *lwstats;
@@ -1086,19 +1087,17 @@ LWLockDequeueSelf(LWLock *lock)
* Can't just remove ourselves from the list, but we need to iterate over
* all entries as somebody else could have unqueued us.
*/
- dlist_foreach_modify(iter, &lock->waiters)
+ proclist_foreach_modify(iter, &lock->waiters, lwWaitLink)
{
- PGPROC *proc = dlist_container(PGPROC, lwWaitLink, iter.cur);
-
- if (proc == MyProc)
+ if (iter.cur == MyProc->pgprocno)
{
found = true;
- dlist_delete(&proc->lwWaitLink);
+ proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
break;
}
}
- if (dlist_is_empty(&lock->waiters) &&
+ if (proclist_is_empty(&lock->waiters) &&
(pg_atomic_read_u32(&lock->state) & LW_FLAG_HAS_WAITERS) != 0)
{
pg_atomic_fetch_and_u32(&lock->state, ~LW_FLAG_HAS_WAITERS);
@@ -1719,12 +1718,12 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
void
LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
{
- dlist_head wakeup;
- dlist_mutable_iter iter;
+ proclist_head wakeup;
+ proclist_mutable_iter iter;
PRINT_LWDEBUG("LWLockUpdateVar", lock, LW_EXCLUSIVE);
- dlist_init(&wakeup);
+ proclist_init(&wakeup);
LWLockWaitListLock(lock);
@@ -1737,15 +1736,15 @@ LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
* See if there are any LW_WAIT_UNTIL_FREE waiters that need to be woken
* up. They are always in the front of the queue.
*/
- dlist_foreach_modify(iter, &lock->waiters)
+ proclist_foreach_modify(iter, &lock->waiters, lwWaitLink)
{
- PGPROC *waiter = dlist_container(PGPROC, lwWaitLink, iter.cur);
+ PGPROC *waiter = GetPGProcByNumber(iter.cur);
if (waiter->lwWaitMode != LW_WAIT_UNTIL_FREE)
break;
- dlist_delete(&waiter->lwWaitLink);
- dlist_push_tail(&wakeup, &waiter->lwWaitLink);
+ proclist_delete(&lock->waiters, iter.cur, lwWaitLink);
+ proclist_push_tail(&wakeup, iter.cur, lwWaitLink);
}
/* We are done updating shared state of the lock itself. */
@@ -1754,11 +1753,11 @@ LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val)
/*
* Awaken any waiters I removed from the queue.
*/
- dlist_foreach_modify(iter, &wakeup)
+ proclist_foreach_modify(iter, &wakeup, lwWaitLink)
{
- PGPROC *waiter = dlist_container(PGPROC, lwWaitLink, iter.cur);
+ PGPROC *waiter = GetPGProcByNumber(iter.cur);
- dlist_delete(&waiter->lwWaitLink);
+ proclist_delete(&wakeup, iter.cur, lwWaitLink);
/* check comment in LWLockWakeup() about this barrier */
pg_write_barrier();
waiter->lwWaiting = false;