From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Kevin Ryde Newsgroups: gmane.lisp.guile.devel Subject: arbiters thread safety Date: Mon, 02 Aug 2004 10:43:32 +1000 Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: <87ekmqpdxn.fsf@zip.com.au> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1091407459 9077 80.91.224.253 (2 Aug 2004 00:44:19 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Mon, 2 Aug 2004 00:44:19 +0000 (UTC) Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Mon Aug 02 02:44:11 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BrQvz-0005MZ-00 for ; Mon, 02 Aug 2004 02:44:11 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BrQzL-00017J-SD for guile-devel@m.gmane.org; Sun, 01 Aug 2004 20:47:39 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BrQzF-00017D-0o for guile-devel@gnu.org; Sun, 01 Aug 2004 20:47:33 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BrQzE-000171-5E for guile-devel@gnu.org; Sun, 01 Aug 2004 20:47:32 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BrQzE-00016y-1y for guile-devel@gnu.org; Sun, 01 Aug 2004 20:47:32 -0400 Original-Received: from [61.8.0.85] (helo=mailout2.pacific.net.au) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BrQvb-0000bd-Ih for guile-devel@gnu.org; Sun, 01 Aug 2004 20:43:48 -0400 Original-Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87]) by mailout2.pacific.net.au (8.12.3/8.12.3/Debian-6.6) with ESMTP id i720hjje027828 for ; Mon, 2 Aug 2004 10:43:45 +1000 Original-Received: from localhost (ppp2BB4.dyn.pacific.net.au [61.8.43.180]) by mailproxy2.pacific.net.au (8.12.3/8.12.3/Debian-6.6) with ESMTP id i720hhib026065 for ; Mon, 2 Aug 2004 10:43:44 +1000 Original-Received: from gg by localhost with local (Exim 3.36 #1 (Debian)) id 1BrQvN-0005eV-00; Mon, 02 Aug 2004 10:43:33 +1000 Original-To: guile-devel@gnu.org Mail-Copies-To: never User-Agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3 (gnu/linux) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.lisp.guile.devel:3904 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:3904 --=-=-= Migrating the DEFER in try, and adding protection to the release. * arbiters.c (scm_try_arbiter): Use scm_i_misc_mutex instead of SCM_DEFER_INTS. (scm_release_arbiter): Use scm_i_misc_mutex so return value can be guaranteed if multiple threads compete to unlock. --=-=-= Content-Disposition: attachment; filename=arbiters.c.threads.diff --- arbiters.c.~1.32.~ 2003-04-07 08:05:04.000000000 +1000 +++ arbiters.c 2004-08-02 10:42:51.000000000 +1000 @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996, 1997, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996, 1997, 2000, 2001, 2004 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,12 +26,14 @@ #include "libguile/arbiters.h" -/* {Arbiters} - * - * These procedures implement synchronization primitives. Processors - * with an atomic test-and-set instruction can use it here (and not - * SCM_DEFER_INTS). - */ +/* ENHANCE-ME: If the cpu has an atomic test-and-set instruction it could be + used instead of a mutex in try-arbiter and release-arbiter. + + For the i386 family, cmpxchg would suit but it's only available on 80486 + and higher so that would have to be checked, perhaps at run-time when + setting up the definitions of the scheme procedures, or at compile time + if we interpret a host cpu type like "i686" to mean not less than that + chip. */ static scm_t_bits scm_tc16_arbiter; @@ -62,6 +64,12 @@ } #undef FUNC_NAME + +/* The mutex here is so two threads can't both see the arbiter unlocked and + both proceed to lock and return #t. The arbiter itself wouldn't be + corrupted by this, but two threads both getting #t would be entirely + contrary to the intended semantics. */ + SCM_DEFINE (scm_try_arbiter, "try-arbiter", 1, 0, 0, (SCM arb), "Return @code{#t} and lock the arbiter @var{arb} if the arbiter\n" @@ -69,7 +77,8 @@ #define FUNC_NAME s_scm_try_arbiter { SCM_VALIDATE_SMOB (1, arb, arbiter); - SCM_DEFER_INTS; + + scm_mutex_lock (&scm_i_misc_mutex); if (SCM_ARB_LOCKED(arb)) arb = SCM_BOOL_F; else @@ -77,23 +86,38 @@ SCM_LOCK_ARB(arb); arb = SCM_BOOL_T; } - SCM_ALLOW_INTS; + scm_mutex_unlock (&scm_i_misc_mutex); return arb; } #undef FUNC_NAME -SCM_DEFINE (scm_release_arbiter, "release-arbiter", 1, 0, 0, +/* The mutex here is so two threads can't both see the arbiter locked and + both proceed to unlock and return #t. The arbiter itself wouldn't be + corrupted by this, but we don't want two threads both thinking they were + the unlocker. The intended usage is for the code which locked to be + responsible for unlocking, but we guarantee the return value even if + multiple threads compete. */ + +SCM_DEFINE (scm_release_arbiter, "release-arbiter", 1, 0, 0, (SCM arb), "Return @code{#t} and unlock the arbiter @var{arb} if the\n" "arbiter was locked. Otherwise, return @code{#f}.") #define FUNC_NAME s_scm_release_arbiter { + SCM ret; SCM_VALIDATE_SMOB (1, arb, arbiter); + + scm_mutex_lock (&scm_i_misc_mutex); if (!SCM_ARB_LOCKED(arb)) - return SCM_BOOL_F; - SCM_UNLOCK_ARB (arb); - return SCM_BOOL_T; + ret = SCM_BOOL_F; + else + { + SCM_UNLOCK_ARB (arb); + ret = SCM_BOOL_T; + } + scm_mutex_unlock (&scm_i_misc_mutex); + return ret; } #undef FUNC_NAME --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://lists.gnu.org/mailman/listinfo/guile-devel --=-=-=--