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