*** empty log message ***
[bpt/guile.git] / libguile / threads.h
CommitLineData
7bfd3b9e
JB
1/* classes: h_files */
2
0527e687
DH
3#ifndef SCM_THREADS_H
4#define SCM_THREADS_H
7bfd3b9e 5
756414cf 6/* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003 Free Software Foundation, Inc.
0527e687 7 *
73be1d9e
MV
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
0527e687 12 *
73be1d9e 13 * This library is distributed in the hope that it will be useful,
7bfd3b9e 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
0527e687 17 *
73be1d9e
MV
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
d3a6bc94 22
7bfd3b9e
JB
23\f
24
25#include "libguile/__scm.h"
26#include "libguile/procs.h"
1651c824 27#include "libguile/throw.h"
f7eca35d 28#include "libguile/root.h"
d823b11b 29#include "libguile/iselect.h"
29717c89 30#include "libguile/threads-plugin.h"
b2728432
DH
31\f
32
7bfd3b9e 33/* smob tags for the thread datatypes */
33b001fd
MV
34SCM_API scm_t_bits scm_tc16_thread;
35SCM_API scm_t_bits scm_tc16_mutex;
9bc4701c 36SCM_API scm_t_bits scm_tc16_fair_mutex;
33b001fd 37SCM_API scm_t_bits scm_tc16_condvar;
9bc4701c 38SCM_API scm_t_bits scm_tc16_fair_condvar;
7bfd3b9e 39
f5710d53
MV
40#define SCM_THREADP(x) SCM_SMOB_PREDICATE (scm_tc16_thread, x)
41#define SCM_THREAD_DATA(x) ((scm_thread *) SCM_SMOB_DATA (x))
7bfd3b9e 42
f5710d53
MV
43#define SCM_MUTEXP(x) SCM_SMOB_PREDICATE (scm_tc16_mutex, x)
44#define SCM_FAIR_MUTEX_P(x) SCM_SMOB_PREDICATE (scm_tc16_fair_mutex, x)
45#define SCM_MUTEX_DATA(x) ((void *) SCM_SMOB_DATA (x))
7bfd3b9e 46
f5710d53
MV
47#define SCM_CONDVARP(x) SCM_SMOB_PREDICATE (scm_tc16_condvar, x)
48#define SCM_FAIR_CONDVAR_P(x) SCM_SMOB_PREDICATE (scm_tc16_fair_condvar, x)
49#define SCM_CONDVAR_DATA(x) ((void *) SCM_SMOB_DATA (x))
7bfd3b9e 50
d823b11b
MV
51#define SCM_VALIDATE_THREAD(pos, a) \
52 SCM_MAKE_VALIDATE_MSG (pos, a, THREADP, "thread")
53
54#define SCM_VALIDATE_MUTEX(pos, a) \
9bc4701c
MD
55 SCM_ASSERT_TYPE (SCM_MUTEXP (a) || SCM_FAIR_MUTEX_P (a), \
56 a, pos, FUNC_NAME, "mutex");
d823b11b
MV
57
58#define SCM_VALIDATE_CONDVAR(pos, a) \
9bc4701c
MD
59 SCM_ASSERT_TYPE (SCM_CONDVARP (a) || SCM_FAIR_CONDVAR_P (a), \
60 a, pos, FUNC_NAME, "condition variable");
d823b11b 61
33b001fd
MV
62SCM_API void scm_threads_mark_stacks (void);
63SCM_API void scm_init_threads (SCM_STACKITEM *);
5f05c406 64SCM_API void scm_init_thread_procs (void);
7bfd3b9e 65
fcc5d734
SJ
66#if SCM_USE_PTHREAD_THREADS
67# include "libguile/pthread-threads.h"
68#else
69# include "libguile/null-threads.h"
70#endif
71
9bc4701c
MD
72/*----------------------------------------------------------------------*/
73/* Low-level C API */
74
75/* The purpose of this API is seamless, simple and thread package
76 independent interaction with Guile threads from the application.
28d52ebb
MD
77
78 Note that Guile also uses it to implement itself, just like
79 with the rest of the application API.
9bc4701c
MD
80 */
81
82/* MDJ 021209 <djurfeldt@nada.kth.se>:
83 The separation of the plugin interface (currently in
84 pthread-threads.h and null-threads.h) and the low-level C API needs
85 to be completed in a sensible way.
86 */
87
88/* Deprecate this name and rename to scm_thread_create?
89 Introduce the other two arguments in pthread_create to prepare for
90 the future?
91 */
33b001fd
MV
92SCM_API SCM scm_spawn_thread (scm_t_catch_body body, void *body_data,
93 scm_t_catch_handler handler, void *handler_data);
92e64b87 94SCM_API scm_t_thread scm_c_scm2thread (SCM thread);
df366c26 95
9bc4701c
MD
96#define scm_thread_join scm_i_plugin_thread_join
97#define scm_thread_detach scm_i_plugin_thread_detach
98#define scm_thread_self scm_i_plugin_thread_self
29717c89 99#define scm_thread_yield scm_i_plugin_thread_yield
9bc4701c
MD
100
101#define scm_mutex_init scm_i_plugin_mutex_init
102#define scm_mutex_destroy scm_i_plugin_mutex_destroy
103SCM_API int scm_mutex_lock (scm_t_mutex *m);
104#define scm_mutex_trylock scm_i_plugin_mutex_trylock
105#define scm_mutex_unlock scm_i_plugin_mutex_unlock
106
28d52ebb
MD
107/* Guile itself needs recursive mutexes. See for example the
108 implentation of scm_force in eval.c.
109
110 Note that scm_rec_mutex_lock et al can be replaced by direct usage
111 of the corresponding pthread functions if we use the pthread
112 debugging API to access the stack top (in which case there is no
113 longer any need to save the top of the stack before blocking).
114
115 It's therefore highly motivated to use these calls in situations
116 where Guile or the application needs recursive mutexes.
117 */
118#define scm_rec_mutex_init scm_i_plugin_rec_mutex_init
119#define scm_rec_mutex_destroy scm_i_plugin_rec_mutex_destroy
120/* It's a safer bet to use the following functions.
121 The future of the _init functions is uncertain.
122 */
123SCM_API scm_t_rec_mutex *scm_make_rec_mutex (void);
124SCM_API void scm_rec_mutex_free (scm_t_rec_mutex *);
125SCM_API int scm_rec_mutex_lock (scm_t_rec_mutex *m);
126#define scm_rec_mutex_trylock scm_i_plugin_rec_mutex_trylock
127#define scm_rec_mutex_unlock scm_i_plugin_rec_mutex_unlock
128
9bc4701c
MD
129#define scm_cond_init scm_i_plugin_cond_init
130#define scm_cond_destroy scm_i_plugin_cond_destroy
131SCM_API int scm_cond_wait (scm_t_cond *c, scm_t_mutex *m);
132SCM_API int scm_cond_timedwait (scm_t_cond *c,
133 scm_t_mutex *m,
d3d605bb 134 const scm_t_timespec *t);
9bc4701c
MD
135#define scm_cond_signal scm_i_plugin_cond_signal
136#define scm_cond_broadcast scm_i_plugin_cond_broadcast
137
138#define scm_key_create scm_i_plugin_key_create
139#define scm_key_delete scm_i_plugin_key_delete
fcc5d734
SJ
140SCM_API int scm_setspecific (scm_t_key k, void *s);
141SCM_API void *scm_getspecific (scm_t_key k);
9bc4701c
MD
142
143#define scm_thread_select scm_internal_select
144
145/* The application must scm_leave_guile() before entering any piece of
146 code which can
147 1. block, or
148 2. execute for any longer period of time without calling SCM_TICK
149
150 Note, though, that it is *not* necessary to use these calls
151 together with any call in this API.
152 */
153
154SCM_API void scm_enter_guile (void);
155SCM_API void scm_leave_guile (void);
156
157/* Better versions (although we need the former ones also in order to
158 avoid forcing code restructuring in existing applications): */
159/*fixme* Not implemented yet! */
160SCM_API void *scm_in_guile (void (*func) (void*), void *data);
161SCM_API void *scm_outside_guile (void (*func) (void*), void *data);
162
d823b11b 163/* These are versions of the ordinary sleep and usleep functions
b74f4728 164 that play nicely with the thread system. */
33b001fd
MV
165SCM_API unsigned long scm_thread_sleep (unsigned long);
166SCM_API unsigned long scm_thread_usleep (unsigned long);
b74f4728 167
9bc4701c
MD
168/* End of low-level C API */
169/*----------------------------------------------------------------------*/
170
171typedef struct scm_thread scm_thread;
172
173SCM_API void scm_i_enter_guile (scm_thread *t);
174SCM_API scm_thread *scm_i_leave_guile (void);
175
d823b11b
MV
176/* Critical sections */
177
9bc4701c
MD
178/* This is the generic critical section for places where we are too
179 lazy to allocate a specific mutex. */
28d52ebb
MD
180extern scm_t_mutex scm_i_critical_section_mutex;
181
9bc4701c 182#define SCM_CRITICAL_SECTION_START \
28d52ebb 183 scm_mutex_lock (&scm_i_critical_section_mutex)
9bc4701c 184#define SCM_CRITICAL_SECTION_END \
28d52ebb 185 scm_mutex_unlock (&scm_i_critical_section_mutex)
d823b11b 186
9bc4701c 187/* This is the temporary support for the old ALLOW/DEFER ints sections */
28d52ebb 188extern scm_t_rec_mutex scm_i_defer_mutex;
d823b11b 189
9bc4701c 190extern int scm_i_thread_go_to_sleep;
d823b11b 191
9bc4701c
MD
192void scm_i_thread_put_to_sleep (void);
193void scm_i_thread_wake_up (void);
b0dc3d71 194void scm_i_thread_invalidate_freelists (void);
9bc4701c
MD
195void scm_i_thread_sleep_for_gc (void);
196void scm_threads_prehistory (void);
197void scm_threads_init_first_thread (void);
d823b11b
MV
198
199#define SCM_THREAD_SWITCHING_CODE \
200do { \
9bc4701c
MD
201 if (scm_i_thread_go_to_sleep) \
202 scm_i_thread_sleep_for_gc (); \
d823b11b 203} while (0)
b74f4728 204
756414cf
MD
205SCM scm_i_create_thread (scm_t_catch_body body, void *body_data,
206 scm_t_catch_handler handler, void *handler_data,
207 SCM protects);
208
6d71500e 209/* The C versions of the Scheme-visible thread functions. */
d823b11b 210SCM_API SCM scm_call_with_new_thread (SCM thunk, SCM handler);
29717c89 211SCM_API SCM scm_yield (void);
33b001fd
MV
212SCM_API SCM scm_join_thread (SCM t);
213SCM_API SCM scm_make_mutex (void);
9bc4701c 214SCM_API SCM scm_make_fair_mutex (void);
33b001fd 215SCM_API SCM scm_lock_mutex (SCM m);
5f05c406 216SCM_API SCM scm_try_mutex (SCM m);
33b001fd
MV
217SCM_API SCM scm_unlock_mutex (SCM m);
218SCM_API SCM scm_make_condition_variable (void);
9bc4701c 219SCM_API SCM scm_make_fair_condition_variable (void);
33b001fd 220SCM_API SCM scm_wait_condition_variable (SCM cond, SCM mutex);
5f05c406
MV
221SCM_API SCM scm_timed_wait_condition_variable (SCM cond, SCM mutex,
222 SCM abstime);
33b001fd 223SCM_API SCM scm_signal_condition_variable (SCM cond);
5f05c406 224SCM_API SCM scm_broadcast_condition_variable (SCM cond);
6d71500e 225
f7eca35d
MV
226SCM_API SCM scm_current_thread (void);
227SCM_API SCM scm_all_threads (void);
228
5f05c406
MV
229SCM_API int scm_c_thread_exited_p (SCM thread);
230SCM_API SCM scm_thread_exited_p (SCM thread);
231
f7eca35d
MV
232SCM_API scm_root_state *scm_i_thread_root (SCM thread);
233
9bc4701c
MD
234#define SCM_CURRENT_THREAD \
235 ((scm_thread *) scm_i_plugin_getspecific (scm_i_thread_key))
236extern scm_t_key scm_i_thread_key;
237
238/* These macros have confusing names.
239 They really refer to the root state of the running thread. */
fcc5d734 240#define SCM_THREAD_LOCAL_DATA (scm_getspecific (scm_i_root_state_key))
d823b11b 241#define SCM_SET_THREAD_LOCAL_DATA(x) scm_i_set_thread_data(x)
2e945bcc 242SCM_API scm_t_key scm_i_root_state_key;
9bc4701c 243SCM_API void scm_i_set_thread_data (void *);
d823b11b 244
0527e687 245#endif /* SCM_THREADS_H */
89e00824
ML
246
247/*
248 Local Variables:
249 c-file-style: "gnu"
250 End:
251*/