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