82 |
SCM_ASSERT_TYPE (SCM_CONDVARP (a) || SCM_FAIR_CONDVAR_P (a), \ |
SCM_ASSERT_TYPE (SCM_CONDVARP (a) || SCM_FAIR_CONDVAR_P (a), \ |
83 |
a, pos, FUNC_NAME, "condition variable"); |
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); |
SCM_API void scm_threads_mark_stacks (void); |
100 |
SCM_API void scm_init_threads (SCM_STACKITEM *); |
SCM_API void scm_init_threads (SCM_STACKITEM *); |
101 |
SCM_API void scm_init_thread_procs (void); |
SCM_API void scm_init_thread_procs (void); |
105 |
|
|
106 |
/* The purpose of this API is seamless, simple and thread package |
/* The purpose of this API is seamless, simple and thread package |
107 |
independent interaction with Guile threads from the application. |
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>: |
/* MDJ 021209 <djurfeldt@nada.kth.se>: |
133 |
#define scm_mutex_trylock scm_i_plugin_mutex_trylock |
#define scm_mutex_trylock scm_i_plugin_mutex_trylock |
134 |
#define scm_mutex_unlock scm_i_plugin_mutex_unlock |
#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 |
#define scm_cond_init scm_i_plugin_cond_init |
159 |
#define scm_cond_destroy scm_i_plugin_cond_destroy |
#define scm_cond_destroy scm_i_plugin_cond_destroy |
160 |
SCM_API int scm_cond_wait (scm_t_cond *c, scm_t_mutex *m); |
SCM_API int scm_cond_wait (scm_t_cond *c, scm_t_mutex *m); |
197 |
/* End of low-level C API */ |
/* End of low-level C API */ |
198 |
/*----------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------*/ |
199 |
|
|
200 |
|
extern SCM *scm_loc_sys_thread_handler; |
201 |
|
|
202 |
typedef struct scm_thread scm_thread; |
typedef struct scm_thread scm_thread; |
203 |
|
|
204 |
SCM_API void scm_i_enter_guile (scm_thread *t); |
SCM_API void scm_i_enter_guile (scm_thread *t); |
206 |
|
|
207 |
/* Critical sections */ |
/* Critical sections */ |
208 |
|
|
|
SCM_API scm_t_mutex scm_i_section_mutex; |
|
|
|
|
209 |
/* This is the generic critical section for places where we are too |
/* This is the generic critical section for places where we are too |
210 |
lazy to allocate a specific mutex. */ |
lazy to allocate a specific mutex. */ |
211 |
SCM_DECLARE_NONREC_CRITICAL_SECTION (scm_i_critical_section); |
extern scm_t_mutex scm_i_critical_section_mutex; |
212 |
|
|
213 |
#define SCM_CRITICAL_SECTION_START \ |
#define SCM_CRITICAL_SECTION_START \ |
214 |
SCM_NONREC_CRITICAL_SECTION_START (scm_i_critical_section) |
scm_mutex_lock (&scm_i_critical_section_mutex) |
215 |
#define SCM_CRITICAL_SECTION_END \ |
#define SCM_CRITICAL_SECTION_END \ |
216 |
SCM_NONREC_CRITICAL_SECTION_END (scm_i_critical_section) |
scm_mutex_unlock (&scm_i_critical_section_mutex) |
217 |
|
|
218 |
/* This is the temporary support for the old ALLOW/DEFER ints sections */ |
/* This is the temporary support for the old ALLOW/DEFER ints sections */ |
219 |
SCM_DECLARE_REC_CRITICAL_SECTION (scm_i_defer); |
extern scm_t_rec_mutex scm_i_defer_mutex; |
220 |
|
|
221 |
extern int scm_i_thread_go_to_sleep; |
extern int scm_i_thread_go_to_sleep; |
222 |
|
|
236 |
/* The C versions of the Scheme-visible thread functions. */ |
/* The C versions of the Scheme-visible thread functions. */ |
237 |
SCM_API SCM scm_call_with_new_thread (SCM thunk, SCM handler); |
SCM_API SCM scm_call_with_new_thread (SCM thunk, SCM handler); |
238 |
SCM_API SCM scm_join_thread (SCM t); |
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); |
SCM_API SCM scm_make_mutex (void); |
242 |
SCM_API SCM scm_make_fair_mutex (void); |
SCM_API SCM scm_make_fair_mutex (void); |
243 |
SCM_API SCM scm_lock_mutex (SCM m); |
SCM_API SCM scm_lock_mutex (SCM m); |