Windows: Interlocked operations for cm_buf
authorJeffrey Altman <jaltman@your-file-system.com>
Wed, 10 Aug 2011 20:40:35 +0000 (16:40 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Thu, 11 Aug 2011 06:16:47 +0000 (23:16 -0700)
cm_buf flags and qFlags

Separate flags and qFlags in the cm_buf structure to improve
performance.

Change-Id: I3d9504827cb74f8770e344cea1c06a6e786785b3
Reviewed-on: http://gerrit.openafs.org/5197
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

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

index dd6946e..391b8ac 100644 (file)
@@ -169,7 +169,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)
@@ -209,7 +209,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);
     }
@@ -272,7 +272,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)
@@ -485,7 +485,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 */
@@ -514,7 +514,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++;
             }
         }
@@ -607,7 +607,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);
@@ -619,7 +619,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;
         }
 
@@ -813,8 +813,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;
@@ -920,14 +920,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 */
 }
 
@@ -1072,7 +1072,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;
@@ -1101,7 +1101,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;
@@ -1214,7 +1214,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
@@ -1226,8 +1226,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);
@@ -1247,9 +1247,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);
@@ -1277,7 +1277,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);
 
@@ -1373,10 +1373,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;
@@ -1401,7 +1401,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);
     }
@@ -1591,7 +1591,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 */
@@ -1682,8 +1682,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;
@@ -1813,8 +1813,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;
@@ -2020,10 +2020,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++;
index 13d2381..5d295fe 100644 (file)
@@ -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 */
 
index 73d455f..5974b2a 100644 (file)
@@ -1051,7 +1051,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;
             }
 
@@ -1494,7 +1494,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:
@@ -1507,8 +1507,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;
@@ -1527,7 +1527,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;
                 }
            }
index 49b409a..081cada 100644 (file)
@@ -165,10 +165,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++;
@@ -187,10 +187,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++;
@@ -1746,7 +1746,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);
             }