88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.97 2001/01/25 03:31:16 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.98 2001/01/26 18:23:12 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -537,13 +537,18 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
537537 * me to before that waiter anyway; but it's relatively cheap to detect
538538 * such a conflict immediately, and avoid delaying till deadlock timeout.
539539 *
540- * Special case: if I find I should go in front of the first waiter,
541- * and I do not conflict with already-held locks, then just grant myself
542- * the requested lock immediately.
540+ * Special case: if I find I should go in front of some waiter, check
541+ * to see if I conflict with already-held locks or the requests before
542+ * that waiter. If not, then just grant myself the requested lock
543+ * immediately. This is the same as the test for immediate grant in
544+ * LockAcquire, except we are only considering the part of the wait queue
545+ * before my insertion point.
543546 * ----------------------
544547 */
545548 if (myHeldLocks != 0 )
546549 {
550+ int aheadRequests = 0 ;
551+
547552 proc = (PROC * ) MAKE_PTR (waitQueue -> links .next );
548553 for (i = 0 ; i < waitQueue -> size ; i ++ )
549554 {
@@ -557,26 +562,30 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable,
557562 MyProc -> errType = STATUS_ERROR ;
558563 return STATUS_ERROR ;
559564 }
560- if (i == 0 )
565+ /* I must go before this waiter. Check special case. */
566+ if ((lockctl -> conflictTab [lockmode ] & aheadRequests ) == 0 &&
567+ LockCheckConflicts (lockMethodTable ,
568+ lockmode ,
569+ lock ,
570+ holder ,
571+ MyProc ,
572+ NULL ) == STATUS_OK )
561573 {
562- /* I must go before first waiter. Check special case. */
563- if (LockCheckConflicts (lockMethodTable ,
564- lockmode ,
565- lock ,
566- holder ,
567- MyProc ,
568- NULL ) == STATUS_OK )
569- {
570- /* Skip the wait and just grant myself the lock. */
571- GrantLock (lock , holder , lockmode );
572- return STATUS_OK ;
573- }
574+ /* Skip the wait and just grant myself the lock. */
575+ GrantLock (lock , holder , lockmode );
576+ return STATUS_OK ;
574577 }
575578 /* Break out of loop to put myself before him */
576579 break ;
577580 }
581+ /* Nope, so advance to next waiter */
582+ aheadRequests |= (1 << proc -> waitLockMode );
578583 proc = (PROC * ) MAKE_PTR (proc -> links .next );
579584 }
585+ /*
586+ * If we fall out of loop normally, proc points to waitQueue head,
587+ * so we will insert at tail of queue as desired.
588+ */
580589 }
581590 else
582591 {
@@ -739,7 +748,7 @@ ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock)
739748 PROC_QUEUE * waitQueue = & (lock -> waitProcs );
740749 int queue_size = waitQueue -> size ;
741750 PROC * proc ;
742- int conflictMask = 0 ;
751+ int aheadRequests = 0 ;
743752
744753 Assert (queue_size >= 0 );
745754
@@ -756,7 +765,7 @@ ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock)
756765 * Waken if (a) doesn't conflict with requests of earlier waiters,
757766 * and (b) doesn't conflict with already-held locks.
758767 */
759- if ((( 1 << lockmode ) & conflictMask ) == 0 &&
768+ if ((lockctl -> conflictTab [ lockmode ] & aheadRequests ) == 0 &&
760769 LockCheckConflicts (lockMethodTable ,
761770 lockmode ,
762771 lock ,
@@ -775,8 +784,8 @@ ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock)
775784 }
776785 else
777786 {
778- /* Cannot wake this guy. Add his request to conflict mask . */
779- conflictMask |= lockctl -> conflictTab [ lockmode ] ;
787+ /* Cannot wake this guy. Remember his request for later checks . */
788+ aheadRequests |= ( 1 << lockmode ) ;
780789 proc = (PROC * ) MAKE_PTR (proc -> links .next );
781790 }
782791 }
0 commit comments