Windows: correct cm_buf use of Head/Tail queues

The buffer free list least recently used queue has both
head and tail points.  Use the proper versions of the queue
mgmt functions and do not handle edge cases as special cases.

Change-Id: I570682ef1cd6801f1467c4b1af40ae6591a33862
Reviewed-on: http://gerrit.openafs.org/5354
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
Jeffrey Altman 2011-09-03 21:07:13 -04:00 committed by Jeffrey Altman
parent 1e23761b7f
commit 537592f6bb

View File

@ -164,11 +164,9 @@ void buf_ReleaseLocked(cm_buf_t *bp, afs_uint32 writeLocked)
if (bp->refCount == 0 && if (bp->refCount == 0 &&
!(bp->qFlags & CM_BUF_QINLRU)) { !(bp->qFlags & CM_BUF_QINLRU)) {
osi_QAdd((osi_queue_t **) &cm_data.buf_freeListp, &bp->q); osi_QAddH( (osi_queue_t **) &cm_data.buf_freeListp,
(osi_queue_t **) &cm_data.buf_freeListEndp,
/* watch for transition from empty to one element */ &bp->q);
if (!cm_data.buf_freeListEndp)
cm_data.buf_freeListEndp = cm_data.buf_freeListp;
_InterlockedOr(&bp->qFlags, CM_BUF_QINLRU); _InterlockedOr(&bp->qFlags, CM_BUF_QINLRU);
} }
@ -204,11 +202,9 @@ void buf_Release(cm_buf_t *bp)
lock_ObtainWrite(&buf_globalLock); lock_ObtainWrite(&buf_globalLock);
if (bp->refCount == 0 && if (bp->refCount == 0 &&
!(bp->qFlags & CM_BUF_QINLRU)) { !(bp->qFlags & CM_BUF_QINLRU)) {
osi_QAdd((osi_queue_t **) &cm_data.buf_freeListp, &bp->q); osi_QAddH( (osi_queue_t **) &cm_data.buf_freeListp,
(osi_queue_t **) &cm_data.buf_freeListEndp,
/* watch for transition from empty to one element */ &bp->q);
if (!cm_data.buf_freeListEndp)
cm_data.buf_freeListEndp = cm_data.buf_freeListp;
_InterlockedOr(&bp->qFlags, CM_BUF_QINLRU); _InterlockedOr(&bp->qFlags, CM_BUF_QINLRU);
} }
lock_ReleaseWrite(&buf_globalLock); lock_ReleaseWrite(&buf_globalLock);
@ -483,17 +479,15 @@ long buf_Init(int newFile, cm_buf_ops_t *opsp, afs_uint64 nbuffers)
bp->allp = cm_data.buf_allp; bp->allp = cm_data.buf_allp;
cm_data.buf_allp = bp; cm_data.buf_allp = bp;
osi_QAdd((osi_queue_t **)&cm_data.buf_freeListp, &bp->q); osi_QAddH( (osi_queue_t **) &cm_data.buf_freeListp,
(osi_queue_t **) &cm_data.buf_freeListEndp,
&bp->q);
_InterlockedOr(&bp->qFlags, CM_BUF_QINLRU); _InterlockedOr(&bp->qFlags, CM_BUF_QINLRU);
lock_InitializeMutex(&bp->mx, "Buffer mutex", LOCK_HIERARCHY_BUFFER); lock_InitializeMutex(&bp->mx, "Buffer mutex", LOCK_HIERARCHY_BUFFER);
/* grab appropriate number of bytes from aligned zone */ /* grab appropriate number of bytes from aligned zone */
bp->datap = data; bp->datap = data;
/* setup last buffer pointer */
if (i == 0)
cm_data.buf_freeListEndp = bp;
/* next */ /* next */
bp++; bp++;
data += cm_data.buf_blockSize; data += cm_data.buf_blockSize;
@ -1089,17 +1083,15 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *req
cm_data.buf_fileHashTablepp[i] = bp; cm_data.buf_fileHashTablepp[i] = bp;
} }
/* we should move it from the lru queue. It better still be there, /* we should remove it from the lru queue. It better still be there,
* since we've held the global (big) lock since we found it there. * since we've held the global (big) lock since we found it there.
*/ */
osi_assertx(bp->qFlags & CM_BUF_QINLRU, osi_assertx(bp->qFlags & CM_BUF_QINLRU,
"buf_GetNewLocked: LRU screwup"); "buf_GetNewLocked: LRU screwup");
if (cm_data.buf_freeListEndp == bp) { osi_QRemoveHT( (osi_queue_t **) &cm_data.buf_freeListp,
/* we're the last guy in this queue, so maintain it */ (osi_queue_t **) &cm_data.buf_freeListEndp,
cm_data.buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); &bp->q);
}
osi_QRemove((osi_queue_t **) &cm_data.buf_freeListp, &bp->q);
_InterlockedAnd(&bp->qFlags, ~CM_BUF_QINLRU); _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINLRU);
/* prepare to return it. Give it a refcount */ /* prepare to return it. Give it a refcount */
@ -1273,9 +1265,9 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf
*/ */
lock_ObtainWrite(&buf_globalLock); lock_ObtainWrite(&buf_globalLock);
if (bp->qFlags & CM_BUF_QINLRU) { if (bp->qFlags & CM_BUF_QINLRU) {
if (cm_data.buf_freeListEndp == bp) osi_QRemoveHT( (osi_queue_t **) &cm_data.buf_freeListp,
cm_data.buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); (osi_queue_t **) &cm_data.buf_freeListEndp,
osi_QRemove((osi_queue_t **) &cm_data.buf_freeListp, &bp->q); &bp->q);
_InterlockedAnd(&bp->qFlags, ~CM_BUF_QINLRU); _InterlockedAnd(&bp->qFlags, ~CM_BUF_QINLRU);
} }
lock_ReleaseWrite(&buf_globalLock); lock_ReleaseWrite(&buf_globalLock);