From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10408 invoked by alias); 18 Oct 2003 17:47:26 -0000 Mailing-List: contact pthreads-win32-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: pthreads-win32-owner@sources.redhat.com Received: (qmail 10401 invoked from network); 18 Oct 2003 17:47:25 -0000 Received: from unknown (HELO d12lmsgate.de.ibm.com) (194.196.100.237) by sources.redhat.com with SMTP; 18 Oct 2003 17:47:25 -0000 Received: from d12relay01.megacenter.de.ibm.com (d12relay01.megacenter.de.ibm.com [9.149.165.180]) by d12lmsgate.de.ibm.com (8.12.10/8.12.8) with ESMTP id h9IHlNo0097618 for ; Sat, 18 Oct 2003 19:47:23 +0200 Received: from d12ml007.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12relay01.megacenter.de.ibm.com (8.12.9/NCO/VER6.6) with ESMTP id h9IHlNf1223486 for ; Sat, 18 Oct 2003 19:47:23 +0200 Importance: Normal MIME-Version: 1.0 Sensitivity: To: pthreads-win32@sources.redhat.com Subject: mutexes: "food for thought" Message-ID: From: "Alexander Terekhov" Date: Sat, 18 Oct 2003 17:47:00 -0000 Content-Type: text/plain; charset="US-ASCII" X-SW-Source: 2003/txt/msg00108.txt.bz2 G'Day, here's "ala futex based" mutex stuff using XCHG. No need for CAS. I hope that it will work just fine. Can you see any harmful race condition(s) here? TIA. #define SWAP_BASED_MUTEX_FOR_WINDOWS_INITIALIZER { 0, 0 } struct swap_based_mutex_for_windows { atomic m_lock_status; // -1: free, 0: locked, 1 lock-contention atomic m_retry_event; // DCSI'd void DCSI(); // double-checked serialized initialization void slow_lock(); bool slow_trylock(); bool slow_timedlock(absolute_timeout const & timeout); void release_one_waiter_if_any(); void lock() { if (m_lock_status.swap(0, msync::acq) >= 0) slow_lock(); } bool trylock() { return (m_lock_status.swap(0, msync::acq) < 0) ? true : slow_trylock(); } bool timedlock(absolute_timeout const & timeout) { return (m_lock_status.swap(0, msync::acq) < 0) ? true : slow_timedlock(timeout); } void unlock() { if (m_lock_status.swap(-1, msync::rel) > 0) release_one_waiter_if_any(); } }; void swap_based_mutex_for_windows::slow_lock() { DCSI(); while (m_lock_status.swap(1, msync::acq) >= 0) m_retry_event.load(msync::none)->wait(); } bool swap_based_mutex_for_windows::slow_trylock() { DCSI(); return m_lock_status.swap(1, msync::acq) < 0; } bool swap_based_mutex_for_windows::slow_timedlock(absolute_timeout const & timeout) { DCSI(); while (m_lock_status.swap(1, msync::acq) >= 0) if (!m_retry_event.load(msync::none)->timedwait(timeout)) return false; return true; } void swap_based_mutex_for_windows::release_one_waiter_if_any() { m_retry_event.load(msync::none)->set(); } void swap_based_mutex_for_windows::DCSI() { if (!m_retry_event.load(msync::none)) { named_windows_mutex_trick guard(this); if (!m_retry_event.load(msync::none)) { m_retry_event.store(new auto_reset_event(), msync::rel); m_lock_status.store(-1, msync::rel); } } } regards, alexander. P.S. I've never run it. Just a sketch.