* 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)) {
bp->flags |= CM_BUF_INLRU;
}
- if (!writeLocked) {
- lock_ReleaseWrite(&buf_globalLock);
- lock_ObtainRead(&buf_globalLock);
- }
+ if (!writeLocked)
+ lock_ConvertWToR(&buf_globalLock);
}
}
lock_ReleaseMutex(&scp->mx);
mxheld = 0;
}
- lock_ReleaseRead(&scp->dirlock);
- lock_ObtainWrite(&scp->dirlock);
+ lock_ConvertRToW(&scp->dirlock);
haveWrite = 1;
}
if (!mxheld) {
if ( !tnc )
{
if ( !writeLocked ) {
- lock_ReleaseRead(&cm_dnlcLock);
- lock_ObtainWrite(&cm_dnlcLock);
+ lock_ConvertRToW(&cm_dnlcLock);
writeLocked = 1;
goto retry;
}
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);
osi_LogEvent @63
osi_HexifyString @64
osi_QRemoveHT @65
+ lock_ConvertRToW @66
/* atomicity-providing critical sections */
CRITICAL_SECTION osi_baseAtomicCS[OSI_MUTEXHASHSIZE];
+static long atomicIndexCounter = 0;
void osi_BaseInit(void)
{
}
}
+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;
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;
}
*/
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);
extern void lock_ConvertWToR(struct osi_rwlock *);
+extern void lock_ConvertRToW(struct osi_rwlock *);
+
/* and stat functions */
extern int lock_GetRWLockState(struct osi_rwlock *);
-/*
+/*
* Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
*
* (C) COPYRIGHT IBM CORPORATION 1987, 1988
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];\
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;
}
}
+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;
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;
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;
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;
lock_FinalizeMutexStat,
lock_FinalizeRWLockStat,
lock_ConvertWToRStat,
+ lock_ConvertRToWStat,
lock_GetRWLockStateStat,
lock_GetMutexStateStat
};
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;
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;