*** src/backend/storage/lmgr/lwlock.c.try1 Sat Dec 29 15:20:08 2001 --- src/backend/storage/lmgr/lwlock.c Sun Dec 30 12:11:47 2001 *************** *** 30,35 **** --- 30,36 ---- typedef struct LWLock { slock_t mutex; /* Protects LWLock and queue of PROCs */ + bool releaseOK; /* T if ok to release waiters */ char exclusive; /* # of exclusive holders (0 or 1) */ int shared; /* # of shared holders (0..MaxBackends) */ PROC *head; /* head of list of waiting PROCs */ *************** *** 67,75 **** PRINT_LWDEBUG(const char *where, LWLockId lockid, const volatile LWLock *lock) { if (Trace_lwlocks) ! elog(DEBUG, "%s(%d): excl %d shared %d head %p", where, (int) lockid, ! (int) lock->exclusive, lock->shared, lock->head); } inline static void --- 68,77 ---- PRINT_LWDEBUG(const char *where, LWLockId lockid, const volatile LWLock *lock) { if (Trace_lwlocks) ! elog(DEBUG, "%s(%d): excl %d shared %d head %p rOK %d", where, (int) lockid, ! (int) lock->exclusive, lock->shared, lock->head, ! (int) lock->releaseOK); } inline static void *************** *** 153,158 **** --- 155,161 ---- for (id = 0, lock = LWLockArray; id < numLocks; id++, lock++) { SpinLockInit(&lock->mutex); + lock->releaseOK = true; lock->exclusive = 0; lock->shared = 0; lock->head = NULL; *************** *** 196,201 **** --- 199,205 ---- { volatile LWLock *lock = LWLockArray + lockid; PROC *proc = MyProc; + bool retry = false; int extraWaits = 0; PRINT_LWDEBUG("LWLockAcquire", lockid, lock); *************** *** 230,235 **** --- 234,243 ---- /* Acquire mutex. Time spent holding mutex should be short! */ SpinLockAcquire_NoHoldoff(&lock->mutex); + /* If retrying, allow LWLockRelease to release waiters again */ + if (retry) + lock->releaseOK = true; + /* If I can get the lock, do so quickly. */ if (mode == LW_EXCLUSIVE) { *************** *** 303,308 **** --- 311,317 ---- LOG_LWDEBUG("LWLockAcquire", lockid, "awakened"); /* Now loop back and try to acquire lock again. */ + retry = true; } /* We are done updating shared state of the lock itself. */ *************** *** 427,438 **** /* * See if I need to awaken any waiters. If I released a non-last ! * shared hold, there cannot be anything to do. */ head = lock->head; if (head != NULL) { ! if (lock->exclusive == 0 && lock->shared == 0) { /* * Remove the to-be-awakened PROCs from the queue. If the --- 436,449 ---- /* * See if I need to awaken any waiters. If I released a non-last ! * shared hold, there cannot be anything to do. Also, do not awaken ! * any waiters if someone has already awakened waiters that haven't ! * yet acquired the lock. */ head = lock->head; if (head != NULL) { ! if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK) { /* * Remove the to-be-awakened PROCs from the queue. If the *************** *** 451,456 **** --- 462,469 ---- /* proc is now the last PROC to be released */ lock->head = proc->lwWaitLink; proc->lwWaitLink = NULL; + /* prevent additional wakeups until retryer gets to run */ + lock->releaseOK = false; } else {