1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 21:10:27 +02:00

* serialize.scm: New file.

This commit is contained in:
Mikael Djurfeldt 2003-04-25 19:49:15 +00:00
parent ee2a6d9940
commit 56b97da987
4 changed files with 154 additions and 1 deletions

35
NEWS
View file

@ -77,6 +77,41 @@ portable way.
The default is now "coop-pthread", unless your platform doesn't have
pthreads, in which case "null" threads are used.
** New module (ice-9 serialize):
(serialize FORM1 ...) and (parallelize FORM1 ...) are useful when
you don't trust the thread safety of most of your program, but
where you have some section(s) of code which you consider can run
in parallel to other sections.
They "flag" (with dynamic extent) sections of code to be of
"serial" or "parallel" nature and have the single effect of
preventing a serial section from being run in parallel with any
serial section (including itself).
Both serialize and parallelize can be nested. If so, the
inner-most construct is in effect.
NOTE 1: A serial section can run in parallel with a parallel
section.
NOTE 2: If a serial section S is "interrupted" by a parallel
section P in the following manner: S = S1 P S2, S2 is not
guaranteed to be resumed by the same thread that previously
executed S1.
WARNING: Spawning new threads within a serial section have
undefined effects. It is OK, though, to spawn threads in unflagged
sections of code where neither serialize or parallelize is in
effect.
A typical usage is when Guile is used as scripting language in some
application doing heavy computations. If each thread is
encapsulated with a serialize form, you can then put a parallelize
form around the code performing the heavy computations (typically a
C code primitive), enabling the computations to run in parallel
while the scripting code runs single-threadedly.
** Guile now includes its own version of libltdl.
We now use a modified version of libltdl that allows us to make

View file

@ -1,3 +1,7 @@
2003-04-25 Mikael Djurfeldt <mdj@kvast.blakulla.net>
* serialize.scm: New file.
2003-04-24 Mikael Djurfeldt <djurfeldt@nada.kth.se>
* threads.scm (n-for-each-par-map): New procedure.

View file

@ -35,7 +35,7 @@ ice9_sources = \
streams.scm string-fun.scm syncase.scm threads.scm \
buffered-input.scm time.scm history.scm channel.scm \
pretty-print.scm ftw.scm gap-buffer.scm occam-channel.scm \
weak-vector.scm deprecated.scm list.scm
weak-vector.scm deprecated.scm list.scm serialize.scm
subpkgdatadir = $(pkgdatadir)/${GUILE_EFFECTIVE_VERSION}/ice-9
subpkgdata_DATA = $(ice9_sources)

114
ice-9/serialize.scm Normal file
View file

@ -0,0 +1,114 @@
;;;; Copyright (C) 2003 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
;;;; License as published by the Free Software Foundation; either
;;;; version 2.1 of the License, or (at your option) any later version.
;;;;
;;;; This library is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this library; if not, write to the Free Software
;;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;;;;
;;; Commentary:
;; (serialize FORM1 ...) and (parallelize FORM1 ...) are useful when
;; you don't trust the thread safety of most of your program, but
;; where you have some section(s) of code which you consider can run
;; in parallel to other sections.
;;
;; They "flag" (with dynamic extent) sections of code to be of
;; "serial" or "parallel" nature and have the single effect of
;; preventing a serial section from being run in parallel with any
;; serial section (including itself).
;;
;; Both serialize and parallelize can be nested. If so, the
;; inner-most construct is in effect.
;;
;; NOTE 1: A serial section can run in parallel with a parallel
;; section.
;;
;; NOTE 2: If a serial section S is "interrupted" by a parallel
;; section P in the following manner: S = S1 P S2, S2 is not
;; guaranteed to be resumed by the same thread that previously
;; executed S1.
;;
;; WARNING: Spawning new threads within a serial section have
;; undefined effects. It is OK, though, to spawn threads in unflagged
;; sections of code where neither serialize or parallelize is in
;; effect.
;;
;; A typical usage is when Guile is used as scripting language in some
;; application doing heavy computations. If each thread is
;; encapsulated with a serialize form, you can then put a parallelize
;; form around the code performing the heavy computations (typically a
;; C code primitive), enabling the computations to run in parallel
;; while the scripting code runs single-threadedly.
;;
;;; Code:
(define-module (ice-9 serialize)
:use-module (ice-9 threads)
:export (call-with-serialization
call-with-parallelization)
:export-syntax (serialize
parallelize))
(define serialization-mutex (make-mutex))
(define admin-mutex (make-mutex))
(define owner #f)
(define (call-with-serialization thunk)
(let ((outer-owner #f))
(dynamic-wind
(lambda ()
(lock-mutex admin-mutex)
(set! outer-owner owner)
(if (not (eqv? outer-owner (dynamic-root)))
(begin
(unlock-mutex admin-mutex)
(lock-mutex serialization-mutex)
(set! owner (dynamic-root)))
(unlock-mutex admin-mutex)))
thunk
(lambda ()
(lock-mutex admin-mutex)
(if (not (eqv? outer-owner (dynamic-root)))
(begin
(set! owner #f)
(unlock-mutex serialization-mutex)))
(unlock-mutex admin-mutex)))))
(define-macro (serialize . forms)
`(call-with-serialization (lambda () ,@forms)))
(define (call-with-parallelization thunk)
(let ((outer-owner #f))
(dynamic-wind
(lambda ()
(lock-mutex admin-mutex)
(set! outer-owner owner)
(if (eqv? outer-owner (dynamic-root))
(begin
(set! owner #f)
(unlock-mutex serialization-mutex)))
(unlock-mutex admin-mutex))
thunk
(lambda ()
(lock-mutex admin-mutex)
(if (eqv? outer-owner (dynamic-root))
(begin
(unlock-mutex admin-mutex)
(lock-mutex serialization-mutex)
(set! owner outer-owner))
(unlock-mutex admin-mutex))))))
(define-macro (parallelize . forms)
`(call-with-parallelization (lambda () ,@forms)))