Commit 9540d978 authored by Bruce Momjian's avatar Bruce Momjian

FIFO lock wait queue, with readers grouped together.

parent 9a550134
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.30 1998/01/28 02:29:29 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.31 1998/02/19 15:04:45 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
* This is so that we can support more backends. (system-wide semaphore * This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95 * sets run out pretty fast.) -ay 4/95
* *
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.30 1998/01/28 02:29:29 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.31 1998/02/19 15:04:45 momjian Exp $
*/ */
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
...@@ -451,19 +451,42 @@ ProcSleep(PROC_QUEUE *waitQueue, ...@@ -451,19 +451,42 @@ ProcSleep(PROC_QUEUE *waitQueue,
int prio, int prio,
LOCK *lock) LOCK *lock)
{ {
int i; int i = 0;
PROC *proc; PROC *proc;
struct itimerval timeval, struct itimerval timeval,
dummy; dummy;
/*
* If the first entries in the waitQueue have a greater priority than
* we have, we must be a reader, and they must be a writers, and we
* must be here because the current holder is a writer or a
* reader but we don't share shared locks if a writer is waiting.
* We put ourselves after the writers. This way, we have a FIFO, but
* keep the readers together to give them decent priority, and no one
* starves. Because we group all readers together, a non-empty queue
* only has a few possible configurations:
*
* [readers]
* [writers]
* [readers][writers]
* [writers][readers]
* [writers][readers][writers]
*
* In a full queue, we would have a reader holding a lock, then a
* writer gets the lock, then a bunch of readers, made up of readers
* who could not share the first readlock because a writer was waiting,
* and new readers arriving while the writer had the lock.
*
*/
proc = (PROC *) MAKE_PTR(waitQueue->links.prev); proc = (PROC *) MAKE_PTR(waitQueue->links.prev);
for (i = 0; i < waitQueue->size; i++)
{ /* If we are a reader, and they are writers, skip past them */
if (proc->prio >= prio) while (i++ < waitQueue->size && proc->prio > prio)
proc = (PROC *) MAKE_PTR(proc->links.prev);
/* The rest of the queue is FIFO, with readers first, writers last */
while (i++ < waitQueue->size && proc->prio <= prio)
proc = (PROC *) MAKE_PTR(proc->links.prev); proc = (PROC *) MAKE_PTR(proc->links.prev);
else
break;
}
MyProc->prio = prio; MyProc->prio = prio;
MyProc->token = token; MyProc->token = token;
...@@ -596,8 +619,7 @@ ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock) ...@@ -596,8 +619,7 @@ ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock)
/* /*
* ProcWakeup removes proc from the lock waiting process queue and * ProcWakeup removes proc from the lock waiting process queue and
* returns the next proc in chain. If a writer just dropped its * returns the next proc in chain.
* lock and there are several waiting readers, wake them all up.
*/ */
proc = ProcWakeup(proc, NO_ERROR); proc = ProcWakeup(proc, NO_ERROR);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment