From f70952a347dff39bd445f8361224e1c622a5b1cf Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 10 Jul 2012 00:13:04 -0400 Subject: [PATCH] Windows: cm_SyncOp waiting logic 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 Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_buf.c | 2 +- src/WINNT/afsd/cm_callback.c | 4 ++-- src/WINNT/afsd/cm_dcache.c | 6 +++--- src/WINNT/afsd/cm_scache.c | 21 ++++++++++++--------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index d7a27c54e1..dd8b8baed0 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -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); } diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index dfd7a2fe18..e245d3e0ce 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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; diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 040671aae7..314def8c40 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -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); } diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 4922fd6bf5..dbfe277fe2 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -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); }