Windows: cm_SyncOp waiting logic
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 10 Jul 2012 04:13:04 +0000 (00:13 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 11 Jul 2012 14:13:22 +0000 (07:13 -0700)
Use interlocked increment and decrement to track the waiters
and use the wait queue itself to determine if there are waiters
instead of the CM_SCACHEFLAG_WAITING flag.

Change-Id: I9c570cb228d73253989932149346ecfc45804267
Reviewed-on: http://gerrit.openafs.org/7752
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsd/cm_buf.c
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_scache.c

index d7a27c5..dd8b8ba 100644 (file)
@@ -674,7 +674,7 @@ void buf_WaitIO(cm_scache_t * scp, cm_buf_t *bp)
         }
         if ( scp ) {
             lock_ObtainRead(&scp->rw);
-            if (scp->flags & CM_SCACHEFLAG_WAITING) {
+            if (!osi_QIsEmpty(&scp->waitQueueH)) {
                 osi_Log1(buf_logp, "buf_WaitIO waking scp 0x%p", scp);
                 osi_Wakeup((LONG_PTR)&scp->flags);
             }
index dfd7a2f..e245d3e 100644 (file)
@@ -733,7 +733,7 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
     if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT &&
         scp->mpDataVersion == scp->dataVersion)
         cep->states |= 8;
-    if (scp->flags & CM_SCACHEFLAG_WAITING)
+    if (!osi_QIsEmpty(&scp->waitQueueH))
         cep->states |= 0x40;
     code = 0;
 
@@ -848,7 +848,7 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep)
     if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT &&
         scp->mpDataVersion == scp->dataVersion)
         cep->states |= 8;
-    if (scp->flags & CM_SCACHEFLAG_WAITING)
+    if (!osi_QIsEmpty(&scp->waitQueueH))
         cep->states |= 0x40;
     code = 0;
 
index 040671a..314def8 100644 (file)
@@ -921,7 +921,7 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af
                          scp, &base, &fetched);
 
     /* wakeup anyone who is waiting */
-    if (scp->flags & CM_SCACHEFLAG_WAITING) {
+    if (!osi_QIsEmpty(&scp->waitQueueH)) {
         osi_Log1(afsd_logp, "CM BkgPrefetch Waking scp 0x%p", scp);
         osi_Wakeup((LONG_PTR) &scp->flags);
     }
@@ -2024,7 +2024,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *userp
                         */
                         _InterlockedOr(&tbufp->cmFlags, CM_BUF_CMFULLYFETCHED);
                         lock_ObtainWrite(&scp->rw);
-                        if (scp->flags & CM_SCACHEFLAG_WAITING) {
+                        if (!osi_QIsEmpty(&scp->waitQueueH)) {
                             osi_Log1(afsd_logp, "CM GetBuffer Waking scp 0x%p", scp);
                             osi_Wakeup((LONG_PTR) &scp->flags);
                         }
@@ -2083,7 +2083,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *userp
                  */
                 _InterlockedOr(&tbufp->cmFlags, CM_BUF_CMFULLYFETCHED);
                 lock_ObtainWrite(&scp->rw);
-                if (scp->flags & CM_SCACHEFLAG_WAITING) {
+                if (!osi_QIsEmpty(&scp->waitQueueH)) {
                     osi_Log1(afsd_logp, "CM GetBuffer Waking scp 0x%p", scp);
                     osi_Wakeup((LONG_PTR) &scp->flags);
                 }
index 4922fd6..dbfe277 100644 (file)
@@ -1170,6 +1170,8 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *req
     afs_uint32 sleep_buf_cmflags = 0;
     afs_uint32 sleep_scp_bufs = 0;
     int wakeupCycle;
+    afs_int32 waitCount;
+    afs_int32 waitRequests;
 
     lock_AssertWrite(&scp->rw);
 
@@ -1413,15 +1415,15 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *req
 
         /* wait here, then try again */
         osi_Log1(afsd_logp, "CM SyncOp sleeping scp 0x%p", scp);
-        if ( scp->flags & CM_SCACHEFLAG_WAITING ) {
-            scp->waitCount++;
-            scp->waitRequests++;
+
+        waitCount = InterlockedIncrement(&scp->waitCount);
+        waitRequests = InterlockedIncrement(&scp->waitRequests);
+        if (waitCount > 1) {
             osi_Log3(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING already set for 0x%p; %d threads; %d requests",
-                     scp, scp->waitCount, scp->waitRequests);
+                     scp, waitCount, waitRequests);
         } else {
             osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING set for 0x%p", scp);
             _InterlockedOr(&scp->flags, CM_SCACHEFLAG_WAITING);
-            scp->waitCount = scp->waitRequests = 1;
         }
 
         cm_SyncOpAddToWaitQueue(scp, flags, bufp);
@@ -1437,10 +1439,10 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *req
 
        cm_UpdateServerPriority();
 
-        scp->waitCount--;
+        waitCount = InterlockedDecrement(&scp->waitCount);
         osi_Log3(afsd_logp, "CM SyncOp woke! scp 0x%p; still waiting %d threads of %d requests",
-                 scp, scp->waitCount, scp->waitRequests);
-        if (scp->waitCount == 0) {
+                 scp, waitCount, scp->waitRequests);
+        if (waitCount == 0) {
             osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING reset for 0x%p", scp);
             _InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_WAITING);
             scp->waitRequests = 0;
@@ -1593,7 +1595,8 @@ void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, afs_uint32 flags)
     }
 
     /* and wakeup anyone who is waiting */
-    if (scp->flags & CM_SCACHEFLAG_WAITING) {
+    if ((scp->flags & CM_SCACHEFLAG_WAITING) ||
+        !osi_QIsEmpty(&scp->waitQueueH)) {
         osi_Log3(afsd_logp, "CM SyncOpDone 0x%x Waking scp 0x%p bufp 0x%p", flags, scp, bufp);
         osi_Wakeup((LONG_PTR) &scp->flags);
     }