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