2001-04-09 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
[bpt/guile.git] / doc / scheme-scheduling.texi
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
6 plus the Cygnus programmer's manual; it should be *very* carefully
7 reviewed 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
23 Return an object of type arbiter and name @var{name}. Its
24 state is initially unlocked. Arbiters are a way to achieve
25 process synchronization.
26 @end deffn
27
28 @c docstring begin (texi-doc-string "guile" "try-arbiter")
29 @deffn primitive try-arbiter arb
30 Return @code{#t} and lock the arbiter @var{arb} if the arbiter
31 was 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
36 Return @code{#t} and unlock the arbiter @var{arb} if the
37 arbiter 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
46 Create 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
51 Create a new async for the procedure @var{thunk}. Also
52 add 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
57 Mark 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
62 Mark 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
67 Execute 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
72 Do nothing. When called without arguments, return @code{#f},
73 otherwise return the first argument.
74 @end deffn
75
76 @c docstring begin (texi-doc-string "guile" "unmask-signals")
77 @deffn primitive unmask-signals
78 Unmask 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
83 Mask 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
91 A @dfn{dynamic root} is a root frame of Scheme evaluation.
92 The top-level repl, for example, is an instance of a dynamic root.
93
94 Each dynamic root has its own chain of dynamic-wind information. Each
95 has its own set of continuations, jump-buffers, and pending CATCH
96 statements which are inaccessible from the dynamic scope of any
97 other dynamic root.
98
99 In a thread-based system, each thread has its own dynamic root. Therefore,
100 continuations created by one thread may not be invoked by another.
101
102 Even in a single-threaded system, it is sometimes useful to create a new
103 dynamic root. For example, if you want to apply a procedure, but to
104 not allow that procedure to capture the current continuation, calling
105 the 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
109 Evaluate @code{(thunk)} in a new dynamic context, returning its value.
110
111 If an error occurs during evaluation, apply @var{handler} to the
112 arguments 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
114 called in the same dynamic context in which
115 @code{call-with-dynamic-root} was evaluated.
116
117 If @var{thunk} captures a continuation, the continuation is rooted at
118 the 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
122 Before calling @var{thunk}, the dynamic-wind chain is un-wound back to
123 the root and a new chain started for @var{thunk}. Therefore, this call
124 may not do what you expect:
125
126 @lisp
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))))
137 @end lisp
138
139 The problem is, on what port will @samp{fnord} be displayed? You
140 might expect that because of the @code{with-output-to-port} that
141 it will be displayed on the port bound to @code{some-port}. But it
142 probably won't -- before evaluating the thunk, dynamic winds are
143 unwound, including those created by @code{with-output-to-port}.
144 So, the standard output port will have been re-set to its default value
145 before @code{display} is evaluated.
146
147 (This function was added to Guile mostly to help calls to functions in C
148 libraries that can not tolerate non-local exits or calls that return
149 multiple times. If such functions call back to the interpreter, it should
150 be 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
156 Return an object representing the current dynamic root.
157
158 These objects are only useful for comparison using @code{eq?}.
159 They are currently represented as numbers, but your code should
160 in 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]
165 Throw back to the error handler of the current dynamic root.
166
167 If integer @var{exit_val} is specified and if Guile is being used
168 stand-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
170 process exits.
171 @end deffn
172
173 When Guile is run interactively, errors are caught from within the
174 read-eval-print loop. An error message will be printed and @code{abort}
175 called. A default set of signal handlers is installed, e.g., to allow
176 user interrupt of the interpreter.
177
178 It is possible to switch to a "batch mode", in which the interpreter
179 will terminate after an error and in which all signals cause their
180 default actions. Switching to batch mode causes any handlers installed
181 from Scheme code to be removed. An example of where this is useful is
182 after 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?
186 Returns 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
191 If @var{arg} is true, switches the interpreter to batch mode.
192 The @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
201 been updated for the Guile 1.x release.]}
202
203 Here is a the reference for Guile's threads. In this chapter I simply
204 quote verbatim Tom Lord's description of the low-level primitives
205 written in C (basically an interface to the POSIX threads library) and
206 Anthony Green's description of the higher-level thread procedures
207 written in scheme.
208 @cindex posix threads
209 @cindex Lord, Tom
210 @cindex Green, Anthony
211
212 When using Guile threads, keep in mind that each guile thread is
213 executed 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")
228 @deffn primitive call-with-new-thread thunk error-handler
229 Evaluate @code{(thunk)} in a new thread, and new dynamic context,
230 returning a new thread object representing the thread.
231
232 If an error occurs during evaluation, call error-handler, passing it an
233 error code describing the condition. [Error codes are currently
234 meaningless integers. In the future, real values will be specified.]
235 If this happens, the error-handler is called outside the scope of the new
236 root -- it is called in the same dynamic context in which
237 with-new-thread was evaluated, but not in the caller's thread.
238
239 All 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
244 Suspend execution of the calling thread until the target @var{thread}
245 terminates, unless the target @var{thread} has already terminated.
246 @end deffn
247
248 @c begin (texi-doc-string "guile" "yield")
249 @deffn primitive yield
250 If one or more threads are waiting to execute, calling yield forces an
251 immediate 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
256 Create a new mutex object.
257 @end deffn
258
259 @c begin (texi-doc-string "guile" "lock-mutex")
260 @deffn primitive lock-mutex mutex
261 Lock @var{mutex}. If the mutex is already locked, the calling thread
262 blocks until the mutex becomes available. The function returns when
263 the 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
268 Unlocks @var{mutex} if the calling thread owns the lock on @var{mutex}.
269 Calling unlock-mutex on a mutex not owned by the current thread results
270 in undefined behaviour. Once a mutex has been unlocked, one thread
271 blocked 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
290 @c new by ttn, needs review
291
292 Higher level thread procedures are available by loading the
293 @code{(ice-9 threads)} module. These provide standardized
294 thread creation and mutex interaction.
295
296 @c docstring begin (texi-doc-string "guile" "%thread-handler")
297 @deffn primitive %thread-handler tag args@dots{}
298
299 This procedure is specified as the standard error-handler for
300 @code{make-thread} and @code{begin-thread}. If the number of @var{args}
301 is 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
303 by @code{current-error-port}.
304
305 Before display, global var @code{the-last-stack} is set to @code{#f}
306 and signals are unmasked with @code{unmask-signals}.
307
308 [FIXME: Why distinguish based on number of args?! Cue voodoo music here.]
309 @end deffn
310
311 @c docstring begin (texi-doc-string "guile" "make-thread")
312 @deffn macro make-thread proc [args@dots{}]
313 Apply @var{proc} to @var{args} in a new thread formed by
314 @code{call-with-new-thread} using @code{%thread-handler} as the error
315 handler.
316 @end deffn
317
318 @c docstring begin (texi-doc-string "guile" "begin-thread")
319 @deffn macro begin-thread first [rest@dots{}]
320 Evaluate forms @var{first} and @var{rest} in a new thread formed by
321 @code{call-with-new-thread} using @code{%thread-handler} as the error
322 handler.
323 @end deffn
324
325 @c docstring begin (texi-doc-string "guile" "with-mutex")
326 @deffn macro with-mutex m [body@dots{}]
327 Lock mutex @var{m}, evaluate @var{body}, and then unlock @var{m}.
328 These sub-operations form the branches of a @code{dynamic-wind}.
329 @end deffn
330
331 @c docstring begin (texi-doc-string "guile" "monitor")
332 @deffn macro monitor first [rest@dots{}]
333 Evaluate forms @var{first} and @var{rest} under a newly created
334 anonymous mutex, using @code{with-mutex}.
335
336 [FIXME: Is there any way to access the mutex?]
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
345 Return a newly created fluid.
346 Fluids are objects of a certain type (a smob) that can hold one SCM
347 value per dynamic root. That is, modifications to this value are
348 only visible to code that executes within the same dynamic root as
349 the modifying code. When a new dynamic root is constructed, it
350 inherits the values from its parent. Because each thread executes
351 in 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
356 Return @code{#t} iff @var{obj} is a fluid; otherwise, return
357 @code{#f}.
358 @end deffn
359
360 @c docstring begin (texi-doc-string "guile" "fluid-ref")
361 @deffn primitive fluid-ref fluid
362 Return the value associated with @var{fluid} in the current
363 dynamic root. If @var{fluid} has not been set, then return
364 @code{#f}.
365 @end deffn
366
367 @c docstring begin (texi-doc-string "guile" "fluid-set!")
368 @deffn primitive fluid-set! fluid value
369 Set 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
374 Set @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
376 number of their values to be applied. Each substitution is done
377 one 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: