static Atomic_Ptr hashTableMem;
-#if defined(_WIN32) && !defined(VMX86_VMX)
-static Atomic_Ptr hashLockMem;
-#endif
-
/*
*-----------------------------------------------------------------------------
HashTable *hash;
MXUserPerThread *perThread = NULL;
-#if defined(_WIN32) && !defined(VMX86_VMX)
- MXRecLock *hashLock = MXUserInternalSingleton(&hashLockMem);
-
- ASSERT(hashLock);
-
- hash = HashTable_AllocOnce(&hashTableMem, 1024, HASH_INT_KEY, NULL);
-
- MXRecLockAcquire(hashLock);
-#else
hash = HashTable_AllocOnce(&hashTableMem, 1024,
HASH_INT_KEY | HASH_FLAG_ATOMIC, NULL);
-#endif
if (!HashTable_Lookup(hash, tid, (void **) &perThread)) {
/* No entry for this tid was found, allocate one? */
}
}
-#if defined(_WIN32) && !defined(VMX86_VMX)
- MXRecLockRelease(hashLock);
-#endif
-
return perThread;
}
perThread->lockArray[lastEntry] = NULL; // tidy up memory
perThread->locksHeld--;
-
-#if defined(_WIN32) && !defined(VMX86_VMX)
- /*
- * On Windows thread IDs aren't greedily recycled. If a process creates and
- * destroys many threads this can cause a memory leak of perThread data
- * (and its overhead). We avoid this by atomically (via a lock) creating
- * (upon first lock acquired) and deleting (upon last lock release) a
- * perThread.
- *
- * Yes, this is a performance cost but it only affects Windows debug
- * builds and then not by very much - we tend to run for a long time
- * with either no locks held or at least one lock held.
- */
-
- if (perThread->locksHeld == 0) {
- HashTable *hash = Atomic_ReadPtr(&hashTableMem);
- MXRecLock *hashLock = MXUserInternalSingleton(&hashLockMem);
-
- ASSERT(hash);
- ASSERT(hashLock);
-
- MXRecLockAcquire(hashLock);
- HashTable_Delete(hash, tid);
- MXRecLockRelease(hashLock);
-
- free(perThread);
- }
-#endif
}
static INLINE void *
MXUserGetThreadID(void)
{
-#if defined(_WIN32)
- /*
- * On Windows there is a problem with using VThread_CurID() - it doesn't
- * maintain unique thread ID values (PR 780775). Native thread ID values
- * and special handling are used to resolve issues.
- */
-
- return (void *) (uintptr_t) GetCurrentThreadId(); // DWORD
-#else
- /*
- * Outside of Windows there are no known issues with using VThread_CurID
- * so that is what is used.
- */
-
return (void *) (uintptr_t) VThread_CurID(); // unsigned
-#endif
}
/*