|
7 | 7 | *
|
8 | 8 | *
|
9 | 9 | * IDENTIFICATION
|
10 |
| - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.30 1998/01/28 02:29:29 momjian Exp $ |
| 10 | + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.31 1998/02/19 15:04:45 momjian Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
|
46 | 46 | *This is so that we can support more backends. (system-wide semaphore
|
47 | 47 | *sets run out pretty fast.) -ay 4/95
|
48 | 48 | *
|
49 |
| - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.30 1998/01/28 02:29:29 momjian Exp $ |
| 49 | + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.31 1998/02/19 15:04:45 momjian Exp $ |
50 | 50 | */
|
51 | 51 | #include<sys/time.h>
|
52 | 52 | #include<unistd.h>
|
@@ -451,19 +451,42 @@ ProcSleep(PROC_QUEUE *waitQueue,
|
451 | 451 | intprio,
|
452 | 452 | LOCK*lock)
|
453 | 453 | {
|
454 |
| -inti; |
| 454 | +inti=0; |
455 | 455 | PROC*proc;
|
456 | 456 | structitimervaltimeval,
|
457 | 457 | dummy;
|
458 | 458 |
|
| 459 | +/* |
| 460 | + *If the first entries in the waitQueue have a greater priority than |
| 461 | + *we have, we must be a reader, and they must be a writers, and we |
| 462 | + *must be here because the current holder is a writer or a |
| 463 | + *reader but we don't share shared locks if a writer is waiting. |
| 464 | + *We put ourselves after the writers. This way, we have a FIFO, but |
| 465 | + *keep the readers together to give them decent priority, and no one |
| 466 | + *starves. Because we group all readers together, a non-empty queue |
| 467 | + *only has a few possible configurations: |
| 468 | + * |
| 469 | + *[readers] |
| 470 | + *[writers] |
| 471 | + *[readers][writers] |
| 472 | + *[writers][readers] |
| 473 | + *[writers][readers][writers] |
| 474 | + * |
| 475 | + *In a full queue, we would have a reader holding a lock, then a |
| 476 | + *writer gets the lock, then a bunch of readers, made up of readers |
| 477 | + *who could not share the first readlock because a writer was waiting, |
| 478 | + *and new readers arriving while the writer had the lock. |
| 479 | + * |
| 480 | + */ |
459 | 481 | proc= (PROC*)MAKE_PTR(waitQueue->links.prev);
|
460 |
| -for (i=0;i<waitQueue->size;i++) |
461 |
| -{ |
462 |
| -if (proc->prio >=prio) |
463 |
| -proc= (PROC*)MAKE_PTR(proc->links.prev); |
464 |
| -else |
465 |
| -break; |
466 |
| -} |
| 482 | + |
| 483 | +/* If we are a reader, and they are writers, skip past them */ |
| 484 | +while (i++<waitQueue->size&&proc->prio>prio) |
| 485 | +proc= (PROC*)MAKE_PTR(proc->links.prev); |
| 486 | + |
| 487 | +/* The rest of the queue is FIFO, with readers first, writers last */ |
| 488 | +while (i++<waitQueue->size&&proc->prio <=prio) |
| 489 | +proc= (PROC*)MAKE_PTR(proc->links.prev); |
467 | 490 |
|
468 | 491 | MyProc->prio=prio;
|
469 | 492 | MyProc->token=token;
|
@@ -596,8 +619,7 @@ ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock)
|
596 | 619 |
|
597 | 620 | /*
|
598 | 621 | * ProcWakeup removes proc from the lock waiting process queue and
|
599 |
| - * returns the next proc in chain.If a writer just dropped its |
600 |
| - * lock and there are several waiting readers, wake them all up. |
| 622 | + * returns the next proc in chain. |
601 | 623 | */
|
602 | 624 | proc=ProcWakeup(proc,NO_ERROR);
|
603 | 625 |
|
|