From f0b590bcc084e7e3873a2236ffba13b8c62151cb Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 10 Aug 2011 16:40:35 -0400 Subject: [PATCH] Windows: Interlocked operations for cm_buf cm_buf flags and qFlags Separate flags and qFlags in the cm_buf structure to improve performance. Reviewed-on: http://gerrit.openafs.org/5197 Tested-by: BuildBot Reviewed-by: Derrick Brashear Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman (cherry picked from commit 7ab34058120ebcc218e4061ea3ac3c8eeca6d83e) Change-Id: I8cbc806833af630fb56c8ef388fe3a21df1f5478 Reviewed-on: http://gerrit.openafs.org/5218 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/WINNT/afsd/cm_buf.c | 58 +++++++++++++++++++------------------- src/WINNT/afsd/cm_buf.h | 4 +-- src/WINNT/afsd/cm_dcache.c | 10 +++---- src/WINNT/afsd/cm_scache.c | 10 +++---- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 5b8435996..eca1ecf8d 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -166,7 +166,7 @@ void buf_ReleaseLocked(cm_buf_t *bp, afs_uint32 writeLocked) /* watch for transition from empty to one element */ if (!cm_data.buf_freeListEndp) cm_data.buf_freeListEndp = cm_data.buf_freeListp; - bp->qFlags |= CM_BUF_QINLRU; + _InterlockedOr(&bp->qFlags, CM_BUF_QINLRU); } if (!writeLocked) @@ -206,7 +206,7 @@ void buf_Release(cm_buf_t *bp) /* watch for transition from empty to one element */ if (!cm_data.buf_freeListEndp) cm_data.buf_freeListEndp = cm_data.buf_freeListp; - bp->qFlags |= CM_BUF_QINLRU; + _InterlockedOr(&bp->qFlags, CM_BUF_QINLRU); } lock_ReleaseWrite(&buf_globalLock); } @@ -269,7 +269,7 @@ buf_Sync(int quitOnShutdown) #endif *bpp = bp->dirtyp; bp->dirtyp = NULL; - bp->qFlags &= ~CM_BUF_QINDL; + _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINDL); if (cm_data.buf_dirtyListp == NULL) cm_data.buf_dirtyListEndp = NULL; else if (cm_data.buf_dirtyListEndp == bp) @@ -482,7 +482,7 @@ long buf_Init(int newFile, cm_buf_ops_t *opsp, afs_uint64 nbuffers) cm_data.buf_allp = bp; osi_QAdd((osi_queue_t **)&cm_data.buf_freeListp, &bp->q); - bp->qFlags |= CM_BUF_QINLRU; + _InterlockedOr(&bp->qFlags, CM_BUF_QINLRU); lock_InitializeMutex(&bp->mx, "Buffer mutex", LOCK_HIERARCHY_BUFFER); /* grab appropriate number of bytes from aligned zone */ @@ -511,7 +511,7 @@ long buf_Init(int newFile, cm_buf_ops_t *opsp, afs_uint64 nbuffers) bp->userp = NULL; bp->waitCount = 0; bp->waitRequests = 0; - bp->flags &= ~CM_BUF_WAITING; + _InterlockedAnd(&bp->flags, ~CM_BUF_WAITING); bp++; } } @@ -604,7 +604,7 @@ void buf_WaitIO(cm_scache_t * scp, cm_buf_t *bp) osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING already set for 0x%p", bp); } else { osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING set for 0x%p", bp); - bp->flags |= CM_BUF_WAITING; + _InterlockedOr(&bp->flags, CM_BUF_WAITING); bp->waitCount = bp->waitRequests = 1; } osi_SleepM((LONG_PTR)bp, &bp->mx); @@ -616,7 +616,7 @@ void buf_WaitIO(cm_scache_t * scp, cm_buf_t *bp) bp->waitCount--; if (bp->waitCount == 0) { osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING reset for 0x%p", bp); - bp->flags &= ~CM_BUF_WAITING; + _InterlockedAnd(&bp->flags, ~CM_BUF_WAITING); bp->waitRequests = 0; } @@ -810,8 +810,8 @@ afs_uint32 buf_CleanAsyncLocked(cm_scache_t *scp, cm_buf_t *bp, cm_req_t *reqp, if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BADFD || code == CM_ERROR_NOACCESS || code == CM_ERROR_QUOTA || code == CM_ERROR_SPACE || code == CM_ERROR_TOOBIG || code == CM_ERROR_READONLY || code == CM_ERROR_NOSUCHPATH){ - bp->flags &= ~CM_BUF_DIRTY; - bp->flags |= CM_BUF_ERROR; + _InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY); + _InterlockedOr(&bp->flags, CM_BUF_ERROR); bp->dirty_offset = 0; bp->dirty_length = 0; bp->error = code; @@ -917,14 +917,14 @@ void buf_Recycle(cm_buf_t *bp) if (nextBp) nextBp->fileHashBackp = prevBp; - bp->qFlags &= ~CM_BUF_QINHASH; + _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINHASH); } /* make the fid unrecognizable */ memset(&bp->fid, 0, sizeof(cm_fid_t)); /* clean up junk flags */ - bp->flags &= ~(CM_BUF_EOF | CM_BUF_ERROR); + _InterlockedAnd(&bp->flags, ~(CM_BUF_EOF | CM_BUF_ERROR)); bp->dataVersion = CM_BUF_VERSION_BAD; /* unknown so far */ } @@ -1069,7 +1069,7 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *req if (scp) { lock_AssertWrite(&buf_globalLock); - bp->qFlags |= CM_BUF_QINHASH; + _InterlockedOr(&bp->qFlags, CM_BUF_QINHASH); bp->fid = scp->fid; #ifdef DEBUG bp->scp = scp; @@ -1098,7 +1098,7 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *req cm_data.buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); } osi_QRemove((osi_queue_t **) &cm_data.buf_freeListp, &bp->q); - bp->qFlags &= ~CM_BUF_QINLRU; + _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINLRU); /* prepare to return it. Give it a refcount */ bp->refCount = 1; @@ -1211,7 +1211,7 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf * implementation of Readp is cm_BufRead() which simply sets * tcount to 0 and returns success. */ - bp->flags |= CM_BUF_READING; + _InterlockedOr(&bp->flags, CM_BUF_READING); code = (*cm_buf_opsp->Readp)(bp, cm_data.buf_blockSize, &tcount, NULL); #ifdef DISKCACHE95 @@ -1223,8 +1223,8 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf /* failure or queued */ if (code != ERROR_IO_PENDING) { bp->error = code; - bp->flags |= CM_BUF_ERROR; - bp->flags &= ~CM_BUF_READING; + _InterlockedOr(&bp->flags, CM_BUF_ERROR); + _InterlockedAnd(&bp->flags, ~CM_BUF_READING); if (bp->flags & CM_BUF_WAITING) { osi_Log1(buf_logp, "buf_Get Waking bp 0x%p", bp); osi_Wakeup((LONG_PTR) bp); @@ -1244,9 +1244,9 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf if (tcount < (unsigned long) cm_data.buf_blockSize) { memset(bp->datap+tcount, 0, cm_data.buf_blockSize - tcount); if (tcount == 0) - bp->flags |= CM_BUF_EOF; + _InterlockedOr(&bp->flags, CM_BUF_EOF); } - bp->flags &= ~CM_BUF_READING; + _InterlockedAnd(&bp->flags, ~CM_BUF_READING); if (bp->flags & CM_BUF_WAITING) { osi_Log1(buf_logp, "buf_Get Waking bp 0x%p", bp); osi_Wakeup((LONG_PTR) bp); @@ -1274,7 +1274,7 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf if (cm_data.buf_freeListEndp == bp) cm_data.buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); osi_QRemove((osi_queue_t **) &cm_data.buf_freeListp, &bp->q); - bp->qFlags &= ~CM_BUF_QINLRU; + _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINLRU); } lock_ReleaseWrite(&buf_globalLock); @@ -1370,10 +1370,10 @@ void buf_SetDirty(cm_buf_t *bp, afs_uint32 offset, afs_uint32 length, cm_user_t osi_Log1(buf_logp, "buf_SetDirty 0x%p", bp); /* set dirty bit */ - bp->flags |= CM_BUF_DIRTY; + _InterlockedOr(&bp->flags, CM_BUF_DIRTY); /* and turn off EOF flag, since it has associated data now */ - bp->flags &= ~CM_BUF_EOF; + _InterlockedAnd(&bp->flags, ~CM_BUF_EOF); bp->dirty_offset = offset; bp->dirty_length = length; @@ -1398,7 +1398,7 @@ void buf_SetDirty(cm_buf_t *bp, afs_uint32 offset, afs_uint32 length, cm_user_t cm_data.buf_dirtyListEndp = bp; } bp->dirtyp = NULL; - bp->qFlags |= CM_BUF_QINDL; + _InterlockedOr(&bp->qFlags, CM_BUF_QINDL); } lock_ReleaseWrite(&buf_globalLock); } @@ -1588,7 +1588,7 @@ long buf_Truncate(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, */ if (LargeIntegerLessThanOrEqualTo(*sizep, bufp->offset)) { /* truncating the entire page */ - bufp->flags &= ~CM_BUF_DIRTY; + _InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY); bufp->dirty_offset = 0; bufp->dirty_length = 0; bufp->dataVersion = CM_BUF_VERSION_BAD; /* known bad */ @@ -1679,8 +1679,8 @@ long buf_FlushCleanPages(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) * page therefore contains data that can no longer be stored. */ lock_ObtainMutex(&bp->mx); - bp->flags &= ~CM_BUF_DIRTY; - bp->flags |= CM_BUF_ERROR; + _InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY); + _InterlockedOr(&bp->flags, CM_BUF_ERROR); bp->error = CM_ERROR_BADFD; bp->dirty_offset = 0; bp->dirty_length = 0; @@ -1810,8 +1810,8 @@ long buf_CleanVnode(struct cm_scache *scp, cm_user_t *userp, cm_req_t *reqp) * Do not waste the time attempting to store to * the file server when we know it will fail. */ - bp->flags &= ~CM_BUF_DIRTY; - bp->flags |= CM_BUF_ERROR; + _InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY); + _InterlockedOr(&bp->flags, CM_BUF_ERROR); bp->dirty_offset = 0; bp->dirty_length = 0; bp->error = code; @@ -2017,10 +2017,10 @@ long buf_CleanDirtyBuffers(cm_scache_t *scp) buf_Hold(bp); lock_ObtainMutex(&bp->mx); _InterlockedAnd(&bp->cmFlags, ~CM_BUF_CMSTORING); - bp->flags &= ~CM_BUF_DIRTY; + _InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY); bp->dirty_offset = 0; bp->dirty_length = 0; - bp->flags |= CM_BUF_ERROR; + _InterlockedOr(&bp->flags, CM_BUF_ERROR); bp->error = VNOVNODE; bp->dataVersion = CM_BUF_VERSION_BAD; /* bad */ bp->dirtyCounter++; diff --git a/src/WINNT/afsd/cm_buf.h b/src/WINNT/afsd/cm_buf.h index 13d2381c4..5d295fe1b 100644 --- a/src/WINNT/afsd/cm_buf.h +++ b/src/WINNT/afsd/cm_buf.h @@ -43,6 +43,7 @@ extern int buf_cacheType; /* represents a single buffer */ typedef struct cm_buf { osi_queue_t q; /* queue of all zero-refcount buffers */ + afs_uint32 qFlags; /* queue/hash state flags - buf_globalLock */ afs_uint32 magic; struct cm_buf *allp; /* next in all list */ struct cm_buf *hashp; /* hash bucket pointer */ @@ -62,9 +63,8 @@ typedef struct cm_buf { afs_uint32 dirtyCounter; /* bumped at each dirty->clean transition */ osi_hyper_t offset; /* offset */ cm_fid_t fid; /* file ID */ - afs_uint32 flags; /* flags we're using - mx */ - afs_uint32 qFlags; /* queue/hash state flags - buf_globalLock */ char *datap; /* data in this buffer */ + afs_uint32 flags; /* flags we're using - mx */ afs_uint32 error; /* last error code, if CM_BUF_ERROR is set */ cm_user_t *userp; /* user who wrote to the buffer last */ diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 9f01e0139..532b8faf9 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -1047,7 +1047,7 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, if (bufp->flags & CM_BUF_DIRTY) { osi_assertx(!(bufp->flags & CM_BUF_WRITING), "WRITING w/o CMSTORING in SetupStoreBIOD"); - bufp->flags |= CM_BUF_WRITING; + _InterlockedOr(&bufp->flags, CM_BUF_WRITING); break; } @@ -1490,7 +1490,7 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked) osi_Wakeup((LONG_PTR) bufp); } if (code) { - bufp->flags &= ~CM_BUF_WRITING; + _InterlockedAnd(&bufp->flags, ~CM_BUF_WRITING); switch (code) { case CM_ERROR_NOSUCHFILE: case CM_ERROR_BADFD: @@ -1503,8 +1503,8 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked) /* * Apply the fatal error to this buffer. */ - bufp->flags &= ~CM_BUF_DIRTY; - bufp->flags |= CM_BUF_ERROR; + _InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY); + _InterlockedOr(&bufp->flags, CM_BUF_ERROR); bufp->dirty_offset = 0; bufp->dirty_length = 0; bufp->error = code; @@ -1523,7 +1523,7 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long code, int scp_locked) break; } } else { - bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY); + _InterlockedAnd(&bufp->flags, ~(CM_BUF_WRITING | CM_BUF_DIRTY)); bufp->dirty_offset = bufp->dirty_length = 0; } } diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 22d7510bb..90615b0d5 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -162,10 +162,10 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) if (bufp) { lock_ObtainMutex(&bufp->mx); _InterlockedAnd(&bufp->cmFlags, ~CM_BUF_CMSTORING); - bufp->flags &= ~CM_BUF_DIRTY; + _InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY); bufp->dirty_offset = 0; bufp->dirty_length = 0; - bufp->flags |= CM_BUF_ERROR; + _InterlockedOr(&bufp->flags, CM_BUF_ERROR); bufp->error = VNOVNODE; bufp->dataVersion = CM_BUF_VERSION_BAD; /* bad */ bufp->dirtyCounter++; @@ -184,10 +184,10 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) if (bufp) { lock_ObtainMutex(&bufp->mx); _InterlockedAnd(&bufp->cmFlags, ~CM_BUF_CMFETCHING); - bufp->flags &= ~CM_BUF_DIRTY; + _InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY); bufp->dirty_offset = 0; bufp->dirty_length = 0; - bufp->flags |= CM_BUF_ERROR; + _InterlockedOr(&bufp->flags, CM_BUF_ERROR); bufp->error = VNOVNODE; bufp->dataVersion = CM_BUF_VERSION_BAD; /* bad */ bufp->dirtyCounter++; @@ -1743,7 +1743,7 @@ void cm_MergeStatus(cm_scache_t *dscp, *lbpp = bp->hashp; /* hash out */ bp->hashp = NULL; - bp->qFlags &= ~CM_BUF_QINHASH; + _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINHASH); } lock_ReleaseMutex(&bp->mx); } -- 2.39.5