mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 05:27:44 +00:00
DEVEL15-windows-osi-convertRToW-and-logging-optimizations-20080227
LICENSE MIT Add lock_convertRToW which permits a read-lock to be upgraded to a write lock. If the caller is the only reader it permits a fast transition otherwise it adds the caller to the waiters queue. In the osi_Log macros, check to see if the log is enabled before making the function call. This avoids significant function call overhead. In the cache manager, make use of the above. (cherry picked from commit 72687c02b6ee5ff3029937b0278733b252f14550)
This commit is contained in:
parent
92f03f92ce
commit
b6654a597f
@ -130,10 +130,8 @@ void buf_ReleaseLocked(cm_buf_t *bp, afs_uint32 writeLocked)
|
||||
* double check that the refCount is actually zero
|
||||
* before we remove the buffer from the LRU queue.
|
||||
*/
|
||||
if (!writeLocked) {
|
||||
lock_ReleaseRead(&buf_globalLock);
|
||||
lock_ObtainWrite(&buf_globalLock);
|
||||
}
|
||||
if (!writeLocked)
|
||||
lock_ConvertRToW(&buf_globalLock);
|
||||
|
||||
if (bp->refCount == 0 &&
|
||||
!(bp->flags & CM_BUF_INLRU)) {
|
||||
@ -145,10 +143,8 @@ void buf_ReleaseLocked(cm_buf_t *bp, afs_uint32 writeLocked)
|
||||
bp->flags |= CM_BUF_INLRU;
|
||||
}
|
||||
|
||||
if (!writeLocked) {
|
||||
lock_ReleaseWrite(&buf_globalLock);
|
||||
lock_ObtainRead(&buf_globalLock);
|
||||
}
|
||||
if (!writeLocked)
|
||||
lock_ConvertWToR(&buf_globalLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1032,8 +1032,7 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
|
||||
lock_ReleaseMutex(&scp->mx);
|
||||
mxheld = 0;
|
||||
}
|
||||
lock_ReleaseRead(&scp->dirlock);
|
||||
lock_ObtainWrite(&scp->dirlock);
|
||||
lock_ConvertRToW(&scp->dirlock);
|
||||
haveWrite = 1;
|
||||
}
|
||||
if (!mxheld) {
|
||||
|
@ -159,8 +159,7 @@ cm_dnlcEnter ( cm_scache_t *adp,
|
||||
if ( !tnc )
|
||||
{
|
||||
if ( !writeLocked ) {
|
||||
lock_ReleaseRead(&cm_dnlcLock);
|
||||
lock_ObtainWrite(&cm_dnlcLock);
|
||||
lock_ConvertRToW(&cm_dnlcLock);
|
||||
writeLocked = 1;
|
||||
goto retry;
|
||||
}
|
||||
|
@ -4740,10 +4740,8 @@ long cm_Unlock(cm_scache_t *scp,
|
||||
return CM_ERROR_RANGE_NOT_LOCKED;
|
||||
}
|
||||
|
||||
lock_ReleaseRead(&cm_scacheLock);
|
||||
|
||||
/* discard lock record */
|
||||
lock_ObtainWrite(&cm_scacheLock);
|
||||
lock_ConvertRToW(&cm_scacheLock);
|
||||
if (scp->fileLocksT == q)
|
||||
scp->fileLocksT = osi_QPrev(q);
|
||||
osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, q);
|
||||
|
@ -70,3 +70,4 @@ EXPORTS
|
||||
osi_LogEvent @63
|
||||
osi_HexifyString @64
|
||||
osi_QRemoveHT @65
|
||||
lock_ConvertRToW @66
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
/* atomicity-providing critical sections */
|
||||
CRITICAL_SECTION osi_baseAtomicCS[OSI_MUTEXHASHSIZE];
|
||||
static long atomicIndexCounter = 0;
|
||||
|
||||
void osi_BaseInit(void)
|
||||
{
|
||||
@ -179,6 +180,38 @@ void lock_ConvertWToR(osi_rwlock_t *lockp)
|
||||
}
|
||||
}
|
||||
|
||||
void lock_ConvertRToW(osi_rwlock_t *lockp)
|
||||
{
|
||||
long i;
|
||||
CRITICAL_SECTION *csp;
|
||||
|
||||
if ((i = lockp->type) != 0) {
|
||||
if (i >= 0 && i < OSI_NLOCKTYPES)
|
||||
(osi_lockOps[i]->ConvertRToWProc)(lockp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* otherwise we're the fast base type */
|
||||
csp = &osi_baseAtomicCS[lockp->atomicIndex];
|
||||
EnterCriticalSection(csp);
|
||||
|
||||
osi_assertx(!(lockp->flags & OSI_LOCKFLAG_EXCL), "write lock held");
|
||||
osi_assertx(lockp->readers > 0, "read lock not held");
|
||||
|
||||
if (--lockp->readers == 0) {
|
||||
/* convert read lock to write lock */
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
} else {
|
||||
lockp->waiters++;
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
|
||||
lockp->waiters--;
|
||||
osi_assert(lockp->readers == 0 && (lockp->flags & OSI_LOCKFLAG_EXCL));
|
||||
}
|
||||
|
||||
lockp->tid = thrd_Current();
|
||||
LeaveCriticalSection(csp);
|
||||
}
|
||||
|
||||
void lock_ObtainMutex(struct osi_mutex *lockp)
|
||||
{
|
||||
long i;
|
||||
@ -443,7 +476,7 @@ void lock_InitializeMutex(osi_mutex_t *mp, char *namep)
|
||||
mp->type = 0;
|
||||
mp->flags = 0;
|
||||
mp->tid = 0;
|
||||
mp->atomicIndex = osi_MUTEXHASH(mp);
|
||||
mp->atomicIndex = (unsigned short)(InterlockedIncrement(&atomicIndexCounter) % OSI_MUTEXHASHSIZE);
|
||||
osi_TInit(&mp->d.turn);
|
||||
return;
|
||||
}
|
||||
@ -463,7 +496,7 @@ void lock_InitializeRWLock(osi_rwlock_t *mp, char *namep)
|
||||
*/
|
||||
mp->type = 0;
|
||||
mp->flags = 0;
|
||||
mp->atomicIndex = osi_MUTEXHASH(mp);
|
||||
mp->atomicIndex = (unsigned short)(InterlockedIncrement(&atomicIndexCounter) % OSI_MUTEXHASHSIZE);
|
||||
mp->readers = 0;
|
||||
mp->tid = 0;
|
||||
osi_TInit(&mp->d.turn);
|
||||
|
@ -109,6 +109,8 @@ extern void osi_Init (void);
|
||||
|
||||
extern void lock_ConvertWToR(struct osi_rwlock *);
|
||||
|
||||
extern void lock_ConvertRToW(struct osi_rwlock *);
|
||||
|
||||
/* and stat functions */
|
||||
|
||||
extern int lock_GetRWLockState(struct osi_rwlock *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
|
||||
*
|
||||
* (C) COPYRIGHT IBM CORPORATION 1987, 1988
|
||||
@ -86,12 +86,12 @@ extern void osi_LogEvent(char *a,char *b,char *c,...);
|
||||
extern char *osi_HexifyString(char *s);
|
||||
|
||||
/* define macros */
|
||||
#define osi_Log0(l,f) osi_LogAdd((l), (f), 0, 0, 0, 0)
|
||||
#define osi_Log1(l,f,a) osi_LogAdd((l), (f), (size_t) (a), 0, 0, 0)
|
||||
#define osi_Log2(l,f,a,b) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), 0, 0)
|
||||
#define osi_Log3(l,f,a,b,c) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), 0)
|
||||
#define osi_Log4(l,f,a,b,c,d) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d))
|
||||
#define osi_Log5(l,f,a,b,c,d,e) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d), (size_t) (e))
|
||||
#define osi_Log0(l,f) if ((l) && (l)->enabled) osi_LogAdd((l), (f), 0, 0, 0, 0)
|
||||
#define osi_Log1(l,f,a) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), 0, 0, 0)
|
||||
#define osi_Log2(l,f,a,b) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), 0, 0)
|
||||
#define osi_Log3(l,f,a,b,c) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), 0)
|
||||
#define osi_Log4(l,f,a,b,c,d) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d))
|
||||
#define osi_Log5(l,f,a,b,c,d,e) if ((l) && (l)->enabled) osi_LogAdd((l), (f), (size_t) (a), (size_t) (b), (size_t) (c), (size_t) (d), (size_t) (e))
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
#define DEBUG_EVENT1(a,b,c) {HANDLE h; char *ptbuf[1],buf[132];\
|
||||
|
@ -35,6 +35,7 @@ typedef struct osi_lockOps {
|
||||
void (*FinalizeMutexProc)(struct osi_mutex *);
|
||||
void (*FinalizeRWLockProc)(struct osi_rwlock *);
|
||||
void (*ConvertWToRProc)(struct osi_rwlock *);
|
||||
void (*ConvertRToWProc)(struct osi_rwlock *);
|
||||
int (*GetRWLockState)(struct osi_rwlock *);
|
||||
int (*GetMutexState)(struct osi_mutex *);
|
||||
} osi_lockOps_t;
|
||||
|
@ -206,6 +206,56 @@ static void lock_ConvertWToRStat(osi_rwlock_t *lockp)
|
||||
}
|
||||
}
|
||||
|
||||
static void lock_ConvertRToWStat(osi_rwlock_t *lockp)
|
||||
{
|
||||
osi_activeInfo_t *ap;
|
||||
osi_rwlockStat_t *realp;
|
||||
CRITICAL_SECTION *csp;
|
||||
|
||||
realp = (osi_rwlockStat_t *)lockp->d.privateDatap;
|
||||
|
||||
/* otherwise we're the fast base type */
|
||||
csp = &osi_statAtomicCS[lockp->atomicIndex];
|
||||
EnterCriticalSection(csp);
|
||||
|
||||
osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
|
||||
ap = osi_FindActiveInfo(&realp->qi);
|
||||
osi_assert(ap !=NULL);
|
||||
osi_RemoveActiveInfo(&realp->qi, ap);
|
||||
realp->readLockedCount++;
|
||||
realp->readLockedTime = LargeIntegerAdd(realp->readLockedTime, ap->startTime);
|
||||
osi_FreeActiveInfo(ap);
|
||||
|
||||
if (--lockp->readers == 0) {
|
||||
/* and obtain the write lock */
|
||||
lockp->readers--;
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
} else {
|
||||
lockp->waiters++;
|
||||
ap = osi_QueueActiveInfo(&realp->qi,
|
||||
OSI_ACTIVEFLAGS_WRITER | OSI_ACTIVEFLAGS_WAITER);
|
||||
osi_TWait(&realp->turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
|
||||
lockp->waiters--;
|
||||
osi_assert((lockp->flags & OSI_LOCKFLAG_EXCL) && lockp->readers == 0);
|
||||
|
||||
/* we have some timer info about the last sleep operation
|
||||
* that we should merge in under the spin lock.
|
||||
*/
|
||||
|
||||
/* remove from queue and turn time to incremental time */
|
||||
osi_RemoveActiveInfo(&realp->qi, ap);
|
||||
|
||||
/* add in increment to statistics */
|
||||
realp->writeBlockedCount++;
|
||||
realp->writeBlockedTime = LargeIntegerAdd(realp->writeBlockedTime,
|
||||
ap->startTime);
|
||||
osi_FreeActiveInfo(ap);
|
||||
}
|
||||
|
||||
osi_QueueActiveInfo(&realp->qi, OSI_ACTIVEFLAGS_WRITER);
|
||||
LeaveCriticalSection(csp);
|
||||
}
|
||||
|
||||
static void lock_ReleaseWriteStat(osi_rwlock_t *lockp)
|
||||
{
|
||||
osi_activeInfo_t *ap;
|
||||
@ -444,7 +494,7 @@ static int lock_TryMutexStat(struct osi_mutex *lockp) {
|
||||
return i;
|
||||
}
|
||||
|
||||
static void osi_SleepRStat(long sleepVal, struct osi_rwlock *lockp)
|
||||
static void osi_SleepRStat(LONG_PTR sleepVal, struct osi_rwlock *lockp)
|
||||
{
|
||||
osi_rwlockStat_t *realp;
|
||||
osi_activeInfo_t *ap;
|
||||
@ -474,7 +524,7 @@ static void osi_SleepRStat(long sleepVal, struct osi_rwlock *lockp)
|
||||
osi_SleepSpin(sleepVal, csp);
|
||||
}
|
||||
|
||||
static void osi_SleepWStat(long sleepVal, struct osi_rwlock *lockp)
|
||||
static void osi_SleepWStat(LONG_PTR sleepVal, struct osi_rwlock *lockp)
|
||||
{
|
||||
osi_activeInfo_t *ap;
|
||||
osi_rwlockStat_t *realp;
|
||||
@ -505,7 +555,7 @@ static void osi_SleepWStat(long sleepVal, struct osi_rwlock *lockp)
|
||||
osi_SleepSpin(sleepVal, csp);
|
||||
}
|
||||
|
||||
static void osi_SleepMStat(long sleepVal, struct osi_mutex *lockp)
|
||||
static void osi_SleepMStat(LONG_PTR sleepVal, struct osi_mutex *lockp)
|
||||
{
|
||||
osi_mutexStat_t *realp;
|
||||
osi_activeInfo_t *ap;
|
||||
@ -740,6 +790,7 @@ static osi_lockOps_t osi_statOps = {
|
||||
lock_FinalizeMutexStat,
|
||||
lock_FinalizeRWLockStat,
|
||||
lock_ConvertWToRStat,
|
||||
lock_ConvertRToWStat,
|
||||
lock_GetRWLockStateStat,
|
||||
lock_GetMutexStateStat
|
||||
};
|
||||
@ -798,7 +849,7 @@ long osi_StatFDGetInfo(osi_fd_t *ifdp, osi_remGetInfoParms_t *parmsp)
|
||||
|
||||
memset((void *) parmsp, 0, sizeof(*parmsp));
|
||||
backMutexp = mp->qi.backp;
|
||||
parmsp->idata[0] = backMutexp;
|
||||
parmsp->idata[0] = (LONG_PTR)backMutexp;
|
||||
parmsp->idata[1] = (backMutexp->flags & OSI_LOCKFLAG_EXCL)? 1 : 0;
|
||||
/* reader count [2] is 0 */
|
||||
parmsp->idata[3] = (backMutexp->waiters > 0)? 1 : 0;
|
||||
@ -816,7 +867,7 @@ long osi_StatFDGetInfo(osi_fd_t *ifdp, osi_remGetInfoParms_t *parmsp)
|
||||
|
||||
memset((void *) parmsp, 0, sizeof(*parmsp));
|
||||
backRWLockp = rwp->qi.backp;
|
||||
parmsp->idata[0] = backRWLockp;
|
||||
parmsp->idata[0] = (LONG_PTR)backRWLockp;
|
||||
parmsp->idata[1] = (backRWLockp->flags & OSI_LOCKFLAG_EXCL)? 1 : 0;
|
||||
parmsp->idata[2] = backRWLockp->readers;
|
||||
parmsp->idata[3] = (backRWLockp->waiters > 0)? 1 : 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user