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:
parent
ee2a6d9940
commit
56b97da987
4 changed files with 154 additions and 1 deletions
35
NEWS
35
NEWS
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
114
ice-9/serialize.scm
Normal 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)))
|
Loading…
Add table
Add a link
Reference in a new issue