From 0479c650c17f35a4cf0de523cfc036b8d21629ce Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 7 Mar 2008 22:07:40 +0000 Subject: [PATCH] windows-cm-server-interlocked-20080307 LICENSE MIT Convert cm_server_t reference counts to use Interlocked operations. This permits almost all of the cm_serverLock holds to be converted to read locks. Add missing cm_PutServerNoLock() calls in the multi_Rx version of cm_CheckServers(). (Thanks to Asanka) --- src/WINNT/afsd/cm_server.c | 69 +++++++++++++++++++++++++--------------------- src/WINNT/afsd/cm_server.h | 4 +-- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index fce5e6e..364ab7f 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -33,13 +33,13 @@ cm_ForceNewConnectionsAllServers(void) { cm_server_t *tsp; - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { cm_GetServerNoLock(tsp); cm_ForceNewConnections(tsp); cm_PutServerNoLock(tsp); } - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); } void @@ -207,10 +207,10 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) int isDown; int isFS; - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { cm_GetServerNoLock(tsp); - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); /* now process the server */ lock_ObtainMutex(&tsp->mx); @@ -245,10 +245,10 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) */ cm_GCConnections(tsp); - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); cm_PutServerNoLock(tsp); } - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); } #else /* MULTI_CHECKSERVERS */ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) @@ -298,7 +298,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) if ((flags & CM_FLAG_CHECKFILESERVERS) || !(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS))) { - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); nconns = 0; for (nconns=0, tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { if (tsp->type != CM_SERVER_FILE || @@ -307,7 +307,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) continue; cm_GetServerNoLock(tsp); - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); lock_ObtainMutex(&tsp->mx); isDown = tsp->flags & CM_SERVERFLAG_DOWN; @@ -316,7 +316,8 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) !((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) || (!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) { lock_ReleaseMutex(&tsp->mx); - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); + cm_PutServerNoLock(tsp); continue; } @@ -326,18 +327,18 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) serversp[nconns] = tsp; code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]); if (code) { - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); cm_PutServerNoLock(tsp); continue; } - lock_ObtainWrite(&cm_serverLock); - rxconns[nconns] = cm_GetRxConn(conns[nconns]); + lock_ObtainRead(&cm_serverLock); + rxconns[nconns] = cm_GetRxConn(conns[nconns]); if (conntimer[nconns] = (isDown ? 1 : 0)) rx_SetConnDeadTime(rxconns[nconns], 10); nconns++; } - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); if (nconns) { /* Perform the multi call */ @@ -593,7 +594,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) if ((flags & CM_FLAG_CHECKVLDBSERVERS) || !(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS))) { - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); nconns = 0; for (nconns=0, tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { if (tsp->type != CM_SERVER_VLDB || @@ -602,7 +603,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) continue; cm_GetServerNoLock(tsp); - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); lock_ObtainMutex(&tsp->mx); isDown = tsp->flags & CM_SERVERFLAG_DOWN; @@ -611,7 +612,8 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) !((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) || (!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) { lock_ReleaseMutex(&tsp->mx); - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); + cm_PutServerNoLock(tsp); continue; } @@ -621,11 +623,11 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) serversp[nconns] = tsp; code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]); if (code) { - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); cm_PutServerNoLock(tsp); continue; } - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); rxconns[nconns] = cm_GetRxConn(conns[nconns]); conntimer[nconns] = (isDown ? 1 : 0); if (isDown) @@ -633,7 +635,7 @@ void cm_CheckServers(afs_uint32 flags, cm_cell_t *cellp) nconns++; } - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); if (nconns) { /* Perform the multi call */ @@ -765,26 +767,29 @@ void cm_InitServer(void) void cm_GetServer(cm_server_t *serverp) { - lock_ObtainWrite(&cm_serverLock); - serverp->refCount++; - lock_ReleaseWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); + InterlockedIncrement(&serverp->refCount); + lock_ReleaseRead(&cm_serverLock); } void cm_GetServerNoLock(cm_server_t *serverp) { - serverp->refCount++; + InterlockedIncrement(&serverp->refCount); } void cm_PutServer(cm_server_t *serverp) { - lock_ObtainWrite(&cm_serverLock); - osi_assertx(serverp->refCount-- > 0, "cm_server_t refCount 0"); - lock_ReleaseWrite(&cm_serverLock); + afs_int32 refCount; + lock_ObtainRead(&cm_serverLock); + refCount = InterlockedDecrement(&serverp->refCount); + osi_assertx(refCount >= 0, "cm_server_t refCount underflow"); + lock_ReleaseRead(&cm_serverLock); } void cm_PutServerNoLock(cm_server_t *serverp) { - osi_assertx(serverp->refCount-- > 0, "cm_server_t refCount 0"); + afs_int32 refCount = InterlockedDecrement(&serverp->refCount); + osi_assertx(refCount >= 0, "cm_server_t refCount underflow"); } void cm_SetServerNo64Bit(cm_server_t * serverp, int no64bit) @@ -928,7 +933,7 @@ cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type) osi_assertx(addrp->sin_family == AF_INET, "unexpected socket value"); - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) { if (tsp->type == type && tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr) @@ -940,7 +945,7 @@ cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type) cm_GetServerNoLock(tsp); /* drop big table lock */ - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); /* return what we found */ return tsp; @@ -1022,7 +1027,7 @@ LONG_PTR cm_ChecksumServerList(cm_serverRef_t *serversp) int first = 1; cm_serverRef_t *tsrp; - lock_ObtainWrite(&cm_serverLock); + lock_ObtainRead(&cm_serverLock); for (tsrp = serversp; tsrp; tsrp=tsrp->next) { if (first) first = 0; @@ -1031,13 +1036,13 @@ LONG_PTR cm_ChecksumServerList(cm_serverRef_t *serversp) sum ^= (LONG_PTR) tsrp->server; } - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseRead(&cm_serverLock); return sum; } /* ** Insert a server into the server list keeping the list sorted in -** asending order of ipRank. +** ascending order of ipRank. ** ** The refCount of the cm_serverRef_t is increased */ diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index ab57b0d..d100667 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -32,7 +32,7 @@ typedef struct cm_server { afs_int32 waitCount; /* by mx */ afs_int32 capabilities; /* by mx */ struct cm_cell *cellp; /* cell containing this server */ - unsigned long refCount; /* locked by cm_serverLock */ + afs_int32 refCount; /* Interlocked with cm_serverLock */ osi_mutex_t mx; unsigned short ipRank; /* server priority */ cm_server_vols_t * vols; /* by mx */ @@ -45,7 +45,7 @@ typedef struct cm_serverRef { struct cm_serverRef *next; /* locked by cm_serverLock */ struct cm_server *server; /* locked by cm_serverLock */ enum repstate status; /* locked by cm_serverLock */ - unsigned long refCount; /* locked by cm_serverLock */ + afs_int32 refCount; /* locked by cm_serverLock */ afs_uint32 volID; /* locked by cm_serverLock */ } cm_serverRef_t; -- 1.9.4