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