1a004c07e75f8e8cde0b85b5bbb044529250dff3
[sbcl.git] / thread.h
1 #if !defined(_INCLUDE_THREAD_H_)
2 #define _INCLUDE_THREAD_H_
3
4 #include <sys/types.h>
5 #include <unistd.h>
6 #include <stddef.h>
7 #include "sbcl.h"
8 #include "globals.h"
9 #include "runtime.h"
10 #include "os.h"
11 #ifdef LISP_FEATURE_GENCGC
12 #include "gencgc-alloc-region.h"
13 #endif
14 #ifdef LISP_FEATURE_WIN32
15 #include "win32-thread-private-events.h"
16 #endif
17 #include "genesis/symbol.h"
18 #include "genesis/static-symbols.h"
19
20 #include "genesis/thread.h"
21 #include "genesis/fdefn.h"
22 #include "interrupt.h"
23 #include "validate.h"           /* for BINDING_STACK_SIZE etc */
24
25 #define STATE_RUNNING MAKE_FIXNUM(1)
26 #define STATE_STOPPED MAKE_FIXNUM(2)
27 #define STATE_DEAD MAKE_FIXNUM(3)
28 #if defined(LISP_FEATURE_SB_SAFEPOINT)
29 # define STATE_SUSPENDED_BRIEFLY MAKE_FIXNUM(4)
30 # define STATE_GC_BLOCKER MAKE_FIXNUM(5)
31 # define STATE_PHASE1_BLOCKER MAKE_FIXNUM(5)
32 # define STATE_PHASE2_BLOCKER MAKE_FIXNUM(6)
33 # define STATE_INTERRUPT_BLOCKER MAKE_FIXNUM(7)
34 #endif
35
36 #ifdef LISP_FEATURE_SB_THREAD
37 lispobj thread_state(struct thread *thread);
38 void set_thread_state(struct thread *thread, lispobj state);
39 void wait_for_thread_state_change(struct thread *thread, lispobj state);
40
41 #if defined(LISP_FEATURE_SB_SAFEPOINT)
42 enum threads_suspend_reason {
43     SUSPEND_REASON_NONE,
44     SUSPEND_REASON_GC,
45     SUSPEND_REASON_INTERRUPT,
46     SUSPEND_REASON_GCING
47 };
48
49 struct threads_suspend_info {
50     int suspend;
51     pthread_mutex_t world_lock;
52     pthread_mutex_t lock;
53     enum threads_suspend_reason reason;
54     int phase;
55     struct thread * gc_thread;
56     struct thread * interrupted_thread;
57     int blockers;
58     int used_gc_page;
59 };
60
61 struct suspend_phase {
62     int suspend;
63     enum threads_suspend_reason reason;
64     int phase;
65     struct suspend_phase *next;
66 };
67
68 extern struct threads_suspend_info suspend_info;
69
70 struct gcing_safety {
71     lispobj csp_around_foreign_call;
72 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
73     lispobj* pc_around_foreign_call;
74 #endif
75 };
76
77 int handle_safepoint_violation(os_context_t *context, os_vm_address_t addr);
78 void** os_get_csp(struct thread* th);
79 void alloc_gc_page();
80 void assert_on_stack(struct thread *th, void *esp);
81 #endif /* defined(LISP_FEATURE_SB_SAFEPOINT) */
82
83 extern pthread_key_t lisp_thread;
84 #endif
85
86 extern int kill_safely(os_thread_t os_thread, int signal);
87
88 #define THREAD_SLOT_OFFSET_WORDS(c) \
89  (offsetof(struct thread,c)/(sizeof (struct thread *)))
90
91 union per_thread_data {
92     struct thread thread;
93     lispobj dynamic_values[1];  /* actually more like 4000 or so */
94 };
95
96 /* A helper structure for data local to a thread, which is not pointer-sized.
97  *
98  * Originally, all layouting of these fields was done manually in C code
99  * with pointer arithmetic.  We let the C compiler figure it out now.
100  *
101  * (Why is this not part of `struct thread'?  Because that structure is
102  * declared using genesis, and we would run into issues with fields that
103  * are of unknown length.)
104  */
105 struct nonpointer_thread_data
106 {
107 #if defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_SB_SAFEPOINT)
108     os_sem_t state_sem;
109     os_sem_t state_not_running_sem;
110     os_sem_t state_not_stopped_sem;
111 #else
112     /* An unused field follows, to ensure that the struct is non-empty
113      * for non-GCC compilers. */
114     int unused;
115 #endif
116 };
117
118 extern struct thread *all_threads;
119 extern int dynamic_values_bytes;
120
121 #if defined(LISP_FEATURE_DARWIN)
122 #define CONTROL_STACK_ALIGNMENT_BYTES 8192 /* darwin wants page-aligned stacks */
123 #define THREAD_ALIGNMENT_BYTES CONTROL_STACK_ALIGNMENT_BYTES
124 #else
125 #define THREAD_ALIGNMENT_BYTES BACKEND_PAGE_BYTES
126 #define CONTROL_STACK_ALIGNMENT_BYTES 16
127 #endif
128
129
130 #ifdef LISP_FEATURE_SB_THREAD
131 #define for_each_thread(th) for(th=all_threads;th;th=th->next)
132 #else
133 /* there's some possibility a SSC could notice this never actually
134  * loops  */
135 #define for_each_thread(th) for(th=all_threads;th;th=0)
136 #endif
137
138 static inline lispobj *
139 SymbolValueAddress(u64 tagged_symbol_pointer, void *thread)
140 {
141     struct symbol *sym= (struct symbol *)
142         (pointer_sized_uint_t)(tagged_symbol_pointer-OTHER_POINTER_LOWTAG);
143 #ifdef LISP_FEATURE_SB_THREAD
144     if(thread && sym->tls_index) {
145         lispobj *r = &(((union per_thread_data *)thread)
146                        ->dynamic_values[(sym->tls_index) >> WORD_SHIFT]);
147         if((*r)!=NO_TLS_VALUE_MARKER_WIDETAG) return r;
148     }
149 #endif
150     return &sym->value;
151 }
152
153 static inline lispobj
154 SymbolValue(u64 tagged_symbol_pointer, void *thread)
155 {
156     struct symbol *sym= (struct symbol *)
157         (pointer_sized_uint_t)(tagged_symbol_pointer-OTHER_POINTER_LOWTAG);
158 #ifdef LISP_FEATURE_SB_THREAD
159     if(thread && sym->tls_index) {
160         lispobj r=
161             ((union per_thread_data *)thread)
162             ->dynamic_values[(sym->tls_index) >> WORD_SHIFT];
163         if(r!=NO_TLS_VALUE_MARKER_WIDETAG) return r;
164     }
165 #endif
166     return sym->value;
167 }
168
169 static inline lispobj
170 SymbolTlValue(u64 tagged_symbol_pointer, void *thread)
171 {
172     struct symbol *sym= (struct symbol *)
173         (pointer_sized_uint_t)(tagged_symbol_pointer-OTHER_POINTER_LOWTAG);
174 #ifdef LISP_FEATURE_SB_THREAD
175     return ((union per_thread_data *)thread)
176         ->dynamic_values[(sym->tls_index) >> WORD_SHIFT];
177 #else
178     return sym->value;
179 #endif
180 }
181
182 static inline void
183 SetSymbolValue(u64 tagged_symbol_pointer,lispobj val, void *thread)
184 {
185     struct symbol *sym= (struct symbol *)
186         (pointer_sized_uint_t)(tagged_symbol_pointer-OTHER_POINTER_LOWTAG);
187 #ifdef LISP_FEATURE_SB_THREAD
188     if(thread && sym->tls_index) {
189         lispobj *pr= &(((union per_thread_data *)thread)
190                        ->dynamic_values[(sym->tls_index) >> WORD_SHIFT]);
191         if(*pr!=NO_TLS_VALUE_MARKER_WIDETAG) {
192             *pr=val;
193             return;
194         }
195     }
196 #endif
197     sym->value = val;
198 }
199
200 static inline void
201 SetTlSymbolValue(u64 tagged_symbol_pointer,lispobj val, void *thread)
202 {
203 #ifdef LISP_FEATURE_SB_THREAD
204     struct symbol *sym= (struct symbol *)
205         (pointer_sized_uint_t)(tagged_symbol_pointer-OTHER_POINTER_LOWTAG);
206     ((union per_thread_data *)thread)
207         ->dynamic_values[(sym->tls_index) >> WORD_SHIFT]
208         =val;
209 #else
210     SetSymbolValue(tagged_symbol_pointer,val,thread) ;
211 #endif
212 }
213
214 /* This only works for static symbols. */
215 static inline lispobj
216 StaticSymbolFunction(lispobj sym)
217 {
218     return ((struct fdefn *)native_pointer(SymbolValue(sym, 0)))->fun;
219 }
220
221 /* These are for use during GC, on the current thread, or on prenatal
222  * threads only. */
223 #if defined(LISP_FEATURE_SB_THREAD)
224 #define get_binding_stack_pointer(thread)       \
225     ((thread)->binding_stack_pointer)
226 #define set_binding_stack_pointer(thread,value) \
227     ((thread)->binding_stack_pointer = (lispobj *)(value))
228 #define access_control_stack_pointer(thread) \
229     ((thread)->control_stack_pointer)
230 #  if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
231 #define access_control_frame_pointer(thread) \
232     ((thread)->control_frame_pointer)
233 #  endif
234 #else
235 #  if defined(BINDING_STACK_POINTER)
236 #define get_binding_stack_pointer(thread)       \
237     SymbolValue(BINDING_STACK_POINTER, thread)
238 #define set_binding_stack_pointer(thread,value) \
239     SetSymbolValue(BINDING_STACK_POINTER, (lispobj)(value), thread)
240 #  else
241 #define get_binding_stack_pointer(thread)       \
242     (current_binding_stack_pointer)
243 #define set_binding_stack_pointer(thread,value) \
244     (current_binding_stack_pointer = (lispobj *)(value))
245 #  endif
246 #define access_control_stack_pointer(thread)    \
247     (current_control_stack_pointer)
248 #  if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
249 #define access_control_frame_pointer(thread) \
250     (current_control_frame_pointer)
251 #  endif
252 #endif
253
254 #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_GCC_TLS)
255 extern __thread struct thread *current_thread;
256 #endif
257
258 #ifndef LISP_FEATURE_SB_SAFEPOINT
259 # define THREAD_CSP_PAGE_SIZE 0
260 #elif defined(LISP_FEATURE_PPC)
261   /* BACKEND_PAGE_BYTES is nice and large on this platform, but therefore
262    * does not fit into an immediate, making it awkward to access the page
263    * relative to the thread-tn... */
264 # define THREAD_CSP_PAGE_SIZE 4096
265 #else
266 # define THREAD_CSP_PAGE_SIZE BACKEND_PAGE_BYTES
267 #endif
268
269 #ifdef LISP_FEATURE_WIN32
270 /*
271  * Win32 doesn't have SIGSTKSZ, and we're not switching stacks anyway,
272  * so define it arbitrarily
273  */
274 #define SIGSTKSZ 1024
275 #endif
276
277 #define THREAD_STRUCT_SIZE (thread_control_stack_size + BINDING_STACK_SIZE + \
278                             ALIEN_STACK_SIZE +                          \
279                             sizeof(struct nonpointer_thread_data) +     \
280                             dynamic_values_bytes +                      \
281                             32 * SIGSTKSZ +                             \
282                             THREAD_ALIGNMENT_BYTES +                    \
283                             THREAD_CSP_PAGE_SIZE)
284
285 #if defined(LISP_FEATURE_WIN32)
286 static inline struct thread* arch_os_get_current_thread()
287     __attribute__((__const__));
288 #endif
289
290 /* This is clearly per-arch and possibly even per-OS code, but we can't
291  * put it somewhere sensible like x86-linux-os.c because it needs too
292  * much stuff like struct thread and all_threads to be defined, which
293  * usually aren't by that time.  So, it's here instead.  Sorry */
294
295 static inline struct thread *arch_os_get_current_thread(void)
296 {
297 #if !defined(LISP_FEATURE_SB_THREAD)
298      return all_threads;
299
300 #elif defined(LISP_FEATURE_X86) && defined(LISP_FEATURE_WIN32)
301     register struct thread *me=0;
302     __asm__ ("movl %%fs:0xE10+(4*63), %0" : "=r"(me) :);
303     return me;
304
305 #else
306
307 # if defined(LISP_FEATURE_X86)
308     if (!all_threads) return 0;
309 #endif
310
311     /* Otherwise, use pthreads to find the right value.  We do not load
312      * directly from %fs:this even on x86 platforms (like Linux and
313      * Solaris) with dependable %fs, because we want to return NULL if
314      * called by a non-Lisp thread, and %fs would not be initialized
315      * suitably in that case. */
316     struct thread *th;
317 # ifdef LISP_FEATURE_GCC_TLS
318     th = current_thread;
319 # else
320     th = pthread_getspecific(specials);
321 # endif
322
323 # if defined(LISP_FEATURE_RESTORE_FS_SEGMENT_REGISTER_FROM_TLS)
324     /* If enabled by make-config (currently Darwin and FreeBSD only),
325      * re-setup %fs.  This is an out-of-line call, and potentially
326      * expensive.*/
327     if (th)
328         arch_os_load_ldt(th);
329 # endif
330
331     return th;
332 #endif
333 }
334
335 #if defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
336 extern kern_return_t mach_lisp_thread_init(struct thread *thread);
337 extern kern_return_t mach_lisp_thread_destroy(struct thread *thread);
338 #endif
339
340 typedef struct init_thread_data {
341     sigset_t oldset;
342 #ifdef LISP_FEATURE_SB_SAFEPOINT
343     struct gcing_safety safety;
344 #endif
345 } init_thread_data;
346
347 #ifdef LISP_FEATURE_SB_SAFEPOINT
348 void thread_in_safety_transition(os_context_t *ctx);
349 void thread_in_lisp_raised(os_context_t *ctx);
350 void thread_interrupted(os_context_t *ctx);
351 void thread_pitstop(os_context_t *ctxptr);
352 extern void thread_register_gc_trigger();
353
354 # ifdef LISP_FEATURE_SB_THRUPTION
355 int wake_thread(os_thread_t os_thread);
356 #  ifdef LISP_FEATURE_WIN32
357 void wake_thread_win32(struct thread *thread);
358 #  else
359 int wake_thread_posix(os_thread_t os_thread);
360 #  endif
361 # endif
362
363 static inline
364 void push_gcing_safety(struct gcing_safety *into)
365 {
366     struct thread* th = arch_os_get_current_thread();
367     asm volatile ("");
368     if ((into->csp_around_foreign_call =
369          *th->csp_around_foreign_call)) {
370         *th->csp_around_foreign_call = 0;
371         asm volatile ("");
372 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
373         into->pc_around_foreign_call = th->pc_around_foreign_call;
374         th->pc_around_foreign_call = 0;
375         asm volatile ("");
376 #endif
377     } else {
378 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
379         into->pc_around_foreign_call = 0;
380 #endif
381     }
382 }
383
384 static inline
385 void pop_gcing_safety(struct gcing_safety *from)
386 {
387     struct thread* th = arch_os_get_current_thread();
388     if (from->csp_around_foreign_call) {
389         asm volatile ("");
390         *th->csp_around_foreign_call = from->csp_around_foreign_call;
391         asm volatile ("");
392 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
393         th->pc_around_foreign_call = from->pc_around_foreign_call;
394         asm volatile ("");
395 #endif
396     }
397 }
398
399 /* Even with just -O1, gcc optimizes the jumps in this "loop" away
400  * entirely, giving the ability to define WITH-FOO-style macros. */
401 #define RUN_BODY_ONCE(prefix, finally_do)               \
402     int prefix##done = 0;                               \
403     for (; !prefix##done; finally_do, prefix##done = 1)
404
405 #define WITH_GC_AT_SAFEPOINTS_ONLY_hygenic(var)        \
406     struct gcing_safety var;                    \
407     push_gcing_safety(&var);                    \
408     RUN_BODY_ONCE(var, pop_gcing_safety(&var))
409
410 #define WITH_GC_AT_SAFEPOINTS_ONLY()                           \
411     WITH_GC_AT_SAFEPOINTS_ONLY_hygenic(sbcl__gc_safety)
412
413 #define WITH_STATE_SEM_hygenic(var, thread)                             \
414     os_sem_wait((thread)->state_sem, "thread_state");                   \
415     RUN_BODY_ONCE(var, os_sem_post((thread)->state_sem, "thread_state"))
416
417 #define WITH_STATE_SEM(thread)                                     \
418     WITH_STATE_SEM_hygenic(sbcl__state_sem, thread)
419
420 int check_pending_thruptions(os_context_t *ctx);
421
422 void attach_os_thread(init_thread_data *);
423 void detach_os_thread(init_thread_data *);
424
425 # if defined(LISP_FEATURE_SB_SAFEPOINT_STRICTLY) && !defined(LISP_FEATURE_WIN32)
426
427 void signal_handler_callback(lispobj, int, void *, void *);
428 # endif
429
430 #endif
431
432 extern void create_initial_thread(lispobj);
433
434 #ifdef LISP_FEATURE_SB_THREAD
435 extern pthread_mutex_t all_threads_lock;
436 #endif
437
438 #endif /* _INCLUDE_THREAD_H_ */