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 <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
This commit is contained in:
Jeffrey Altman 2012-07-10 00:13:04 -04:00
parent 80732b94ef
commit f70952a347
4 changed files with 18 additions and 15 deletions

View File

@ -674,7 +674,7 @@ void buf_WaitIO(cm_scache_t * scp, cm_buf_t *bp)
} }
if ( scp ) { if ( scp ) {
lock_ObtainRead(&scp->rw); 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_Log1(buf_logp, "buf_WaitIO waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR)&scp->flags); osi_Wakeup((LONG_PTR)&scp->flags);
} }

View File

@ -733,7 +733,7 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT && if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT &&
scp->mpDataVersion == scp->dataVersion) scp->mpDataVersion == scp->dataVersion)
cep->states |= 8; cep->states |= 8;
if (scp->flags & CM_SCACHEFLAG_WAITING) if (!osi_QIsEmpty(&scp->waitQueueH))
cep->states |= 0x40; cep->states |= 0x40;
code = 0; code = 0;
@ -848,7 +848,7 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep)
if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT && if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT &&
scp->mpDataVersion == scp->dataVersion) scp->mpDataVersion == scp->dataVersion)
cep->states |= 8; cep->states |= 8;
if (scp->flags & CM_SCACHEFLAG_WAITING) if (!osi_QIsEmpty(&scp->waitQueueH))
cep->states |= 0x40; cep->states |= 0x40;
code = 0; code = 0;

View File

@ -921,7 +921,7 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af
scp, &base, &fetched); scp, &base, &fetched);
/* wakeup anyone who is waiting */ /* 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_Log1(afsd_logp, "CM BkgPrefetch Waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR) &scp->flags); 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); _InterlockedOr(&tbufp->cmFlags, CM_BUF_CMFULLYFETCHED);
lock_ObtainWrite(&scp->rw); 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_Log1(afsd_logp, "CM GetBuffer Waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR) &scp->flags); 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); _InterlockedOr(&tbufp->cmFlags, CM_BUF_CMFULLYFETCHED);
lock_ObtainWrite(&scp->rw); 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_Log1(afsd_logp, "CM GetBuffer Waking scp 0x%p", scp);
osi_Wakeup((LONG_PTR) &scp->flags); osi_Wakeup((LONG_PTR) &scp->flags);
} }

View 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_buf_cmflags = 0;
afs_uint32 sleep_scp_bufs = 0; afs_uint32 sleep_scp_bufs = 0;
int wakeupCycle; int wakeupCycle;
afs_int32 waitCount;
afs_int32 waitRequests;
lock_AssertWrite(&scp->rw); 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 */ /* wait here, then try again */
osi_Log1(afsd_logp, "CM SyncOp sleeping scp 0x%p", scp); osi_Log1(afsd_logp, "CM SyncOp sleeping scp 0x%p", scp);
if ( scp->flags & CM_SCACHEFLAG_WAITING ) {
scp->waitCount++; waitCount = InterlockedIncrement(&scp->waitCount);
scp->waitRequests++; 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", 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 { } else {
osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING set for 0x%p", scp); osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING set for 0x%p", scp);
_InterlockedOr(&scp->flags, CM_SCACHEFLAG_WAITING); _InterlockedOr(&scp->flags, CM_SCACHEFLAG_WAITING);
scp->waitCount = scp->waitRequests = 1;
} }
cm_SyncOpAddToWaitQueue(scp, flags, bufp); 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(); 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", osi_Log3(afsd_logp, "CM SyncOp woke! scp 0x%p; still waiting %d threads of %d requests",
scp, scp->waitCount, scp->waitRequests); scp, waitCount, scp->waitRequests);
if (scp->waitCount == 0) { if (waitCount == 0) {
osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING reset for 0x%p", scp); osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING reset for 0x%p", scp);
_InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_WAITING); _InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_WAITING);
scp->waitRequests = 0; 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 */ /* 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_Log3(afsd_logp, "CM SyncOpDone 0x%x Waking scp 0x%p bufp 0x%p", flags, scp, bufp);
osi_Wakeup((LONG_PTR) &scp->flags); osi_Wakeup((LONG_PTR) &scp->flags);
} }