2003-06-14 Stefan Jahn <stefan@lkcc.org>
[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, 2003 Free Software Foundation, Inc.
7 *
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.
12 *
13 * This library 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 GNU
16 * Lesser General Public License for more details.
17 *
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 */
22
23 \f
24
25 #include "libguile/__scm.h"
26 #include "libguile/procs.h"
27 #include "libguile/throw.h"
28 #include "libguile/root.h"
29 #include "libguile/iselect.h"
30 #include "libguile/threads-plugin.h"
31 \f
32
33 /* smob tags for the thread datatypes */
34 SCM_API scm_t_bits scm_tc16_thread;
35 SCM_API scm_t_bits scm_tc16_mutex;
36 SCM_API scm_t_bits scm_tc16_fair_mutex;
37 SCM_API scm_t_bits scm_tc16_condvar;
38 SCM_API scm_t_bits scm_tc16_fair_condvar;
39
40 #define SCM_THREADP(x) SCM_TYP16_PREDICATE (scm_tc16_thread, x)
41 #define SCM_THREAD_DATA(x) ((scm_thread *) SCM_CELL_WORD_1 (x))
42
43 #define SCM_MUTEXP(x) SCM_TYP16_PREDICATE (scm_tc16_mutex, x)
44 #define SCM_FAIR_MUTEX_P(x) SCM_TYP16_PREDICATE (scm_tc16_fair_mutex, x)
45 #define SCM_MUTEX_DATA(x) ((void *) SCM_CELL_WORD_1 (x))
46
47 #define SCM_CONDVARP(x) SCM_TYP16_PREDICATE (scm_tc16_condvar, x)
48 #define SCM_FAIR_CONDVAR_P(x) SCM_TYP16_PREDICATE (scm_tc16_fair_condvar, x)
49 #define SCM_CONDVAR_DATA(x) ((void *) SCM_CELL_WORD_1 (x))
50
51 #define SCM_VALIDATE_THREAD(pos, a) \
52 SCM_MAKE_VALIDATE_MSG (pos, a, THREADP, "thread")
53
54 #define SCM_VALIDATE_MUTEX(pos, a) \
55 SCM_ASSERT_TYPE (SCM_MUTEXP (a) || SCM_FAIR_MUTEX_P (a), \
56 a, pos, FUNC_NAME, "mutex");
57
58 #define SCM_VALIDATE_CONDVAR(pos, a) \
59 SCM_ASSERT_TYPE (SCM_CONDVARP (a) || SCM_FAIR_CONDVAR_P (a), \
60 a, pos, FUNC_NAME, "condition variable");
61
62 SCM_API void scm_threads_mark_stacks (void);
63 SCM_API void scm_init_threads (SCM_STACKITEM *);
64 SCM_API void scm_init_thread_procs (void);
65
66 #if SCM_USE_PTHREAD_THREADS
67 # include "libguile/pthread-threads.h"
68 #else
69 # include "libguile/null-threads.h"
70 #endif
71
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.
77
78 Note that Guile also uses it to implement itself, just like
79 with the rest of the application API.
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 */
92 SCM_API SCM scm_spawn_thread (scm_t_catch_body body, void *body_data,
93 scm_t_catch_handler handler, void *handler_data);
94
95 #define scm_thread_join scm_i_plugin_thread_join
96 #define scm_thread_detach scm_i_plugin_thread_detach
97 #define scm_thread_self scm_i_plugin_thread_self
98 #define scm_thread_yield scm_i_plugin_thread_yield
99
100 #define scm_mutex_init scm_i_plugin_mutex_init
101 #define scm_mutex_destroy scm_i_plugin_mutex_destroy
102 SCM_API int scm_mutex_lock (scm_t_mutex *m);
103 #define scm_mutex_trylock scm_i_plugin_mutex_trylock
104 #define scm_mutex_unlock scm_i_plugin_mutex_unlock
105
106 /* Guile itself needs recursive mutexes. See for example the
107 implentation of scm_force in eval.c.
108
109 Note that scm_rec_mutex_lock et al can be replaced by direct usage
110 of the corresponding pthread functions if we use the pthread
111 debugging API to access the stack top (in which case there is no
112 longer any need to save the top of the stack before blocking).
113
114 It's therefore highly motivated to use these calls in situations
115 where Guile or the application needs recursive mutexes.
116 */
117 #define scm_rec_mutex_init scm_i_plugin_rec_mutex_init
118 #define scm_rec_mutex_destroy scm_i_plugin_rec_mutex_destroy
119 /* It's a safer bet to use the following functions.
120 The future of the _init functions is uncertain.
121 */
122 SCM_API scm_t_rec_mutex *scm_make_rec_mutex (void);
123 SCM_API void scm_rec_mutex_free (scm_t_rec_mutex *);
124 SCM_API int scm_rec_mutex_lock (scm_t_rec_mutex *m);
125 #define scm_rec_mutex_trylock scm_i_plugin_rec_mutex_trylock
126 #define scm_rec_mutex_unlock scm_i_plugin_rec_mutex_unlock
127
128 #define scm_cond_init scm_i_plugin_cond_init
129 #define scm_cond_destroy scm_i_plugin_cond_destroy
130 SCM_API int scm_cond_wait (scm_t_cond *c, scm_t_mutex *m);
131 SCM_API int scm_cond_timedwait (scm_t_cond *c,
132 scm_t_mutex *m,
133 const scm_t_timespec *t);
134 #define scm_cond_signal scm_i_plugin_cond_signal
135 #define scm_cond_broadcast scm_i_plugin_cond_broadcast
136
137 #define scm_key_create scm_i_plugin_key_create
138 #define scm_key_delete scm_i_plugin_key_delete
139 SCM_API int scm_setspecific (scm_t_key k, void *s);
140 SCM_API void *scm_getspecific (scm_t_key k);
141
142 #define scm_thread_select scm_internal_select
143
144 /* The application must scm_leave_guile() before entering any piece of
145 code which can
146 1. block, or
147 2. execute for any longer period of time without calling SCM_TICK
148
149 Note, though, that it is *not* necessary to use these calls
150 together with any call in this API.
151 */
152
153 SCM_API void scm_enter_guile (void);
154 SCM_API void scm_leave_guile (void);
155
156 /* Better versions (although we need the former ones also in order to
157 avoid forcing code restructuring in existing applications): */
158 /*fixme* Not implemented yet! */
159 SCM_API void *scm_in_guile (void (*func) (void*), void *data);
160 SCM_API void *scm_outside_guile (void (*func) (void*), void *data);
161
162 /* These are versions of the ordinary sleep and usleep functions
163 that play nicely with the thread system. */
164 SCM_API unsigned long scm_thread_sleep (unsigned long);
165 SCM_API unsigned long scm_thread_usleep (unsigned long);
166
167 /* End of low-level C API */
168 /*----------------------------------------------------------------------*/
169
170 typedef struct scm_thread scm_thread;
171
172 SCM_API void scm_i_enter_guile (scm_thread *t);
173 SCM_API scm_thread *scm_i_leave_guile (void);
174
175 /* Critical sections */
176
177 /* This is the generic critical section for places where we are too
178 lazy to allocate a specific mutex. */
179 extern scm_t_mutex scm_i_critical_section_mutex;
180
181 #define SCM_CRITICAL_SECTION_START \
182 scm_mutex_lock (&scm_i_critical_section_mutex)
183 #define SCM_CRITICAL_SECTION_END \
184 scm_mutex_unlock (&scm_i_critical_section_mutex)
185
186 /* This is the temporary support for the old ALLOW/DEFER ints sections */
187 extern scm_t_rec_mutex scm_i_defer_mutex;
188
189 extern int scm_i_thread_go_to_sleep;
190
191 void scm_i_thread_put_to_sleep (void);
192 void scm_i_thread_wake_up (void);
193 void scm_i_thread_invalidate_freelists (void);
194 void scm_i_thread_sleep_for_gc (void);
195 void scm_threads_prehistory (void);
196 void scm_threads_init_first_thread (void);
197
198 #define SCM_THREAD_SWITCHING_CODE \
199 do { \
200 if (scm_i_thread_go_to_sleep) \
201 scm_i_thread_sleep_for_gc (); \
202 } while (0)
203
204 SCM scm_i_create_thread (scm_t_catch_body body, void *body_data,
205 scm_t_catch_handler handler, void *handler_data,
206 SCM protects);
207
208 /* The C versions of the Scheme-visible thread functions. */
209 SCM_API SCM scm_call_with_new_thread (SCM thunk, SCM handler);
210 SCM_API SCM scm_yield (void);
211 SCM_API SCM scm_join_thread (SCM t);
212 SCM_API SCM scm_make_mutex (void);
213 SCM_API SCM scm_make_fair_mutex (void);
214 SCM_API SCM scm_lock_mutex (SCM m);
215 SCM_API SCM scm_try_mutex (SCM m);
216 SCM_API SCM scm_unlock_mutex (SCM m);
217 SCM_API SCM scm_make_condition_variable (void);
218 SCM_API SCM scm_make_fair_condition_variable (void);
219 SCM_API SCM scm_wait_condition_variable (SCM cond, SCM mutex);
220 SCM_API SCM scm_timed_wait_condition_variable (SCM cond, SCM mutex,
221 SCM abstime);
222 SCM_API SCM scm_signal_condition_variable (SCM cond);
223 SCM_API SCM scm_broadcast_condition_variable (SCM cond);
224
225 SCM_API SCM scm_current_thread (void);
226 SCM_API SCM scm_all_threads (void);
227
228 SCM_API int scm_c_thread_exited_p (SCM thread);
229 SCM_API SCM scm_thread_exited_p (SCM thread);
230
231 SCM_API scm_root_state *scm_i_thread_root (SCM thread);
232
233 #define SCM_CURRENT_THREAD \
234 ((scm_thread *) scm_i_plugin_getspecific (scm_i_thread_key))
235 extern scm_t_key scm_i_thread_key;
236
237 /* These macros have confusing names.
238 They really refer to the root state of the running thread. */
239 #define SCM_THREAD_LOCAL_DATA (scm_getspecific (scm_i_root_state_key))
240 #define SCM_SET_THREAD_LOCAL_DATA(x) scm_i_set_thread_data(x)
241 SCM_API scm_t_key scm_i_root_state_key;
242 SCM_API void scm_i_set_thread_data (void *);
243
244 #endif /* SCM_THREADS_H */
245
246 /*
247 Local Variables:
248 c-file-style: "gnu"
249 End:
250 */