From 3011a8228a04a54e04f5626e9f686840a25f2d5f Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 26 Dec 2011 20:51:33 -0500 Subject: [PATCH] Windows: add osi_TWaitExt(), fix osi_TWait() osi_TWait() was adding new locks to the turnstile at the tail which is the end of the queue locks are removed from. This implemented LIFO instead of FIFO when FIFO is the "fair" order to service lock requests. osi_TWaitExt() is added to permit the Reader to Writer upgrade request to use LIFO when more than one reader is present. Change-Id: Ib6435a3edc2cb8519939cfad93e0db4b0604da2d Reviewed-on: http://gerrit.openafs.org/6435 Tested-by: BuildBot Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- src/WINNT/client_osi/osibasel.c | 2 +- src/WINNT/client_osi/osisleep.c | 12 +++++++++--- src/WINNT/client_osi/osisleep.h | 4 ++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/WINNT/client_osi/osibasel.c b/src/WINNT/client_osi/osibasel.c index 20444f8..192a22c 100644 --- a/src/WINNT/client_osi/osibasel.c +++ b/src/WINNT/client_osi/osibasel.c @@ -445,7 +445,7 @@ void lock_ConvertRToW(osi_rwlock_t *lockp) osi_assertx(lockp->readers > 0, "read lock underflow"); lockp->waiters++; - osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, lockp->tid, csp); + osi_TWaitExt(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, lockp->tid, csp, FALSE); lockp->waiters--; osi_assertx(lockp->waiters >= 0, "waiters underflow"); osi_assert(lockp->readers == 0 && (lockp->flags & OSI_LOCKFLAG_EXCL)); diff --git a/src/WINNT/client_osi/osisleep.c b/src/WINNT/client_osi/osisleep.c index a810936..5b2e0d4 100644 --- a/src/WINNT/client_osi/osisleep.c +++ b/src/WINNT/client_osi/osisleep.c @@ -260,6 +260,11 @@ void osi_Init(void) void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, CRITICAL_SECTION *releasep) { + osi_TWaitExt(turnp, waitFor, patchp, tidp, releasep, TRUE); +} + +void osi_TWaitExt(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, CRITICAL_SECTION *releasep, int prepend) +{ osi_sleepInfo_t *sp; unsigned int code; @@ -275,9 +280,10 @@ void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, C sp->waitFor = waitFor; sp->value = (LONG_PTR) patchp; sp->tidp = tidp; - osi_QAddT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q); - if (!turnp->lastp) - turnp->lastp = sp; + if (prepend) + osi_QAddH((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q); + else + osi_QAddT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q); LeaveCriticalSection(releasep); /* now wait for the signal */ diff --git a/src/WINNT/client_osi/osisleep.h b/src/WINNT/client_osi/osisleep.h index 0c3fe46..b833d26 100644 --- a/src/WINNT/client_osi/osisleep.h +++ b/src/WINNT/client_osi/osisleep.h @@ -149,6 +149,10 @@ extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, Crit_Sec *releasep); +extern void osi_TWaitExt(osi_turnstile_t *turnp, int waitFor, + void *patchp, DWORD *tidp, + Crit_Sec *releasep, int prepend); + extern void osi_TSignal(osi_turnstile_t *turnp); extern void osi_TBroadcast(osi_turnstile_t *turnp); -- 1.9.4