Index: src/backend/storage/lmgr/lwlock.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/storage/lmgr/lwlock.c,v retrieving revision 1.49 diff -c -r1.49 lwlock.c *** src/backend/storage/lmgr/lwlock.c 15 Nov 2007 21:14:38 -0000 1.49 --- src/backend/storage/lmgr/lwlock.c 4 Dec 2007 11:20:20 -0000 *************** *** 42,47 **** --- 42,48 ---- int shared; /* # of shared holders (0..MaxBackends) */ PGPROC *head; /* head of list of waiting PGPROCs */ PGPROC *tail; /* tail of list of waiting PGPROCs */ + PGPROC *shared_tail; /* tail of list of shared waiters */ /* tail is undefined when head is NULL */ } LWLock; *************** *** 419,430 **** proc->lwWaiting = true; proc->lwExclusive = (mode == LW_EXCLUSIVE); ! proc->lwWaitLink = NULL; ! if (lock->head == NULL) ! lock->head = proc; else ! lock->tail->lwWaitLink = proc; ! lock->tail = proc; /* Can release the mutex now */ SpinLockRelease(&lock->mutex); --- 420,443 ---- proc->lwWaiting = true; proc->lwExclusive = (mode == LW_EXCLUSIVE); ! proc->lwWaitLink = NULL; /* back of the main queue */ ! ! if (mode == LW_EXCLUSIVE || lock->shared_tail == NULL) ! { ! if (lock->head == NULL) ! lock->head = proc; ! else ! lock->tail->lwWaitLink = proc; ! lock->tail = proc; ! } else ! lock->shared_tail->lwSWaitLink = proc; ! ! if (mode == LW_SHARED) ! { ! lock->shared_tail = proc; ! proc->lwSWaitLink = NULL; /* back of the shared queue */ ! } /* Can release the mutex now */ SpinLockRelease(&lock->mutex); *************** *** 604,620 **** if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK) { /* ! * Remove the to-be-awakened PGPROCs from the queue. If the front ! * waiter wants exclusive lock, awaken him only. Otherwise awaken ! * as many waiters as want shared access. */ proc = head; if (!proc->lwExclusive) ! { ! while (proc->lwWaitLink != NULL && ! !proc->lwWaitLink->lwExclusive) ! proc = proc->lwWaitLink; ! } /* proc is now the last PGPROC to be released */ lock->head = proc->lwWaitLink; proc->lwWaitLink = NULL; --- 617,628 ---- if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK) { /* ! * Remove the next PGPROC from the queue. There is only ever one ! * to remove whether it is X or S */ proc = head; if (!proc->lwExclusive) ! lock->shared_tail = NULL; /* proc is now the last PGPROC to be released */ lock->head = proc->lwWaitLink; proc->lwWaitLink = NULL; *************** *** 640,647 **** { LOG_LWDEBUG("LWLockRelease", lockid, "release waiter"); proc = head; ! head = proc->lwWaitLink; ! proc->lwWaitLink = NULL; proc->lwWaiting = false; PGSemaphoreUnlock(&proc->sem); } --- 648,663 ---- { LOG_LWDEBUG("LWLockRelease", lockid, "release waiter"); proc = head; ! if (proc->lwExclusive) ! { ! head = proc->lwWaitLink; ! proc->lwWaitLink = NULL; ! } ! else ! { ! head = proc->lwSWaitLink; ! proc->lwSWaitLink = NULL; ! } proc->lwWaiting = false; PGSemaphoreUnlock(&proc->sem); } Index: src/backend/storage/lmgr/proc.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/storage/lmgr/proc.c,v retrieving revision 1.197 diff -c -r1.197 proc.c *** src/backend/storage/lmgr/proc.c 15 Nov 2007 21:14:38 -0000 1.197 --- src/backend/storage/lmgr/proc.c 4 Dec 2007 11:18:30 -0000 *************** *** 297,302 **** --- 297,303 ---- MyProc->lwWaiting = false; MyProc->lwExclusive = false; MyProc->lwWaitLink = NULL; + MyProc->lwSWaitLink = NULL; MyProc->waitLock = NULL; MyProc->waitProcLock = NULL; for (i = 0; i < NUM_LOCK_PARTITIONS; i++) Index: src/include/storage/proc.h =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/storage/proc.h,v retrieving revision 1.102 diff -c -r1.102 proc.h *** src/include/storage/proc.h 15 Nov 2007 21:14:44 -0000 1.102 --- src/include/storage/proc.h 4 Dec 2007 11:18:15 -0000 *************** *** 97,102 **** --- 97,103 ---- bool lwWaiting; /* true if waiting for an LW lock */ bool lwExclusive; /* true if waiting for exclusive access */ struct PGPROC *lwWaitLink; /* next waiter for same LW lock */ + struct PGPROC *lwSWaitLink; /* next waiter for same LW lock */ /* Info about lock the process is currently waiting for, if any. */ /* waitLock and waitProcLock are NULL if not currently waiting. */