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