* __scm.h (SCM_DEFER_INTS, SCM_ALLOW_INTS): New definitions.
[bpt/guile.git] / libguile / threads.h
1 /* classes: h_files */
2
3 #ifndef SCM_THREADS_H
4 #define SCM_THREADS_H
5
6 /* Copyright (C) 1996,1997,1998,2000,2001, 2002 Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this software; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 * Boston, MA 02111-1307 USA
22 *
23 * As a special exception, the Free Software Foundation gives permission
24 * for additional uses of the text contained in its release of GUILE.
25 *
26 * The exception is that, if you link the GUILE library with other files
27 * to produce an executable, this does not by itself cause the
28 * resulting executable to be covered by the GNU General Public License.
29 * Your use of that executable is in no way restricted on account of
30 * linking the GUILE library code into it.
31 *
32 * This exception does not however invalidate any other reasons why
33 * the executable file might be covered by the GNU General Public License.
34 *
35 * This exception applies only to the code released by the
36 * Free Software Foundation under the name GUILE. If you copy
37 * code from other Free Software Foundation releases into a copy of
38 * GUILE, as the General Public License permits, the exception does
39 * not apply to the code that you add in this way. To avoid misleading
40 * anyone as to the status of such modified files, you must delete
41 * this exception notice from them.
42 *
43 * If you write modifications of your own for GUILE, it is your choice
44 * whether to permit this exception to apply to your modifications.
45 * If you do not wish that, delete this exception notice. */
46
47 \f
48
49 #include "libguile/__scm.h"
50 #include "libguile/procs.h"
51 #include "libguile/throw.h"
52 #include "libguile/root.h"
53 #include "libguile/iselect.h"
54 \f
55
56 /* smob tags for the thread datatypes */
57 SCM_API scm_t_bits scm_tc16_thread;
58 SCM_API scm_t_bits scm_tc16_mutex;
59 SCM_API scm_t_bits scm_tc16_fair_mutex;
60 SCM_API scm_t_bits scm_tc16_condvar;
61 SCM_API scm_t_bits scm_tc16_fair_condvar;
62
63 #define SCM_THREADP(x) SCM_TYP16_PREDICATE (scm_tc16_thread, x)
64 #define SCM_THREAD_DATA(x) ((scm_thread *) SCM_CELL_WORD_1 (x))
65
66 #define SCM_MUTEXP(x) SCM_TYP16_PREDICATE (scm_tc16_mutex, x)
67 #define SCM_FAIR_MUTEX_P(x) SCM_TYP16_PREDICATE (scm_tc16_fair_mutex, x)
68 #define SCM_MUTEX_DATA(x) ((void *) SCM_CELL_WORD_1 (x))
69
70 #define SCM_CONDVARP(x) SCM_TYP16_PREDICATE (scm_tc16_condvar, x)
71 #define SCM_FAIR_CONDVAR_P(x) SCM_TYP16_PREDICATE (scm_tc16_fair_condvar, x)
72 #define SCM_CONDVAR_DATA(x) ((void *) SCM_CELL_WORD_1 (x))
73
74 #define SCM_VALIDATE_THREAD(pos, a) \
75 SCM_MAKE_VALIDATE_MSG (pos, a, THREADP, "thread")
76
77 #define SCM_VALIDATE_MUTEX(pos, a) \
78 SCM_ASSERT_TYPE (SCM_MUTEXP (a) || SCM_FAIR_MUTEX_P (a), \
79 a, pos, FUNC_NAME, "mutex");
80
81 #define SCM_VALIDATE_CONDVAR(pos, a) \
82 SCM_ASSERT_TYPE (SCM_CONDVARP (a) || SCM_FAIR_CONDVAR_P (a), \
83 a, pos, FUNC_NAME, "condition variable");
84
85 #define SCM_VALIDATE_FUTURE(pos, obj) \
86 SCM_ASSERT_TYPE (SCM_TYP16_PREDICATE (scm_tc16_future, obj), \
87 obj, pos, FUNC_NAME, "future");
88 #define SCM_F_FUTURE_COMPUTED (1L << 16)
89 #define SCM_FUTURE_COMPUTED_P(future) \
90 (SCM_F_FUTURE_COMPUTED & SCM_CELL_WORD_0 (future))
91 #define SCM_SET_FUTURE_COMPUTED(future) \
92 SCM_SET_CELL_WORD_0 (future, scm_tc16_future | SCM_F_FUTURE_COMPUTED)
93 #define SCM_FUTURE_MUTEX(future) \
94 ((scm_t_rec_mutex *) SCM_CELL_WORD_2 (future))
95 #define SCM_FUTURE_DATA SCM_CELL_OBJECT_1
96 #define SCM_SET_FUTURE_DATA SCM_SET_CELL_OBJECT_1
97 SCM_API scm_t_bits scm_tc16_future;
98
99 SCM_API void scm_threads_mark_stacks (void);
100 SCM_API void scm_init_threads (SCM_STACKITEM *);
101 SCM_API void scm_init_thread_procs (void);
102
103 /*----------------------------------------------------------------------*/
104 /* Low-level C API */
105
106 /* The purpose of this API is seamless, simple and thread package
107 independent interaction with Guile threads from the application.
108
109 Note that Guile also uses it to implement itself, just like
110 with the rest of the application API.
111 */
112
113 /* MDJ 021209 <djurfeldt@nada.kth.se>:
114 The separation of the plugin interface (currently in
115 pthread-threads.h and null-threads.h) and the low-level C API needs
116 to be completed in a sensible way.
117 */
118
119 /* Deprecate this name and rename to scm_thread_create?
120 Introduce the other two arguments in pthread_create to prepare for
121 the future?
122 */
123 SCM_API SCM scm_spawn_thread (scm_t_catch_body body, void *body_data,
124 scm_t_catch_handler handler, void *handler_data);
125
126 #define scm_thread_join scm_i_plugin_thread_join
127 #define scm_thread_detach scm_i_plugin_thread_detach
128 #define scm_thread_self scm_i_plugin_thread_self
129
130 #define scm_mutex_init scm_i_plugin_mutex_init
131 #define scm_mutex_destroy scm_i_plugin_mutex_destroy
132 SCM_API int scm_mutex_lock (scm_t_mutex *m);
133 #define scm_mutex_trylock scm_i_plugin_mutex_trylock
134 #define scm_mutex_unlock scm_i_plugin_mutex_unlock
135
136 /* Guile itself needs recursive mutexes. See for example the
137 implentation of scm_force in eval.c.
138
139 Note that scm_rec_mutex_lock et al can be replaced by direct usage
140 of the corresponding pthread functions if we use the pthread
141 debugging API to access the stack top (in which case there is no
142 longer any need to save the top of the stack before blocking).
143
144 It's therefore highly motivated to use these calls in situations
145 where Guile or the application needs recursive mutexes.
146 */
147 #define scm_rec_mutex_init scm_i_plugin_rec_mutex_init
148 #define scm_rec_mutex_destroy scm_i_plugin_rec_mutex_destroy
149 /* It's a safer bet to use the following functions.
150 The future of the _init functions is uncertain.
151 */
152 SCM_API scm_t_rec_mutex *scm_make_rec_mutex (void);
153 SCM_API void scm_rec_mutex_free (scm_t_rec_mutex *);
154 SCM_API int scm_rec_mutex_lock (scm_t_rec_mutex *m);
155 #define scm_rec_mutex_trylock scm_i_plugin_rec_mutex_trylock
156 #define scm_rec_mutex_unlock scm_i_plugin_rec_mutex_unlock
157
158 #define scm_cond_init scm_i_plugin_cond_init
159 #define scm_cond_destroy scm_i_plugin_cond_destroy
160 SCM_API int scm_cond_wait (scm_t_cond *c, scm_t_mutex *m);
161 SCM_API int scm_cond_timedwait (scm_t_cond *c,
162 scm_t_mutex *m,
163 const struct timespec *t);
164 #define scm_cond_signal scm_i_plugin_cond_signal
165 #define scm_cond_broadcast scm_i_plugin_cond_broadcast
166
167 #define scm_key_create scm_i_plugin_key_create
168 #define scm_key_delete scm_i_plugin_key_delete
169 #define scm_setspecific scm_i_plugin_setspecific
170 #define scm_getspecific scm_i_plugin_getspecific
171
172 #define scm_thread_select scm_internal_select
173
174 /* The application must scm_leave_guile() before entering any piece of
175 code which can
176 1. block, or
177 2. execute for any longer period of time without calling SCM_TICK
178
179 Note, though, that it is *not* necessary to use these calls
180 together with any call in this API.
181 */
182
183 SCM_API void scm_enter_guile (void);
184 SCM_API void scm_leave_guile (void);
185
186 /* Better versions (although we need the former ones also in order to
187 avoid forcing code restructuring in existing applications): */
188 /*fixme* Not implemented yet! */
189 SCM_API void *scm_in_guile (void (*func) (void*), void *data);
190 SCM_API void *scm_outside_guile (void (*func) (void*), void *data);
191
192 /* These are versions of the ordinary sleep and usleep functions
193 that play nicely with the thread system. */
194 SCM_API unsigned long scm_thread_sleep (unsigned long);
195 SCM_API unsigned long scm_thread_usleep (unsigned long);
196
197 /* End of low-level C API */
198 /*----------------------------------------------------------------------*/
199
200 extern SCM *scm_loc_sys_thread_handler;
201
202 typedef struct scm_thread scm_thread;
203
204 SCM_API void scm_i_enter_guile (scm_thread *t);
205 SCM_API scm_thread *scm_i_leave_guile (void);
206
207 /* Critical sections */
208
209 /* This is the generic critical section for places where we are too
210 lazy to allocate a specific mutex. */
211 extern scm_t_mutex scm_i_critical_section_mutex;
212
213 #define SCM_CRITICAL_SECTION_START \
214 scm_mutex_lock (&scm_i_critical_section_mutex)
215 #define SCM_CRITICAL_SECTION_END \
216 scm_mutex_unlock (&scm_i_critical_section_mutex)
217
218 /* This is the temporary support for the old ALLOW/DEFER ints sections */
219 extern scm_t_rec_mutex scm_i_defer_mutex;
220
221 extern int scm_i_thread_go_to_sleep;
222
223 void scm_i_thread_put_to_sleep (void);
224 void scm_i_thread_wake_up (void);
225 void scm_i_thread_invalidate_freelists (void);
226 void scm_i_thread_sleep_for_gc (void);
227 void scm_threads_prehistory (void);
228 void scm_threads_init_first_thread (void);
229
230 #define SCM_THREAD_SWITCHING_CODE \
231 do { \
232 if (scm_i_thread_go_to_sleep) \
233 scm_i_thread_sleep_for_gc (); \
234 } while (0)
235
236 /* The C versions of the Scheme-visible thread functions. */
237 SCM_API SCM scm_call_with_new_thread (SCM thunk, SCM handler);
238 SCM_API SCM scm_join_thread (SCM t);
239 SCM_API SCM scm_i_make_future (SCM thunk);
240 SCM_API SCM scm_future_ref (SCM future);
241 SCM_API SCM scm_make_mutex (void);
242 SCM_API SCM scm_make_fair_mutex (void);
243 SCM_API SCM scm_lock_mutex (SCM m);
244 SCM_API SCM scm_try_mutex (SCM m);
245 SCM_API SCM scm_unlock_mutex (SCM m);
246 SCM_API SCM scm_make_condition_variable (void);
247 SCM_API SCM scm_make_fair_condition_variable (void);
248 SCM_API SCM scm_wait_condition_variable (SCM cond, SCM mutex);
249 SCM_API SCM scm_timed_wait_condition_variable (SCM cond, SCM mutex,
250 SCM abstime);
251 SCM_API SCM scm_signal_condition_variable (SCM cond);
252 SCM_API SCM scm_broadcast_condition_variable (SCM cond);
253
254 SCM_API SCM scm_current_thread (void);
255 SCM_API SCM scm_all_threads (void);
256
257 SCM_API int scm_c_thread_exited_p (SCM thread);
258 SCM_API SCM scm_thread_exited_p (SCM thread);
259
260 SCM_API scm_root_state *scm_i_thread_root (SCM thread);
261
262 #define SCM_CURRENT_THREAD \
263 ((scm_thread *) scm_i_plugin_getspecific (scm_i_thread_key))
264 extern scm_t_key scm_i_thread_key;
265
266 /* These macros have confusing names.
267 They really refer to the root state of the running thread. */
268 #define SCM_THREAD_LOCAL_DATA (scm_i_plugin_getspecific (scm_i_root_state_key))
269 #define SCM_SET_THREAD_LOCAL_DATA(x) scm_i_set_thread_data(x)
270 extern scm_t_key scm_i_root_state_key;
271 SCM_API void scm_i_set_thread_data (void *);
272
273 #ifndef HAVE_STRUCT_TIMESPEC
274 /* POSIX.4 structure for a time value. This is like a `struct timeval' but
275 has nanoseconds instead of microseconds. */
276 struct timespec
277 {
278 long int tv_sec; /* Seconds. */
279 long int tv_nsec; /* Nanoseconds. */
280 };
281 #endif
282
283 #ifdef USE_PTHREAD_THREADS
284 #include "libguile/pthread-threads.h"
285 #else
286 #include "libguile/null-threads.h"
287 #endif
288
289 #endif /* SCM_THREADS_H */
290
291 /*
292 Local Variables:
293 c-file-style: "gnu"
294 End:
295 */