*** empty log message ***
[bpt/guile.git] / doc / ref / scheme-scheduling.texi
CommitLineData
a0e07ba4
NJ
1@page
2@node Scheduling
3@chapter Threads, Mutexes, Asyncs and Dynamic Roots
4
5[FIXME: This is pasted in from Tom Lord's original guile.texi chapter
6plus the Cygnus programmer's manual; it should be *very* carefully
7reviewed and largely reorganized.]
8
9@menu
10* Arbiters:: Synchronization primitives.
11* Asyncs:: Asynchronous procedure invocation.
12* Dynamic Roots:: Root frames of execution.
13* Threads:: Multiple threads of execution.
14* Fluids:: Dynamically scoped variables.
15@end menu
16
17
18@node Arbiters
19@section Arbiters
20
21@cindex arbiters
22
23@c FIXME::martin: Review me!
24
25Arbiters are synchronization objects. They are created with
26@code{make-arbiter}. Two or more threads can synchronize on an arbiter
27by trying to lock it using @code{try-arbiter}. This call will succeed
28if no other thread has called @code{try-arbiter} on the arbiter yet,
29otherwise it will fail and return @code{#f}. Once an arbiter is
30successfully locked, it cannot be locked by another thread until the
31thread holding the arbiter calls @code{release-arbiter} to unlock it.
32
8f85c0c6
NJ
33@deffn {Scheme Procedure} make-arbiter name
34@deffnx {C Function} scm_make_arbiter (name)
a0e07ba4
NJ
35Return an object of type arbiter and name @var{name}. Its
36state is initially unlocked. Arbiters are a way to achieve
37process synchronization.
38@end deffn
39
8f85c0c6
NJ
40@deffn {Scheme Procedure} try-arbiter arb
41@deffnx {C Function} scm_try_arbiter (arb)
a0e07ba4
NJ
42Return @code{#t} and lock the arbiter @var{arb} if the arbiter
43was unlocked. Otherwise, return @code{#f}.
44@end deffn
45
8f85c0c6
NJ
46@deffn {Scheme Procedure} release-arbiter arb
47@deffnx {C Function} scm_release_arbiter (arb)
a0e07ba4
NJ
48Return @code{#t} and unlock the arbiter @var{arb} if the
49arbiter was locked. Otherwise, return @code{#f}.
50@end deffn
51
52
53@node Asyncs
54@section Asyncs
55
56@cindex asyncs
57@cindex system asyncs
58
59@c FIXME::martin: Review me!
60
61An async is a pair of one thunk (a parameterless procedure) and a mark.
62Setting the mark on an async guarantees that the thunk will be executed
63somewhen in the future (@dfn{asynchronously}). Setting the mark more
64than once is satisfied by one execution of the thunk.
65
66Guile supports two types of asyncs: Normal asyncs and system asyncs.
67They differ in that marked system asyncs are executed implicitly as soon
68as possible, whereas normal asyncs have to be invoked explicitly.
69System asyncs are held in an internal data structure and are maintained
70by Guile.
71
72Normal asyncs are created with @code{async}, system asyncs with
73@code{system-async}. They are marked with @code{async-mark} or
74@code{system-async-mark}, respectively.
75
8f85c0c6
NJ
76@deffn {Scheme Procedure} async thunk
77@deffnx {C Function} scm_async (thunk)
a0e07ba4
NJ
78Create a new async for the procedure @var{thunk}.
79@end deffn
80
8f85c0c6
NJ
81@deffn {Scheme Procedure} system-async thunk
82@deffnx {C Function} scm_system_async (thunk)
a0e07ba4
NJ
83Create a new async for the procedure @var{thunk}. Also
84add it to the system's list of active async objects.
85@end deffn
86
8f85c0c6
NJ
87@deffn {Scheme Procedure} async-mark a
88@deffnx {C Function} scm_async_mark (a)
a0e07ba4
NJ
89Mark the async @var{a} for future execution.
90@end deffn
91
8f85c0c6
NJ
92@deffn {Scheme Procedure} system-async-mark a
93@deffnx {C Function} scm_system_async_mark (a)
a0e07ba4
NJ
94Mark the async @var{a} for future execution.
95@end deffn
96
97As already mentioned above, system asyncs are executed automatically.
98Normal asyncs have to be explicitly invoked by storing one or more of
99them into a list and passing them to @code{run-asyncs}.
100
8f85c0c6
NJ
101@deffn {Scheme Procedure} run-asyncs list_of_a
102@deffnx {C Function} scm_run_asyncs (list_of_a)
a0e07ba4
NJ
103Execute all thunks from the asyncs of the list @var{list_of_a}.
104@end deffn
105
106Automatic invocation of system asyncs can be temporarily disabled by
107calling @code{mask-signals} and @code{unmask-signals}. Setting the mark
108while async execution is disabled will nevertheless cause the async to
109run once execution is enabled again. Please note that calls to these
110procedures should always be paired, and they must not be nested, e.g. no
111@code{mask-signals} is allowed if another one is still active.
112
8f85c0c6
NJ
113@deffn {Scheme Procedure} mask-signals
114@deffnx {C Function} scm_mask_signals ()
a0e07ba4
NJ
115Mask signals. The returned value is not specified.
116@end deffn
117
8f85c0c6
NJ
118@deffn {Scheme Procedure} unmask-signals
119@deffnx {C Function} scm_unmask_signals ()
a0e07ba4
NJ
120Unmask signals. The returned value is not specified.
121@end deffn
122
123@c FIXME::martin: Find an example for usage of `noop'. What is that
124@c procedure for anyway?
125
8f85c0c6
NJ
126@deffn {Scheme Procedure} noop . args
127@deffnx {C Function} scm_noop (args)
a0e07ba4
NJ
128Do nothing. When called without arguments, return @code{#f},
129otherwise return the first argument.
130@end deffn
131
132
133@node Dynamic Roots
134@section Dynamic Roots
135@cindex dynamic roots
136
137A @dfn{dynamic root} is a root frame of Scheme evaluation.
138The top-level repl, for example, is an instance of a dynamic root.
139
140Each dynamic root has its own chain of dynamic-wind information. Each
141has its own set of continuations, jump-buffers, and pending CATCH
142statements which are inaccessible from the dynamic scope of any
143other dynamic root.
144
145In a thread-based system, each thread has its own dynamic root. Therefore,
146continuations created by one thread may not be invoked by another.
147
148Even in a single-threaded system, it is sometimes useful to create a new
149dynamic root. For example, if you want to apply a procedure, but to
150not allow that procedure to capture the current continuation, calling
151the procedure under a new dynamic root will do the job.
152
8f85c0c6
NJ
153@deffn {Scheme Procedure} call-with-dynamic-root thunk handler
154@deffnx {C Function} scm_call_with_dynamic_root (thunk, handler)
a0e07ba4
NJ
155Evaluate @code{(thunk)} in a new dynamic context, returning its value.
156
157If an error occurs during evaluation, apply @var{handler} to the
158arguments to the throw, just as @code{throw} would. If this happens,
159@var{handler} is called outside the scope of the new root -- it is
160called in the same dynamic context in which
161@code{call-with-dynamic-root} was evaluated.
162
163If @var{thunk} captures a continuation, the continuation is rooted at
164the call to @var{thunk}. In particular, the call to
165@code{call-with-dynamic-root} is not captured. Therefore,
166@code{call-with-dynamic-root} always returns at most one time.
167
168Before calling @var{thunk}, the dynamic-wind chain is un-wound back to
169the root and a new chain started for @var{thunk}. Therefore, this call
170may not do what you expect:
171
172@lisp
173;; Almost certainly a bug:
174(with-output-to-port
175 some-port
176
177 (lambda ()
178 (call-with-dynamic-root
179 (lambda ()
180 (display 'fnord)
181 (newline))
182 (lambda (errcode) errcode))))
183@end lisp
184
185The problem is, on what port will @samp{fnord} be displayed? You
186might expect that because of the @code{with-output-to-port} that
187it will be displayed on the port bound to @code{some-port}. But it
188probably won't -- before evaluating the thunk, dynamic winds are
189unwound, including those created by @code{with-output-to-port}.
190So, the standard output port will have been re-set to its default value
191before @code{display} is evaluated.
192
193(This function was added to Guile mostly to help calls to functions in C
194libraries that can not tolerate non-local exits or calls that return
195multiple times. If such functions call back to the interpreter, it should
196be under a new dynamic root.)
197@end deffn
198
199
8f85c0c6
NJ
200@deffn {Scheme Procedure} dynamic-root
201@deffnx {C Function} scm_dynamic_root ()
a0e07ba4
NJ
202Return an object representing the current dynamic root.
203
204These objects are only useful for comparison using @code{eq?}.
205They are currently represented as numbers, but your code should
206in no way depend on this.
207@end deffn
208
209@c begin (scm-doc-string "boot-9.scm" "quit")
8f85c0c6 210@deffn {Scheme Procedure} quit [exit_val]
a0e07ba4
NJ
211Throw back to the error handler of the current dynamic root.
212
213If integer @var{exit_val} is specified and if Guile is being used
214stand-alone and if quit is called from the initial dynamic-root,
215@var{exit_val} becomes the exit status of the Guile process and the
216process exits.
217@end deffn
218
219When Guile is run interactively, errors are caught from within the
220read-eval-print loop. An error message will be printed and @code{abort}
221called. A default set of signal handlers is installed, e.g., to allow
222user interrupt of the interpreter.
223
224It is possible to switch to a "batch mode", in which the interpreter
225will terminate after an error and in which all signals cause their
226default actions. Switching to batch mode causes any handlers installed
227from Scheme code to be removed. An example of where this is useful is
228after forking a new process intended to run non-interactively.
229
230@c begin (scm-doc-string "boot-9.scm" "batch-mode?")
8f85c0c6 231@deffn {Scheme Procedure} batch-mode?
a0e07ba4
NJ
232Returns a boolean indicating whether the interpreter is in batch mode.
233@end deffn
234
235@c begin (scm-doc-string "boot-9.scm" "set-batch-mode?!")
8f85c0c6 236@deffn {Scheme Procedure} set-batch-mode?! arg
a0e07ba4
NJ
237If @var{arg} is true, switches the interpreter to batch mode.
238The @code{#f} case has not been implemented.
239@end deffn
240
241@node Threads
242@section Threads
243@cindex threads
244@cindex Guile threads
245
246@strong{[NOTE: this chapter was written for Cygnus Guile and has not yet
247been updated for the Guile 1.x release.]}
248
249Here is a the reference for Guile's threads. In this chapter I simply
250quote verbatim Tom Lord's description of the low-level primitives
251written in C (basically an interface to the POSIX threads library) and
252Anthony Green's description of the higher-level thread procedures
253written in scheme.
254@cindex posix threads
255@cindex Lord, Tom
256@cindex Green, Anthony
257
258When using Guile threads, keep in mind that each guile thread is
259executed in a new dynamic root.
260
261@menu
262* Low level thread primitives::
263* Higher level thread procedures::
264@end menu
265
266
267@node Low level thread primitives
268@subsection Low level thread primitives
269
270@c NJFIXME no current mechanism for making sure that these docstrings
271@c are in sync.
272
273@c begin (texi-doc-string "guile" "call-with-new-thread")
8f85c0c6 274@deffn {Scheme Procedure} call-with-new-thread thunk error-handler
a0e07ba4
NJ
275Evaluate @code{(thunk)} in a new thread, and new dynamic context,
276returning a new thread object representing the thread.
277
278If an error occurs during evaluation, call error-handler, passing it an
279error code describing the condition. [Error codes are currently
280meaningless integers. In the future, real values will be specified.]
281If this happens, the error-handler is called outside the scope of the new
282root -- it is called in the same dynamic context in which
283with-new-thread was evaluated, but not in the caller's thread.
284
285All the evaluation rules for dynamic roots apply to threads.
286@end deffn
287
288@c begin (texi-doc-string "guile" "join-thread")
8f85c0c6 289@deffn {Scheme Procedure} join-thread thread
a0e07ba4
NJ
290Suspend execution of the calling thread until the target @var{thread}
291terminates, unless the target @var{thread} has already terminated.
292@end deffn
293
294@c begin (texi-doc-string "guile" "yield")
8f85c0c6 295@deffn {Scheme Procedure} yield
a0e07ba4
NJ
296If one or more threads are waiting to execute, calling yield forces an
297immediate context switch to one of them. Otherwise, yield has no effect.
298@end deffn
299
300@c begin (texi-doc-string "guile" "make-mutex")
8f85c0c6 301@deffn {Scheme Procedure} make-mutex
a0e07ba4
NJ
302Create a new mutex object.
303@end deffn
304
305@c begin (texi-doc-string "guile" "lock-mutex")
8f85c0c6 306@deffn {Scheme Procedure} lock-mutex mutex
a0e07ba4
NJ
307Lock @var{mutex}. If the mutex is already locked, the calling thread
308blocks until the mutex becomes available. The function returns when
309the calling thread owns the lock on @var{mutex}.
310@end deffn
311
312@c begin (texi-doc-string "guile" "unlock-mutex")
8f85c0c6 313@deffn {Scheme Procedure} unlock-mutex mutex
a0e07ba4
NJ
314Unlocks @var{mutex} if the calling thread owns the lock on @var{mutex}.
315Calling unlock-mutex on a mutex not owned by the current thread results
316in undefined behaviour. Once a mutex has been unlocked, one thread
317blocked on @var{mutex} is awakened and grabs the mutex lock.
318@end deffn
319
320@c begin (texi-doc-string "guile" "make-condition-variable")
8f85c0c6 321@deffn {Scheme Procedure} make-condition-variable
a0e07ba4
NJ
322@end deffn
323
324@c begin (texi-doc-string "guile" "wait-condition-variable")
8f85c0c6 325@deffn {Scheme Procedure} wait-condition-variable cond-var mutex
a0e07ba4
NJ
326@end deffn
327
328@c begin (texi-doc-string "guile" "signal-condition-variable")
8f85c0c6 329@deffn {Scheme Procedure} signal-condition-variable cond-var
a0e07ba4
NJ
330@end deffn
331
332
333@node Higher level thread procedures
334@subsection Higher level thread procedures
335
336@c new by ttn, needs review
337
338Higher level thread procedures are available by loading the
339@code{(ice-9 threads)} module. These provide standardized
340thread creation and mutex interaction.
341
8f85c0c6 342@deffn {Scheme Procedure} %thread-handler tag args@dots{}
a0e07ba4
NJ
343
344This procedure is specified as the standard error-handler for
345@code{make-thread} and @code{begin-thread}. If the number of @var{args}
346is three or more, use @code{display-error}, otherwise display a message
347"uncaught throw to @var{tag}". All output is sent to the port specified
348by @code{current-error-port}.
349
350Before display, global var @code{the-last-stack} is set to @code{#f}
351and signals are unmasked with @code{unmask-signals}.
352
353[FIXME: Why distinguish based on number of args?! Cue voodoo music here.]
354@end deffn
355
356@deffn macro make-thread proc [args@dots{}]
357Apply @var{proc} to @var{args} in a new thread formed by
358@code{call-with-new-thread} using @code{%thread-handler} as the error
359handler.
360@end deffn
361
362@deffn macro begin-thread first [rest@dots{}]
363Evaluate forms @var{first} and @var{rest} in a new thread formed by
364@code{call-with-new-thread} using @code{%thread-handler} as the error
365handler.
366@end deffn
367
368@deffn macro with-mutex m [body@dots{}]
369Lock mutex @var{m}, evaluate @var{body}, and then unlock @var{m}.
370These sub-operations form the branches of a @code{dynamic-wind}.
371@end deffn
372
373@deffn macro monitor first [rest@dots{}]
374Evaluate forms @var{first} and @var{rest} under a newly created
375anonymous mutex, using @code{with-mutex}.
376
377[FIXME: Is there any way to access the mutex?]
378@end deffn
379
380
381@node Fluids
382@section Fluids
383
384@cindex fluids
385
386@c FIXME::martin: Review me!
387
388Fluids are objects to store values in. They have a few properties which
389make them useful in certain situations: Fluids can have one value per
390dynamic root (@pxref{Dynamic Roots}), so that changes to the value in a
391fluid are only visible in the same dynamic root. Since threads are
392executed in separate dynamic roots, fluids can be used for thread local
393storage (@pxref{Threads}).
394
395Fluids can be used to simulate dynamically scoped variables. These are
396used in several (especially in older) dialects of lisp, such as in Emacs
397Lisp, and they work a bit like global variables in that they can be
398modified by the caller of a procedure, and the called procedure will see
399the changes. With lexically scoped variables---which are normally used
400in Scheme---this cannot happen. See the description of
401@code{with-fluids*} below for details.
402
403New fluids are created with @code{make-fluid} and @code{fluid?} is used
404for testing whether an object is actually a fluid.
405
8f85c0c6
NJ
406@deffn {Scheme Procedure} make-fluid
407@deffnx {C Function} scm_make_fluid ()
a0e07ba4
NJ
408Return a newly created fluid.
409Fluids are objects of a certain type (a smob) that can hold one SCM
410value per dynamic root. That is, modifications to this value are
411only visible to code that executes within the same dynamic root as
412the modifying code. When a new dynamic root is constructed, it
413inherits the values from its parent. Because each thread executes
414in its own dynamic root, you can use fluids for thread local storage.
415@end deffn
416
8f85c0c6
NJ
417@deffn {Scheme Procedure} fluid? obj
418@deffnx {C Function} scm_fluid_p (obj)
a0e07ba4
NJ
419Return @code{#t} iff @var{obj} is a fluid; otherwise, return
420@code{#f}.
421@end deffn
422
423The values stored in a fluid can be accessed with @code{fluid-ref} and
424@code{fluid-set!}.
425
8f85c0c6
NJ
426@deffn {Scheme Procedure} fluid-ref fluid
427@deffnx {C Function} scm_fluid_ref (fluid)
a0e07ba4
NJ
428Return the value associated with @var{fluid} in the current
429dynamic root. If @var{fluid} has not been set, then return
430@code{#f}.
431@end deffn
432
8f85c0c6
NJ
433@deffn {Scheme Procedure} fluid-set! fluid value
434@deffnx {C Function} scm_fluid_set_x (fluid, value)
a0e07ba4
NJ
435Set the value associated with @var{fluid} in the current dynamic root.
436@end deffn
437
438@code{with-fluids*} temporarily changes the values of one or more fluids,
439so that the given procedure and each procedure called by it access the
440given values. After the procedure returns, the old values are restored.
441
8f85c0c6
NJ
442@deffn {Scheme Procedure} with-fluids* fluids values thunk
443@deffnx {C Function} scm_with_fluids (fluids, values, thunk)
a0e07ba4
NJ
444Set @var{fluids} to @var{values} temporary, and call @var{thunk}.
445@var{fluids} must be a list of fluids and @var{values} must be the same
446number of their values to be applied. Each substitution is done
447one after another. @var{thunk} must be a procedure with no argument.
448@end deffn
449
450
451@c Local Variables:
452@c TeX-master: "guile.texi"
453@c End: