Subj : Re: Memory Barriers, Compiler Optimizations, etc. To : comp.programming.threads From : Alexander Terekhov Date : Wed Feb 02 2005 03:30 pm Just to clarify... Alexander Terekhov wrote: [...] > void lock() throw() { > int old = m_lock_status.load_reserved(msync::none); > if (old || old = attempt_update(0, 1, msync::acq)) { > do { > while (old < 0 || > old = attempt_update(1, -1, msync::acq)) { ^^^^^^^^^^ Acq above is needed in order to ensure proper ordering with respect to "semaphore lock" operation on m_retry_event below. Lock status transition 1 -> -1 must complete before "semaphore lock" operation will take place (otherwise a "deadlock" can arise). > m_retry_event.wait(); > old = m_lock_status.load_reserved(msync::none); ^^^^^^^^^^^ Here proper ordering is ensured by semaphore lock operation (m_retry_event.wait()) which is meant to provide acquire semantics (m_lock_status.load_reserved(msync::none) must complete after semaphore lock operation). > if (!old) break; > } > } while (old = attempt_update(0, -1, msync::acq)); > } > } > > void unlock() throw() { > if (m_lock_status.load_reserved(msync::none) < 0 || > attempt_update(1, 0, msync::rel) < 0) { // or just !SC > m_lock_status.store(0, msync::rel); > m_retry_event.set(); ^^^^^^^^^^^^^^^^^^^ Ordering here is also important. m_retry_event.set() (semaphore unlock operation) is meant to provide release semantics (m_lock_status.store(0, msync::rel) must complete before semaphore unlock operation). > } > } > > }; regards, alexander. .