Subj : Re: Recursive mutexes To : comp.programming.threads From : doug Date : Sun Mar 27 2005 12:22 pm "Chris Thomasson" <_no_damn_spam_cristom@_no_damn_comcast.net_spam> wrote in message news:HMadndFiKdmz0t7fRVn-2g@comcast.com... >> Not in my system. Why you assume I'm using windows? :-) > > DOH! > > I instantly thought windows because you used EnterCriticalSection. I > failed to see the call to ExitCriticalSection. Windows has > EnterCriticalSection/LeaveCriticalSection API's. Thats what confuused me. > > > > >>(In fact, AFAIK, windows does support recursive mutexes). > > Yes it does. > > >> No, in my case they're implemented with a semaphore, so calling it twice >> in a row >> in the same thread would deadlock. This is an embedded system, and the >> synchronization support >> isn't very good. It's quite minimal. This is why I need to do it by >> myself. > > Ok, you can do it like this: > > > void my_mutex::acquire() { > if (m_owner == thread_id) { > ++m_count; > return; > } This may not be relevant (depending on your OS/hardware) - but the above will not work on a multi-CPU system. There is no memory barrier op before the read of m_owner, so a cpu could read an out of date value from its cache. Bug would manifest itself as a thread recursively acquiring mutex (i.e. has not called ExitCriticalSection() - the barrier which 'writes' the value of m_owner), but on different cpu, seeing an old value of m_owner, skipping the increment of m_count and (according to your description of the behaviour) hanging on EnterCriticalSection. > > EnterCriticalSection(); > m_owner = thread_id; > } > > > > > void my_mutex::release() { > if (m_count) { > --m_count; > if ( m_count ) { return; } > } > > m_owner = 0; > ExitCriticalSection(); > } > > > > .