Subj : Re: Optimization to Jeffrey Richter's COptex (Windows)? To : comp.programming.threads From : Joseph Seigh Date : Wed Jan 26 2005 08:04 pm On Wed, 26 Jan 2005 14:47:17 -0800, SenderX wrote: >> http://www.microsoft.com/msj/0198/win320198.aspx >> http://www.microsoft.com/msj/0198/win32textfigs.htm#fig2 > > This is crap. Use the mutex logic that Alex suggested. > > The coptex waiting logic should be changed to something like __inline void CoptexSpin(coptex_t *lock) { DWORD SpinCount; if (lock->m_lLockCount != 0 && lock->m_dwThreadId != GetCurrentThreadId()) { SpinCount = lock->m_dwSpinCount; while ((SpinCount-- > 0) && lock->m_lLockCount != 0) __asm pause; } return; } void CoptexEnter(coptex_t *lock) { CoptexSpin(lock); if (InterlockedIncrement(&(lock->m_lLockCount)) == 1) { lock->m_dwThreadId = GetCurrentThreadId(); } else if (lock->m_dwThreadId != GetCurrentThreadId()) { WaitForSingleObject(lock->hEvent, INFINITE); lock->m_dwThreadId = GetCurrentThreadId(); } lock->m_lRecurseCount++; return; } BOOL CoptexTryEnter(coptex_t *lock) { CoptexSpin(lock); if (InterlockedCompareExchange(&(lock->m_lLockCount), 1, 0) == 0) { lock->m_dwThreadId = GetCurrentThreadId(); lock->m_lRecurseCount = 1; return TRUE; } else if (lock->m_dwThreadId == GetCurrentThreadId()) { lock->m_lRecurseCount++; return TRUE; } return FALSE; } I'm assuming GetCurrentThreadId or an equivalent intrinsic is very efficient. With an unconditional increment of the lockcount you end up with the threadid final check after a memory barrier anyway so paranoids like Alexander should be happy. :) This is not an adaptive lock so it's not going to scale as well as one. One might be better off using other logic. -- Joe Seigh .