Windows: add osi_TWaitExt(), fix osi_TWait()
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 27 Dec 2011 01:51:33 +0000 (20:51 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 31 Dec 2011 21:15:35 +0000 (13:15 -0800)
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 <buildbot@rampaginggeek.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/client_osi/osibasel.c
src/WINNT/client_osi/osisleep.c
src/WINNT/client_osi/osisleep.h

index 20444f8..192a22c 100644 (file)
@@ -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));
index a810936..5b2e0d4 100644 (file)
@@ -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 */
index 0c3fe46..b833d26 100644 (file)
@@ -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);