-/*
+/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
lockp->waiters++;
if (!ap) ap = osi_QueueActiveInfo(&realp->qi,
OSI_ACTIVEFLAGS_WRITER | OSI_ACTIVEFLAGS_WAITER);
- osi_TWait(&realp->turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
+ osi_TWait(&realp->turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, lockp->tid, csp);
lockp->waiters--;
osi_assert((lockp->flags & OSI_LOCKFLAG_EXCL) && lockp->readers == 0);
}
if (ap) {
/* 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,
lockp->waiters++;
if (!ap) ap = osi_QueueActiveInfo(&realp->qi,
OSI_ACTIVEFLAGS_WAITER | OSI_ACTIVEFLAGS_READER);
- osi_TWait(&realp->turn, OSI_SLEEPINFO_W4READ, &lockp->readers, csp);
+ osi_TWait(&realp->turn, OSI_SLEEPINFO_W4READ, &lockp->readers, lockp->tid, csp);
lockp->waiters--;
osi_assert(!(lockp->flags & OSI_LOCKFLAG_EXCL) && lockp->readers > 0);
}
realp->readLockedCount++;
realp->readLockedTime = LargeIntegerAdd(realp->readLockedTime, ap->startTime);
osi_FreeActiveInfo(ap);
-
+
if (--lockp->readers == 0 && !osi_TEmpty(&realp->turn)) {
osi_TSignalForMLs(&realp->turn, 0, csp);
}
realp->writeLockedCount++;
realp->writeLockedTime = LargeIntegerAdd(realp->writeLockedTime, ap->startTime);
osi_FreeActiveInfo(ap);
-
+
/* and obtain the read lock */
lockp->readers++;
osi_QueueActiveInfo(&realp->qi, OSI_ACTIVEFLAGS_READER);
-
+
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
if (!osi_TEmpty(&realp->turn)) {
osi_TSignalForMLs(&realp->turn, 1, csp);
}
}
+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, lockp->tid, 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;
realp->writeLockedCount++;
realp->writeLockedTime = LargeIntegerAdd(realp->writeLockedTime, ap->startTime);
osi_FreeActiveInfo(ap);
-
+
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
if (!osi_TEmpty(&realp->turn)) {
osi_TSignalForMLs(&realp->turn, 0, csp);
if (lockp->waiters > 0 || (lockp->flags & OSI_LOCKFLAG_EXCL)) {
lockp->waiters++;
ap = osi_QueueActiveInfo(&realp->qi, OSI_ACTIVEFLAGS_WAITER);
- osi_TWait(&realp->turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
+ osi_TWait(&realp->turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, &lockp->tid, csp);
lockp->waiters--;
osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
}
EnterCriticalSection(csp);
osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
-
+
ap = osi_FindActiveInfo(&realp->qi);
osi_assert(ap != NULL);
osi_RemoveActiveInfo(&realp->qi, ap);
static int lock_TryReadStat(struct osi_rwlock *lockp)
{
long i;
- osi_rwlockStat_t *realp;
+ osi_rwlockStat_t *realp;
CRITICAL_SECTION *csp;
realp = (osi_rwlockStat_t *) lockp->d.privateDatap;
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;
EnterCriticalSection(csp);
osi_assert(lockp->readers > 0);
-
+
if (--lockp->readers == 0 && !osi_TEmpty(&realp->turn)) {
osi_TSignalForMLs(&realp->turn, 0, NULL);
}
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;
EnterCriticalSection(csp);
osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
-
+
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
if (!osi_TEmpty(&realp->turn)) {
osi_TSignalForMLs(&realp->turn, 0, NULL);
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;
EnterCriticalSection(csp);
osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
-
+
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
if (!osi_TEmpty(&realp->turn)) {
osi_TSignalForMLs(&realp->turn, 0, NULL);
static void lock_FinalizeMutexStat(osi_mutex_t *lockp)
{
osi_mutexStat_t *realp;
-
+
/* pull out the real pointer */
realp = (osi_mutexStat_t *) lockp->d.privateDatap;
-
+
/* remove from the queues, and free */
EnterCriticalSection(&osi_statFDCS);
if (realp->refCount <= 0) {
static void lock_FinalizeRWLockStat(osi_rwlock_t *lockp)
{
osi_rwlockStat_t *realp;
-
+
/* pull out the real pointer */
realp = (osi_rwlockStat_t *) lockp->d.privateDatap;
-
+
/* remove from the queues, and free */
EnterCriticalSection(&osi_statFDCS);
if (realp->refCount <= 0) {
LeaveCriticalSection(&osi_statFDCS);
}
-void lock_InitializeRWLockStat(osi_rwlock_t *lockp, char *namep)
+void lock_InitializeRWLockStat(osi_rwlock_t *lockp, char *namep, unsigned short level)
{
osi_rwlockStat_t *realp;
-
+
realp = (osi_rwlockStat_t *) malloc(sizeof(*realp));
lockp->d.privateDatap = (void *) realp;
lockp->type = osi_statType;
LeaveCriticalSection(&osi_statFDCS);
}
-void lock_InitializeMutexStat(osi_mutex_t *lockp, char *namep)
+void lock_InitializeMutexStat(osi_mutex_t *lockp, char *namep, unsigned short level)
{
osi_mutexStat_t *realp;
-
+
realp = (osi_mutexStat_t *) malloc(sizeof(*realp));
lockp->d.privateDatap = (void *) realp;
lockp->type = osi_statType;
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] = (long) 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] = (long) 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;