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: Re: pthread fast mutexes Date: Sun, 29 Feb 2004 06:18:02 +1000 Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: <87wu67argl.fsf@zip.com.au> References: <87ishxv6m5.fsf@zip.com.au> <87oerptl3i.fsf@zip.com.au> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1077999596 11319 80.91.224.253 (28 Feb 2004 20:19:56 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 28 Feb 2004 20:19:56 +0000 (UTC) Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Feb 28 21:19:48 2004 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1AxAw8-00061r-00 for ; Sat, 28 Feb 2004 21:19:48 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.30) id 1AxAvu-0000Uu-8O for guile-devel@m.gmane.org; Sat, 28 Feb 2004 15:19:34 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.30) id 1AxAvQ-0000C2-D5 for guile-devel@gnu.org; Sat, 28 Feb 2004 15:19:04 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.30) id 1AxAul-0007mf-A1 for guile-devel@gnu.org; Sat, 28 Feb 2004 15:18:54 -0500 Original-Received: from [61.8.0.85] (helo=mailout2.pacific.net.au) by monty-python.gnu.org with esmtp (Exim 4.30) id 1AxAuj-0007lM-Rq for guile-devel@gnu.org; Sat, 28 Feb 2004 15:18:22 -0500 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 i1SKIGHa011130 for ; Sun, 29 Feb 2004 07:18:16 +1100 Original-Received: from localhost (ppp91.dyn11.pacific.net.au [61.8.11.91]) by mailproxy2.pacific.net.au (8.12.3/8.12.3/Debian-6.6) with ESMTP id i1SKIEvs007170 for ; Sun, 29 Feb 2004 07:18:15 +1100 Original-Received: from gg by localhost with local (Exim 3.36 #1 (Debian)) id 1AxAuQ-00054E-00; Sun, 29 Feb 2004 06:18:02 +1000 Original-To: guile-devel@gnu.org Mail-Copies-To: never User-Agent: Gnus/5.110002 (No Gnus v0.2) Emacs/21.3 (gnu/linux) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.2 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:3464 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:3464 Mikael Djurfeldt writes: > > Well, but the past mutexes didn't report an error either. I've not > taken away any semantics. Ah yes. Ok, below is some words for the manual to try to clarify the situation. In particular I take it the current words about mutexes being recursive applies only to fair mutexes. (This is also what I threatened about collecting up of all mutex stuff into one section, instead of spread through three places.) Mutexes ======= - Scheme Procedure: make-mutex - Scheme Procedure: make-fair-mutex Create a new mutex object. A standard mutex (`make-mutex') is fast, but its features are minimal. Recursive locking (multiple lock calls) is not permitted, and an unlock can be done only when already locked, and only by the owning thread. When multiple threads are blocked waiting to acquire the mutex, it's unspecified which will get it next. A fair mutex (`make-fair-mutex') on the other hand has more features and error checking. Recursive locking is allowed, a given thread can make multiple lock calls and the mutex is released when a balancing number of unlocks are done. Other threads blocked waiting to acquire the mutex form a queue and the one waiting longest will be the next to acquire it. Note that in both cases there is no protection against a "deadly embrace". For instance currently an endless wait will occur if one thread has locked mutex A and is waiting on mutex B, but another thread owns B and is waiting on A. Acquiring requisite mutexes in a fixed order (like always A before B) in all threads is one way to avoid such problems. - Scheme Procedure: lock-mutex mutex Lock MUTEX. If the mutex is already locked by another thread then the calling thread is blocked and `lock-mutex' only returns when the mutex is acquired and locked. For standard mutexes (`make-mutex'), a thread which has locked MUTEX must not call `lock-mutex' on it a further time. Behaviour is unspecified if this is done. For a fair mutex (`make-fair-mutex'), a thread may call `lock-mutex' to lock MUTEX again, this will then require a further balancing `unlock-mutex' to release. When a system async is activated for a thread blocked in a call to `lock-mutex', the waiting is interrupted and the async is executed. When the async returns, the waiting is resumed. - Scheme Procedure: try-mutex mutex Try to lock MUTEX as per `lock-mutex', but without waiting. If MUTEX can be acquired immediately, this is done and the return is `#t'. If MUTEX is owned by some other thread then nothing is done and the return is `#f'. - Scheme Procedure: unlock-mutex mutex Unlock MUTEX. For a standard mutex (`make-mutex'), behaviour is unspecified if the calling thread has not locked MUTEX. For a fair mutex (`make-fair-mutex'), an error is thrown if the calling thread does not own MUTEX. - macro: with-mutex mutex [body...] Lock MUTEX, evaluate BODY, and then unlock MUTEX. These sub-operations form the branches of a `dynamic-wind', so MUTEX is unlocked if an error or new continuation exits BODY, and is re-locked if BODY is re-entered by a captured continuation. - macro: monitor body... Evaluate BODY, with a mutex locked so only one thread can execute that code at any one time. The return value is the return from the last form in BODY. Each `monitor' form has its own private mutex and the locking is done as per `with-mutex' above. A standard mutex (`make-mutex') is used, which means BODY must not recursively re-enter its `monitor' form. The term "monitor" comes from operating system theory, where it means a particular bit of code managing access to some resource and which only ever executes on behalf of one process at any one time. For C code, the standard mutexes described above can be used with the following C datatype and functions. - C Data Type: scm_t_mutex A mutex, to be used with `scm_mutex_init', etc. - C Function: void scm_mutex_init (scm_t_mutex *m) Initialize the mutex structure pointed to by M. - C Function: void scm_mutex_destroy (scm_t_mutex *m) Deallocate all resources associated with M. - C Function: void scm_mutex_lock (scm_t_mutex *m) Lock the mutex M. When it is already locked by a different thread, wait until it becomes available. Locking a mutex that is already locked by the current threads is not allowd and results in undefined behavior. The mutexes are not guaranteed to be fair. That is, a thread that attempts a lock after yourself might be granted it before you. - C Function: int scm_mutex_trylock (scm_t_mutex *m) Lock M as per `scm_mutex_lock' but don't wait. Return non-zero when the mutex has been locked, or return zero if it is already locked by some other thread. - C Function: void scm_mutex_unlock (scm_t_mutex *m) Unlock the mutex M. The mutex must have been locked by the current thread, else the behavior is undefined. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel