From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10187 invoked by alias); 26 Oct 2004 17:29:38 -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 10178 invoked from network); 26 Oct 2004 17:29:37 -0000 Received: from unknown (HELO mtagate2.de.ibm.com) (195.212.29.151) by sourceware.org with SMTP; 26 Oct 2004 17:29:37 -0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate2.de.ibm.com (8.12.10/8.12.10) with ESMTP id i9QHTaxD145800 for ; Tue, 26 Oct 2004 17:29:36 GMT Received: from d12ml062.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.12.10/NCO/VER6.6) with ESMTP id i9QHTZBJ180018 for ; Tue, 26 Oct 2004 19:29:35 +0200 In-Reply-To: <41668CD1.7090207@ise.canberra.edu.au> MIME-Version: 1.0 Sensitivity: To: pthreads-win32@sources.redhat.com Subject: mutexes: "food for thought" [upcoming XBOX] Message-ID: From: Alexander Terekhov Date: Tue, 26 Oct 2004 17:29:00 -0000 Content-Type: text/plain; charset="US-ASCII" X-SW-Source: 2004/txt/msg00120.txt.bz2 Given http://www.theinquirer.net/?article=14407 http://www.gamepro.com/microsoft/xbox/hardware/news/35216.shtml here's "food for thought" illustration. // doesn't provide "POSIX-safety" with respect to destruction class mutex_for_XBOX_NEXT { // noncopyable atomic m_lock_status; // 0: free, 1/-1: locked/contention auto_reset_event m_retry_event; // prohibitively slow bin.sema/gate template int attempt_update(int old, int new, T msync) { while (!m_lock_status.store_conditional(new, msync)) { int fresh = m_lock_status.load_reserved(msync::none); if (fresh != old) return fresh; } return old; } public: // ctor/dtor [w/o lazy event init] bool trylock() throw() { return !(m_lock_status.load_reserved(msync::none) || attempt_update(0, 1, msync::acq)); } // bool timedlock() omitted for brevity 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::none)) { m_retry_event.wait(); old = m_lock_status.load_reserved(msync::none); 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(); } } }; Oder? regards, alexander.