mirror of
https://git.openafs.org/openafs.git
synced 2025-01-19 23:40:13 +00:00
Windows: record history of read lock threads
Maintance an array of up to 32 reader threads that have acquired a rwlock. Use it for debugging when things go bad. Change-Id: I2e2e781ff355f1452e991898dfb5b91c47db9e34 Reviewed-on: http://gerrit.openafs.org/5411 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:
parent
1de4561529
commit
c9d655b9a6
@ -177,17 +177,14 @@ void lock_ObtainWrite(osi_rwlock_t *lockp)
|
||||
if (lockp->waiters > 0 || (lockp->flags & OSI_LOCKFLAG_EXCL) ||
|
||||
(lockp->readers > 0)) {
|
||||
lockp->waiters++;
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, lockp->tid, csp);
|
||||
lockp->waiters--;
|
||||
osi_assert(lockp->readers == 0 && (lockp->flags & OSI_LOCKFLAG_EXCL));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* if we're here, all clear to set the lock */
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
lockp->tid[0] = thrd_Current();
|
||||
}
|
||||
|
||||
lockp->tid = thrd_Current();
|
||||
|
||||
LeaveCriticalSection(csp);
|
||||
|
||||
if (lockOrderValidation) {
|
||||
@ -204,6 +201,7 @@ void lock_ObtainRead(osi_rwlock_t *lockp)
|
||||
CRITICAL_SECTION *csp;
|
||||
osi_queue_t * lockRefH, *lockRefT;
|
||||
osi_lock_ref_t *lockRefp;
|
||||
DWORD tid = thrd_Current();
|
||||
|
||||
if ((i=lockp->type) != 0) {
|
||||
if (i >= 0 && i < OSI_NLOCKTYPES)
|
||||
@ -223,18 +221,21 @@ void lock_ObtainRead(osi_rwlock_t *lockp)
|
||||
csp = &osi_baseAtomicCS[lockp->atomicIndex];
|
||||
EnterCriticalSection(csp);
|
||||
|
||||
for ( i=0; i < lockp->readers; i++ ) {
|
||||
osi_assertx(lockp->tid[i] != tid, "OSI_RWLOCK_READHELD");
|
||||
}
|
||||
|
||||
/* here we have the fast lock, so see if we can obtain the real lock */
|
||||
if (lockp->waiters > 0 || (lockp->flags & OSI_LOCKFLAG_EXCL)) {
|
||||
lockp->waiters++;
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4READ, &lockp->readers, csp);
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4READ, &lockp->readers, lockp->tid, csp);
|
||||
lockp->waiters--;
|
||||
osi_assert(!(lockp->flags & OSI_LOCKFLAG_EXCL) && lockp->readers > 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* if we're here, all clear to set the lock */
|
||||
lockp->readers++;
|
||||
if (++lockp->readers <= OSI_RWLOCK_THREADS)
|
||||
lockp->tid[lockp->readers-1] = tid;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(csp);
|
||||
|
||||
if (lockOrderValidation) {
|
||||
@ -251,6 +252,7 @@ void lock_ReleaseRead(osi_rwlock_t *lockp)
|
||||
CRITICAL_SECTION *csp;
|
||||
osi_queue_t * lockRefH, *lockRefT;
|
||||
osi_lock_ref_t *lockRefp;
|
||||
DWORD tid = thrd_Current();
|
||||
|
||||
if ((i = lockp->type) != 0) {
|
||||
if (i >= 0 && i < OSI_NLOCKTYPES)
|
||||
@ -283,6 +285,15 @@ void lock_ReleaseRead(osi_rwlock_t *lockp)
|
||||
|
||||
osi_assertx(lockp->readers > 0, "read lock not held");
|
||||
|
||||
for ( i=0; i < lockp->readers; i++) {
|
||||
if ( lockp->tid[i] == tid ) {
|
||||
for ( ; i < lockp->readers - 1; i++)
|
||||
lockp->tid[i] = lockp->tid[i+1];
|
||||
lockp->tid[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* releasing a read lock can allow readers or writers */
|
||||
if (--lockp->readers == 0 && !osi_TEmpty(&lockp->d.turn)) {
|
||||
osi_TSignalForMLs(&lockp->d.turn, 0, csp);
|
||||
@ -330,9 +341,9 @@ void lock_ReleaseWrite(osi_rwlock_t *lockp)
|
||||
EnterCriticalSection(csp);
|
||||
|
||||
osi_assertx(lockp->flags & OSI_LOCKFLAG_EXCL, "write lock not held");
|
||||
osi_assertx(lockp->tid == thrd_Current(), "write lock not held by current thread");
|
||||
osi_assertx(lockp->tid[0] == thrd_Current(), "write lock not held by current thread");
|
||||
|
||||
lockp->tid = 0;
|
||||
lockp->tid[0] = 0;
|
||||
|
||||
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
|
||||
if (!osi_TEmpty(&lockp->d.turn)) {
|
||||
@ -360,14 +371,12 @@ void lock_ConvertWToR(osi_rwlock_t *lockp)
|
||||
EnterCriticalSection(csp);
|
||||
|
||||
osi_assertx(lockp->flags & OSI_LOCKFLAG_EXCL, "write lock not held");
|
||||
osi_assertx(lockp->tid == thrd_Current(), "write lock not held by current thread");
|
||||
osi_assertx(lockp->tid[0] == thrd_Current(), "write lock not held by current thread");
|
||||
|
||||
/* convert write lock to read lock */
|
||||
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
|
||||
lockp->readers++;
|
||||
|
||||
lockp->tid = 0;
|
||||
|
||||
if (!osi_TEmpty(&lockp->d.turn)) {
|
||||
osi_TSignalForMLs(&lockp->d.turn, /* still have readers */ 1, csp);
|
||||
}
|
||||
@ -381,6 +390,7 @@ void lock_ConvertRToW(osi_rwlock_t *lockp)
|
||||
{
|
||||
long i;
|
||||
CRITICAL_SECTION *csp;
|
||||
DWORD tid = thrd_Current();
|
||||
|
||||
if ((i = lockp->type) != 0) {
|
||||
if (i >= 0 && i < OSI_NLOCKTYPES)
|
||||
@ -395,17 +405,26 @@ void lock_ConvertRToW(osi_rwlock_t *lockp)
|
||||
osi_assertx(!(lockp->flags & OSI_LOCKFLAG_EXCL), "write lock held");
|
||||
osi_assertx(lockp->readers > 0, "read lock not held");
|
||||
|
||||
for ( i=0; i < lockp->readers; i++) {
|
||||
if ( lockp->tid[i] == tid ) {
|
||||
for ( ; i < lockp->readers - 1; i++)
|
||||
lockp->tid[i] = lockp->tid[i+1];
|
||||
lockp->tid[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (--lockp->readers == 0) {
|
||||
/* convert read lock to write lock */
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
lockp->tid[0] = tid;
|
||||
} else {
|
||||
lockp->waiters++;
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, lockp->tid, csp);
|
||||
lockp->waiters--;
|
||||
osi_assert(lockp->readers == 0 && (lockp->flags & OSI_LOCKFLAG_EXCL));
|
||||
}
|
||||
|
||||
lockp->tid = thrd_Current();
|
||||
LeaveCriticalSection(csp);
|
||||
}
|
||||
|
||||
@ -437,15 +456,14 @@ void lock_ObtainMutex(struct osi_mutex *lockp)
|
||||
/* here we have the fast lock, so see if we can obtain the real lock */
|
||||
if (lockp->waiters > 0 || (lockp->flags & OSI_LOCKFLAG_EXCL)) {
|
||||
lockp->waiters++;
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, csp);
|
||||
osi_TWait(&lockp->d.turn, OSI_SLEEPINFO_W4WRITE, &lockp->flags, &lockp->tid, csp);
|
||||
lockp->waiters--;
|
||||
osi_assert(lockp->flags & OSI_LOCKFLAG_EXCL);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* if we're here, all clear to set the lock */
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
}
|
||||
lockp->tid = thrd_Current();
|
||||
}
|
||||
LeaveCriticalSection(csp);
|
||||
|
||||
if (lockOrderValidation) {
|
||||
@ -540,7 +558,8 @@ int lock_TryRead(struct osi_rwlock *lockp)
|
||||
}
|
||||
else {
|
||||
/* if we're here, all clear to set the lock */
|
||||
lockp->readers++;
|
||||
if (++lockp->readers < OSI_RWLOCK_THREADS)
|
||||
lockp->tid[lockp->readers-1] = thrd_Current();
|
||||
i = 1;
|
||||
}
|
||||
|
||||
@ -593,12 +612,10 @@ int lock_TryWrite(struct osi_rwlock *lockp)
|
||||
else {
|
||||
/* if we're here, all clear to set the lock */
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
lockp->tid[0] = thrd_Current();
|
||||
i = 1;
|
||||
}
|
||||
|
||||
if (i)
|
||||
lockp->tid = thrd_Current();
|
||||
|
||||
LeaveCriticalSection(csp);
|
||||
|
||||
if (lockOrderValidation && i) {
|
||||
@ -646,12 +663,10 @@ int lock_TryMutex(struct osi_mutex *lockp) {
|
||||
else {
|
||||
/* if we're here, all clear to set the lock */
|
||||
lockp->flags |= OSI_LOCKFLAG_EXCL;
|
||||
lockp->tid = thrd_Current();
|
||||
i = 1;
|
||||
}
|
||||
|
||||
if (i)
|
||||
lockp->tid = thrd_Current();
|
||||
|
||||
LeaveCriticalSection(csp);
|
||||
|
||||
if (lockOrderValidation && i) {
|
||||
@ -669,6 +684,7 @@ void osi_SleepR(LONG_PTR sleepVal, struct osi_rwlock *lockp)
|
||||
CRITICAL_SECTION *csp;
|
||||
osi_queue_t * lockRefH, *lockRefT;
|
||||
osi_lock_ref_t *lockRefp;
|
||||
DWORD tid = thrd_Current();
|
||||
|
||||
if ((i = lockp->type) != 0) {
|
||||
if (i >= 0 && i < OSI_NLOCKTYPES)
|
||||
@ -698,6 +714,15 @@ void osi_SleepR(LONG_PTR sleepVal, struct osi_rwlock *lockp)
|
||||
|
||||
osi_assertx(lockp->readers > 0, "osi_SleepR: not held");
|
||||
|
||||
for ( i=0; i < lockp->readers; i++) {
|
||||
if ( lockp->tid[i] == tid ) {
|
||||
for ( ; i < lockp->readers - 1; i++)
|
||||
lockp->tid[i] = lockp->tid[i+1];
|
||||
lockp->tid[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX better to get the list of things to wakeup from TSignalForMLs, and
|
||||
* then do the wakeup after SleepSpin releases the low-level mutex.
|
||||
*/
|
||||
@ -715,6 +740,7 @@ void osi_SleepW(LONG_PTR sleepVal, struct osi_rwlock *lockp)
|
||||
CRITICAL_SECTION *csp;
|
||||
osi_queue_t * lockRefH, *lockRefT;
|
||||
osi_lock_ref_t *lockRefp;
|
||||
DWORD tid = thrd_Current();
|
||||
|
||||
if ((i = lockp->type) != 0) {
|
||||
if (i >= 0 && i < OSI_NLOCKTYPES)
|
||||
@ -745,6 +771,7 @@ void osi_SleepW(LONG_PTR sleepVal, struct osi_rwlock *lockp)
|
||||
osi_assertx(lockp->flags & OSI_LOCKFLAG_EXCL, "osi_SleepW: not held");
|
||||
|
||||
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
|
||||
lockp->tid[0] = 0;
|
||||
if (!osi_TEmpty(&lockp->d.turn)) {
|
||||
osi_TSignalForMLs(&lockp->d.turn, 0, NULL);
|
||||
}
|
||||
@ -789,6 +816,7 @@ void osi_SleepM(LONG_PTR sleepVal, struct osi_mutex *lockp)
|
||||
osi_assertx(lockp->flags & OSI_LOCKFLAG_EXCL, "osi_SleepM not held");
|
||||
|
||||
lockp->flags &= ~OSI_LOCKFLAG_EXCL;
|
||||
lockp->tid = 0;
|
||||
if (!osi_TEmpty(&lockp->d.turn)) {
|
||||
osi_TSignalForMLs(&lockp->d.turn, 0, NULL);
|
||||
}
|
||||
@ -850,11 +878,8 @@ void lock_InitializeRWLock(osi_rwlock_t *mp, char *namep, unsigned short level)
|
||||
/* otherwise we have the base case, which requires no special
|
||||
* initialization.
|
||||
*/
|
||||
mp->type = 0;
|
||||
mp->flags = 0;
|
||||
memset(mp, 0, sizeof(osi_rwlock_t));
|
||||
mp->atomicIndex = (unsigned short)(InterlockedIncrement(&atomicIndexCounter) % OSI_MUTEXHASHSIZE);
|
||||
mp->readers = 0;
|
||||
mp->tid = 0;
|
||||
mp->level = level;
|
||||
osi_TInit(&mp->d.turn);
|
||||
return;
|
||||
|
@ -53,11 +53,14 @@ typedef struct osi_mutex {
|
||||
*
|
||||
* This type of lock has N readers or one writer.
|
||||
*/
|
||||
|
||||
#define OSI_RWLOCK_THREADS 32
|
||||
|
||||
typedef struct osi_rwlock {
|
||||
char type; /* for all types; type 0 uses atomic count */
|
||||
char flags; /* flags for base type */
|
||||
unsigned short atomicIndex; /* index into hash table for low-level sync */
|
||||
DWORD tid; /* writer's tid */
|
||||
DWORD tid[OSI_RWLOCK_THREADS]; /* writer's tid */
|
||||
unsigned short waiters; /* waiters */
|
||||
unsigned short readers; /* readers */
|
||||
union {
|
||||
@ -149,10 +152,10 @@ extern void osi_SetLockOrderValidation(int);
|
||||
|
||||
#define lock_AssertRead(x) osi_assertx(lock_GetRWLockState(x) & OSI_RWLOCK_READHELD, "!OSI_RWLOCK_READHELD")
|
||||
|
||||
#define lock_AssertWrite(x) osi_assertx(lock_GetRWLockState(x) & OSI_RWLOCK_WRITEHELD, "!OSI_RWLOCK_WRITEHELD")
|
||||
#define lock_AssertWrite(x) osi_assertx((lock_GetRWLockState(x) & OSI_RWLOCK_WRITEHELD) && ((x)->tid[0] == thrd_Current()), "!OSI_RWLOCK_WRITEHELD")
|
||||
|
||||
#define lock_AssertAny(x) osi_assertx(lock_GetRWLockState(x) != 0, "!(OSI_RWLOCK_READHELD | OSI_RWLOCK_WRITEHELD)")
|
||||
|
||||
#define lock_AssertMutex(x) osi_assertx(lock_GetMutexState(x) & OSI_MUTEX_HELD, "!OSI_MUTEX_HELD")
|
||||
#define lock_AssertMutex(x) osi_assertx((lock_GetMutexState(x) & OSI_MUTEX_HELD) && ((x)->tid == thrd_Current()), "!OSI_MUTEX_HELD")
|
||||
|
||||
#endif /* OPENAFS_WINNT_CLIENT_OSI_OSIBASEL_H */
|
||||
|
@ -199,7 +199,8 @@ void osi_Init(void)
|
||||
osi_hyper_t bootTime;
|
||||
|
||||
/* check to see if already initialized; if so, claim success */
|
||||
if (!osi_Once(&once)) return;
|
||||
if (!osi_Once(&once))
|
||||
return;
|
||||
|
||||
/* setup boot time values */
|
||||
GetSystemTime(&sysTime);
|
||||
@ -257,7 +258,7 @@ void osi_Init(void)
|
||||
osi_EndOnce(&once);
|
||||
}
|
||||
|
||||
void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, CRITICAL_SECTION *releasep)
|
||||
void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, CRITICAL_SECTION *releasep)
|
||||
{
|
||||
osi_sleepInfo_t *sp;
|
||||
unsigned int code;
|
||||
@ -273,6 +274,7 @@ void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, CRITICAL_SECTI
|
||||
sp->refCount = 0;
|
||||
sp->waitFor = waitFor;
|
||||
sp->value = (LONG_PTR) patchp;
|
||||
sp->tidp = tidp;
|
||||
osi_QAddT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
|
||||
if (!turnp->lastp)
|
||||
turnp->lastp = sp;
|
||||
@ -366,9 +368,11 @@ void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, CRITICAL_SE
|
||||
* wakeup.
|
||||
*/
|
||||
if (tsp->waitFor & OSI_SLEEPINFO_W4WRITE) {
|
||||
if (wokeReader) break;
|
||||
if (wokeReader)
|
||||
break;
|
||||
}
|
||||
else wokeReader = 1;
|
||||
else
|
||||
wokeReader = 1;
|
||||
|
||||
/* otherwise, we will wake this guy. For now, remove from this list
|
||||
* and move to private one, so we can do the wakeup after releasing
|
||||
@ -381,10 +385,13 @@ void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, CRITICAL_SE
|
||||
if (tsp->waitFor & OSI_SLEEPINFO_W4WRITE) {
|
||||
cp = (void *) tsp->value;
|
||||
(*cp) |= OSI_LOCKFLAG_EXCL;
|
||||
tsp->tidp[0] = tsp->tid;
|
||||
}
|
||||
else if (tsp->waitFor & OSI_SLEEPINFO_W4READ) {
|
||||
sp = (void *) tsp->value;
|
||||
(*sp)++;
|
||||
if ((*sp) <= OSI_RWLOCK_THREADS)
|
||||
tsp->tidp[(*sp)-1] = tsp->tid;
|
||||
}
|
||||
|
||||
/* and add to our own list */
|
||||
@ -394,11 +401,13 @@ void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, CRITICAL_SE
|
||||
/* now if we woke a writer, we're done, since it is pointless
|
||||
* to wake more than one writer.
|
||||
*/
|
||||
if (!wokeReader) break;
|
||||
if (!wokeReader)
|
||||
break;
|
||||
}
|
||||
|
||||
/* hit end, or found someone we're not supposed to wakeup */
|
||||
if (csp) LeaveCriticalSection(csp);
|
||||
if (csp)
|
||||
LeaveCriticalSection(csp);
|
||||
|
||||
/* finally, wakeup everyone we found. Don't free things since the sleeper
|
||||
* will free the sleepInfo structure.
|
||||
@ -566,8 +575,10 @@ void osi_AdvanceSleepFD(osi_sleepFD_t *cp)
|
||||
osi_ReleaseSleepInfo(sip);
|
||||
sip = nsip;
|
||||
|
||||
if (sip) sip->refCount++;
|
||||
else idx++;
|
||||
if (sip)
|
||||
sip->refCount++;
|
||||
else
|
||||
idx++;
|
||||
}
|
||||
cp->idx = idx;
|
||||
cp->sip = sip;
|
||||
@ -577,7 +588,8 @@ void osi_AdvanceSleepFD(osi_sleepFD_t *cp)
|
||||
* done, otherwise we continue and look at the next hash bucket
|
||||
* until we're out of them.
|
||||
*/
|
||||
if (sip) break;
|
||||
if (sip)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,12 +647,14 @@ int osi_IsPrime(unsigned long x)
|
||||
|
||||
for(c = 3; c<x; c += 2) {
|
||||
/* see if x is divisible by c */
|
||||
if ((x % c) == 0) return 0; /* yup, it ain't prime */
|
||||
if ((x % c) == 0)
|
||||
return 0; /* yup, it ain't prime */
|
||||
|
||||
/* see if we've gone far enough; only have to compute until
|
||||
* square root of x.
|
||||
*/
|
||||
if (c*c > x) return 1;
|
||||
if (c*c > x)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* probably never get here */
|
||||
@ -652,7 +666,8 @@ unsigned long osi_PrimeLessThan(unsigned long x) {
|
||||
unsigned long c;
|
||||
|
||||
for(c = x; c > 1; c--) {
|
||||
if (osi_IsPrime(c)) return c;
|
||||
if (osi_IsPrime(c))
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ever reached? */
|
||||
|
@ -27,6 +27,7 @@
|
||||
typedef struct osi_sleepInfo {
|
||||
osi_queue_t q;
|
||||
LONG_PTR value; /* sleep value when in a sleep queue, patch addr for turnstiles */
|
||||
DWORD *tidp; /* tid history */
|
||||
size_t tid; /* thread ID of sleeper */
|
||||
EVENT_HANDLE sema; /* semaphore for this entry */
|
||||
unsigned short states; /* states bits */
|
||||
@ -144,7 +145,8 @@ void osi_panic(char *, char *, long);
|
||||
|
||||
time_t osi_Time(void);
|
||||
|
||||
extern void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp,
|
||||
extern void osi_TWait(osi_turnstile_t *turnp, int waitFor,
|
||||
void *patchp, DWORD *tidp,
|
||||
Crit_Sec *releasep);
|
||||
|
||||
extern void osi_TSignal(osi_turnstile_t *turnp);
|
||||
|
@ -78,7 +78,7 @@ static void lock_ObtainWriteStat(osi_rwlock_t *lockp)
|
||||
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);
|
||||
}
|
||||
@ -123,7 +123,7 @@ static void lock_ObtainReadStat(osi_rwlock_t *lockp)
|
||||
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);
|
||||
}
|
||||
@ -234,7 +234,7 @@ static void lock_ConvertRToWStat(osi_rwlock_t *lockp)
|
||||
lockp->waiters++;
|
||||
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);
|
||||
|
||||
@ -302,7 +302,7 @@ static void lock_ObtainMutexStat(struct osi_mutex *lockp)
|
||||
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);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ typedef struct osi_rwlockStat {
|
||||
osi_turnstile_t turn; /* the real turnstile */
|
||||
unsigned long refCount; /* so we can iterate cleanly */
|
||||
short states;
|
||||
DWORD tid;
|
||||
DWORD tid[OSI_RWLOCK_THREADS];
|
||||
|
||||
/* statistics */
|
||||
LARGE_INTEGER writeLockedTime; /* total time held */
|
||||
|
Loading…
Reference in New Issue
Block a user