/* Thread local storage index for lock tracking */
static DWORD tls_LockRefH = 0;
static DWORD tls_LockRefT = 0;
+static BOOLEAN lockOrderValidation = 0;
void osi_BaseInit(void)
{
osi_panic("TlsAlloc(tls_LockRefT) failure", __FILE__, __LINE__);
}
+void osi_SetLockOrderValidation(int on)
+{
+ lockOrderValidation = (BOOLEAN)on;
+}
+
osi_lock_ref_t *lock_GetLockRef(void * lockp, char type)
{
osi_lock_ref_t * lockRefp = (osi_lock_ref_t *)malloc(sizeof(osi_lock_ref_t));
return;
}
- lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
- lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
+ if (lockOrderValidation) {
+ lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
+ lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
- if (lockp->level != 0)
- lock_VerifyOrderRW(lockRefH, lockRefT, lockp);
+ if (lockp->level != 0)
+ lock_VerifyOrderRW(lockRefH, lockRefT, lockp);
+ }
/* otherwise we're the fast base type */
csp = &osi_baseAtomicCS[lockp->atomicIndex];
LeaveCriticalSection(csp);
- lockRefp = lock_GetLockRef(lockp, OSI_LOCK_RW);
- osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
- TlsSetValue(tls_LockRefH, lockRefH);
- TlsSetValue(tls_LockRefT, lockRefT);
+ if (lockOrderValidation) {
+ lockRefp = lock_GetLockRef(lockp, OSI_LOCK_RW);
+ osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
+ TlsSetValue(tls_LockRefH, lockRefH);
+ TlsSetValue(tls_LockRefT, lockRefT);
+ }
}
void lock_ObtainRead(osi_rwlock_t *lockp)
return;
}
- lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
- lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
+ if (lockOrderValidation) {
+ lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
+ lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
- if (lockp->level != 0)
- lock_VerifyOrderRW(lockRefH, lockRefT, lockp);
+ if (lockp->level != 0)
+ lock_VerifyOrderRW(lockRefH, lockRefT, lockp);
+ }
/* otherwise we're the fast base type */
csp = &osi_baseAtomicCS[lockp->atomicIndex];
LeaveCriticalSection(csp);
- lockRefp = lock_GetLockRef(lockp, OSI_LOCK_RW);
- osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
- TlsSetValue(tls_LockRefH, lockRefH);
- TlsSetValue(tls_LockRefT, lockRefT);
+ if (lockOrderValidation) {
+ lockRefp = lock_GetLockRef(lockp, OSI_LOCK_RW);
+ osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
+ TlsSetValue(tls_LockRefH, lockRefH);
+ TlsSetValue(tls_LockRefT, lockRefT);
+ }
}
void lock_ReleaseRead(osi_rwlock_t *lockp)
return;
}
- if (lockp->level != 0) {
+ if (lockOrderValidation && lockp->level != 0) {
int found = 0;
lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
return;
}
- if (lockp->level != 0) {
+ if (lockOrderValidation && lockp->level != 0) {
int found = 0;
lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
return;
}
- lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
- lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
+ if (lockOrderValidation) {
+ lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
+ lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
- if (lockp->level != 0)
- lock_VerifyOrderMX(lockRefH, lockRefT, lockp);
+ if (lockp->level != 0)
+ lock_VerifyOrderMX(lockRefH, lockRefT, lockp);
+ }
/* otherwise we're the fast base type */
csp = &osi_baseAtomicCS[lockp->atomicIndex];
lockp->tid = thrd_Current();
LeaveCriticalSection(csp);
- lockRefp = lock_GetLockRef(lockp, OSI_LOCK_MUTEX);
- osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
- TlsSetValue(tls_LockRefH, lockRefH);
- TlsSetValue(tls_LockRefT, lockRefT);
+ if (lockOrderValidation) {
+ lockRefp = lock_GetLockRef(lockp, OSI_LOCK_MUTEX);
+ osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
+ TlsSetValue(tls_LockRefH, lockRefH);
+ TlsSetValue(tls_LockRefT, lockRefT);
+ }
}
void lock_ReleaseMutex(struct osi_mutex *lockp)
return;
}
- if (lockp->level != 0) {
+ if (lockOrderValidation && lockp->level != 0) {
int found = 0;
lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
if (i >= 0 && i < OSI_NLOCKTYPES)
return (osi_lockOps[i]->TryReadProc)(lockp);
- lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
- lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
+ if (lockOrderValidation) {
+ lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
+ lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
- if (lockp->level != 0) {
- for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) {
- if (lockRefp->type == OSI_LOCK_RW) {
- osi_assertx(lockRefp->rw != lockp, "RW Lock already held");
+ if (lockp->level != 0) {
+ for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) {
+ if (lockRefp->type == OSI_LOCK_RW) {
+ osi_assertx(lockRefp->rw != lockp, "RW Lock already held");
+ }
}
}
}
LeaveCriticalSection(csp);
- if (i) {
+ if (lockOrderValidation && i) {
lockRefp = lock_GetLockRef(lockp, OSI_LOCK_RW);
osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
TlsSetValue(tls_LockRefH, lockRefH);
if (i >= 0 && i < OSI_NLOCKTYPES)
return (osi_lockOps[i]->TryWriteProc)(lockp);
- lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
- lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
+ if (lockOrderValidation) {
+ lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
+ lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
- if (lockp->level != 0) {
- for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) {
- if (lockRefp->type == OSI_LOCK_RW) {
- osi_assertx(lockRefp->rw != lockp, "RW Lock already held");
+ if (lockp->level != 0) {
+ for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) {
+ if (lockRefp->type == OSI_LOCK_RW) {
+ osi_assertx(lockRefp->rw != lockp, "RW Lock already held");
+ }
}
}
}
LeaveCriticalSection(csp);
- if (i) {
+ if (lockOrderValidation && i) {
lockRefp = lock_GetLockRef(lockp, OSI_LOCK_RW);
osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
TlsSetValue(tls_LockRefH, lockRefH);
if (i >= 0 && i < OSI_NLOCKTYPES)
return (osi_lockOps[i]->TryMutexProc)(lockp);
- lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
- lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
+ if (lockOrderValidation) {
+ lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
+ lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
- if (lockp->level != 0) {
- for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) {
- if (lockRefp->type == OSI_LOCK_MUTEX) {
- osi_assertx(lockRefp->mx != lockp, "Mutex already held");
+ if (lockp->level != 0) {
+ for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) {
+ if (lockRefp->type == OSI_LOCK_MUTEX) {
+ osi_assertx(lockRefp->mx != lockp, "Mutex already held");
+ }
}
}
}
LeaveCriticalSection(csp);
- if (i) {
+ if (lockOrderValidation && i) {
lockRefp = lock_GetLockRef(lockp, OSI_LOCK_MUTEX);
osi_QAddH(&lockRefH, &lockRefT, &lockRefp->q);
TlsSetValue(tls_LockRefH, lockRefH);
return;
}
- if (lockp->level != 0) {
+ if (lockOrderValidation && lockp->level != 0) {
lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
return;
}
- if (lockp->level != 0) {
+ if (lockOrderValidation && lockp->level != 0) {
lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);
return;
}
- if (lockp->level != 0) {
+ if (lockOrderValidation && lockp->level != 0) {
lockRefH = (osi_queue_t *)TlsGetValue(tls_LockRefH);
lockRefT = (osi_queue_t *)TlsGetValue(tls_LockRefT);