create_thread_struct: don't allocate interrupt_data separately.
[sbcl.git] / src / runtime / thread.h
blob00f2927b82a474b2274814a951a0812506f6ae3f
1 #if !defined(_INCLUDE_THREAD_H_)
2 #define _INCLUDE_THREAD_H_
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"
20 #include "genesis/thread.h"
21 #include "genesis/fdefn.h"
22 #include "interrupt.h"
23 #include "validate.h" /* for BINDING_STACK_SIZE etc */
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
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);
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
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;
61 struct suspend_phase {
62 int suspend;
63 enum threads_suspend_reason reason;
64 int phase;
65 struct suspend_phase *next;
68 extern struct threads_suspend_info suspend_info;
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
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) */
83 extern pthread_key_t lisp_thread;
84 #endif
86 extern int kill_safely(os_thread_t os_thread, int signal);
88 #define THREAD_SLOT_OFFSET_WORDS(c) \
89 (offsetof(struct thread,c)/(sizeof (struct thread *)))
91 union per_thread_data {
92 struct thread thread;
93 lispobj dynamic_values[1]; /* actually more like 4000 or so */
96 /* The thread struct is generated from lisp during genesis and it
97 * needs to know the sizes of all its members, but some types may have
98 * arbitrary lengths, thus the pointers are stored instead. This
99 * structure is used to help allocation of those types, so that the
100 * pointers can be later shoved into the thread struct. */
101 struct nonpointer_thread_data
103 #if defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_SB_SAFEPOINT)
104 os_sem_t state_sem;
105 os_sem_t state_not_running_sem;
106 os_sem_t state_not_stopped_sem;
107 #endif
108 pthread_attr_t os_attr;
109 struct interrupt_data interrupt_data;
112 extern struct thread *all_threads;
113 extern int dynamic_values_bytes;
115 #if defined(LISP_FEATURE_DARWIN)
116 #define CONTROL_STACK_ALIGNMENT_BYTES 8192 /* darwin wants page-aligned stacks */
117 #define THREAD_ALIGNMENT_BYTES CONTROL_STACK_ALIGNMENT_BYTES
118 #else
119 #define THREAD_ALIGNMENT_BYTES BACKEND_PAGE_BYTES
120 #define CONTROL_STACK_ALIGNMENT_BYTES 16
121 #endif
124 #ifdef LISP_FEATURE_SB_THREAD
125 #define for_each_thread(th) for(th=all_threads;th;th=th->next)
126 #else
127 /* there's some possibility a SSC could notice this never actually
128 * loops */
129 #define for_each_thread(th) for(th=all_threads;th;th=0)
130 #endif
132 #ifndef LISP_FEATURE_SB_THREAD
133 /* no threads: every symbol's tls_index is statically zero */
134 # define tls_index_of(x) 0
135 # define per_thread_value(sym, thread) sym->value
136 #else
137 #ifdef LISP_FEATURE_64_BIT
138 static inline int
139 tls_index_of(struct symbol *symbol) // untagged pointer
141 return symbol->header >> 32;
143 #else
144 # define tls_index_of(x) (x->tls_index)
145 #endif
146 #define per_thread_value(sym,th) \
147 ((union per_thread_data *)th)->dynamic_values[tls_index_of(sym)>>WORD_SHIFT]
148 #endif
150 static inline lispobj *
151 SymbolValueAddress(u64 tagged_symbol_pointer, void *thread)
153 struct symbol *sym= SYMBOL(tagged_symbol_pointer);
154 if(thread && tls_index_of(sym)) {
155 lispobj *r = &per_thread_value(sym, thread);
156 if((*r)!=NO_TLS_VALUE_MARKER_WIDETAG) return r;
158 return &sym->value;
161 static inline lispobj
162 SymbolValue(u64 tagged_symbol_pointer, void *thread)
164 struct symbol *sym= SYMBOL(tagged_symbol_pointer);
165 if(thread && tls_index_of(sym)) {
166 lispobj r = per_thread_value(sym, thread);
167 if(r!=NO_TLS_VALUE_MARKER_WIDETAG) return r;
169 return sym->value;
172 static inline void
173 SetSymbolValue(u64 tagged_symbol_pointer,lispobj val, void *thread)
175 struct symbol *sym= SYMBOL(tagged_symbol_pointer);
176 if(thread && tls_index_of(sym)) {
177 if (per_thread_value(sym, thread) != NO_TLS_VALUE_MARKER_WIDETAG) {
178 per_thread_value(sym, thread) = val;
179 return;
182 sym->value = val;
185 static inline lispobj
186 SymbolTlValue(u64 tagged_symbol_pointer, void *thread)
188 struct symbol *sym= SYMBOL(tagged_symbol_pointer);
189 return per_thread_value(sym, thread);
192 static inline void
193 SetTlSymbolValue(u64 tagged_symbol_pointer,lispobj val, void *thread)
195 struct symbol *sym= SYMBOL(tagged_symbol_pointer);
196 // dynbind asserts that there is a tls_index in multithread runtime
197 per_thread_value(sym, thread) = val;
200 /* This only works for static symbols. */
201 static inline lispobj
202 StaticSymbolFunction(lispobj sym)
204 return ((struct fdefn *)native_pointer(SymbolValue(sym, 0)))->fun;
207 /* These are for use during GC, on the current thread, or on prenatal
208 * threads only. */
209 #if defined(LISP_FEATURE_SB_THREAD)
210 #define get_binding_stack_pointer(thread) \
211 ((thread)->binding_stack_pointer)
212 #define set_binding_stack_pointer(thread,value) \
213 ((thread)->binding_stack_pointer = (lispobj *)(value))
214 #define access_control_stack_pointer(thread) \
215 ((thread)->control_stack_pointer)
216 # if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
217 #define access_control_frame_pointer(thread) \
218 ((thread)->control_frame_pointer)
219 # endif
220 #else
221 # if defined(BINDING_STACK_POINTER)
222 #define get_binding_stack_pointer(thread) \
223 SymbolValue(BINDING_STACK_POINTER, thread)
224 #define set_binding_stack_pointer(thread,value) \
225 SetSymbolValue(BINDING_STACK_POINTER, (lispobj)(value), thread)
226 # else
227 #define get_binding_stack_pointer(thread) \
228 (current_binding_stack_pointer)
229 #define set_binding_stack_pointer(thread,value) \
230 (current_binding_stack_pointer = (lispobj *)(value))
231 # endif
232 #define access_control_stack_pointer(thread) \
233 (current_control_stack_pointer)
234 # if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
235 #define access_control_frame_pointer(thread) \
236 (current_control_frame_pointer)
237 # endif
238 #endif
240 #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_GCC_TLS)
241 extern __thread struct thread *current_thread;
242 #endif
244 #ifndef LISP_FEATURE_SB_SAFEPOINT
245 # define THREAD_CSP_PAGE_SIZE 0
246 #elif defined(LISP_FEATURE_PPC)
247 /* BACKEND_PAGE_BYTES is nice and large on this platform, but therefore
248 * does not fit into an immediate, making it awkward to access the page
249 * relative to the thread-tn... */
250 # define THREAD_CSP_PAGE_SIZE 4096
251 #else
252 # define THREAD_CSP_PAGE_SIZE BACKEND_PAGE_BYTES
253 #endif
255 #ifdef LISP_FEATURE_WIN32
257 * Win32 doesn't have SIGSTKSZ, and we're not switching stacks anyway,
258 * so define it arbitrarily
260 #define SIGSTKSZ 1024
261 #endif
263 #define THREAD_STRUCT_SIZE (thread_control_stack_size + BINDING_STACK_SIZE + \
264 ALIEN_STACK_SIZE + \
265 sizeof(struct nonpointer_thread_data) + \
266 dynamic_values_bytes + \
267 32 * SIGSTKSZ + \
268 THREAD_ALIGNMENT_BYTES + \
269 THREAD_CSP_PAGE_SIZE)
271 #if defined(LISP_FEATURE_WIN32)
272 static inline struct thread* arch_os_get_current_thread()
273 __attribute__((__const__));
274 #endif
276 /* This is clearly per-arch and possibly even per-OS code, but we can't
277 * put it somewhere sensible like x86-linux-os.c because it needs too
278 * much stuff like struct thread and all_threads to be defined, which
279 * usually aren't by that time. So, it's here instead. Sorry */
281 static inline struct thread *arch_os_get_current_thread(void)
283 #if !defined(LISP_FEATURE_SB_THREAD)
284 return all_threads;
286 #elif defined(LISP_FEATURE_X86) && defined(LISP_FEATURE_WIN32)
287 register struct thread *me=0;
288 __asm__ volatile ("movl %%fs:0xE10+(4*63), %0" : "=r"(me) :);
289 return me;
291 #else
293 # if defined(LISP_FEATURE_X86)
294 if (!all_threads) return 0;
295 #endif
297 /* Otherwise, use pthreads to find the right value. We do not load
298 * directly from %fs:this even on x86 platforms (like Linux and
299 * Solaris) with dependable %fs, because we want to return NULL if
300 * called by a non-Lisp thread, and %fs would not be initialized
301 * suitably in that case. */
302 struct thread *th;
303 # ifdef LISP_FEATURE_GCC_TLS
304 th = current_thread;
305 # else
306 th = pthread_getspecific(specials);
307 # endif
309 # if defined(LISP_FEATURE_RESTORE_FS_SEGMENT_REGISTER_FROM_TLS)
310 /* If enabled by make-config (currently Darwin and FreeBSD only),
311 * re-setup %fs. This is an out-of-line call, and potentially
312 * expensive.*/
313 if (th) {
314 void arch_os_load_ldt(struct thread*);
315 arch_os_load_ldt(th);
317 # endif
319 return th;
320 #endif
323 #if defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
324 extern kern_return_t mach_lisp_thread_init(struct thread *thread);
325 extern kern_return_t mach_lisp_thread_destroy(struct thread *thread);
326 #endif
328 typedef struct init_thread_data {
329 sigset_t oldset;
330 #ifdef LISP_FEATURE_SB_SAFEPOINT
331 struct gcing_safety safety;
332 #endif
333 } init_thread_data;
335 #ifdef LISP_FEATURE_SB_SAFEPOINT
336 void thread_in_safety_transition(os_context_t *ctx);
337 void thread_in_lisp_raised(os_context_t *ctx);
338 void thread_interrupted(os_context_t *ctx);
339 void thread_pitstop(os_context_t *ctxptr);
340 extern void thread_register_gc_trigger();
342 # ifdef LISP_FEATURE_SB_THRUPTION
343 int wake_thread(os_thread_t os_thread);
344 # ifdef LISP_FEATURE_WIN32
345 void wake_thread_win32(struct thread *thread);
346 # else
347 int wake_thread_posix(os_thread_t os_thread);
348 # endif
349 # endif
351 static inline
352 void push_gcing_safety(struct gcing_safety *into)
354 struct thread* th = arch_os_get_current_thread();
355 asm volatile ("");
356 if ((into->csp_around_foreign_call =
357 *th->csp_around_foreign_call)) {
358 *th->csp_around_foreign_call = 0;
359 asm volatile ("");
360 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
361 into->pc_around_foreign_call = th->pc_around_foreign_call;
362 th->pc_around_foreign_call = 0;
363 asm volatile ("");
364 #endif
365 } else {
366 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
367 into->pc_around_foreign_call = 0;
368 #endif
372 static inline
373 void pop_gcing_safety(struct gcing_safety *from)
375 struct thread* th = arch_os_get_current_thread();
376 if (from->csp_around_foreign_call) {
377 asm volatile ("");
378 *th->csp_around_foreign_call = from->csp_around_foreign_call;
379 asm volatile ("");
380 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
381 th->pc_around_foreign_call = from->pc_around_foreign_call;
382 asm volatile ("");
383 #endif
387 /* Even with just -O1, gcc optimizes the jumps in this "loop" away
388 * entirely, giving the ability to define WITH-FOO-style macros. */
389 #define RUN_BODY_ONCE(prefix, finally_do) \
390 int prefix##done = 0; \
391 for (; !prefix##done; finally_do, prefix##done = 1)
393 #define WITH_GC_AT_SAFEPOINTS_ONLY_hygenic(var) \
394 struct gcing_safety var; \
395 push_gcing_safety(&var); \
396 RUN_BODY_ONCE(var, pop_gcing_safety(&var))
398 #define WITH_GC_AT_SAFEPOINTS_ONLY() \
399 WITH_GC_AT_SAFEPOINTS_ONLY_hygenic(sbcl__gc_safety)
401 #define WITH_STATE_SEM_hygenic(var, thread) \
402 os_sem_wait((thread)->state_sem, "thread_state"); \
403 RUN_BODY_ONCE(var, os_sem_post((thread)->state_sem, "thread_state"))
405 #define WITH_STATE_SEM(thread) \
406 WITH_STATE_SEM_hygenic(sbcl__state_sem, thread)
408 int check_pending_thruptions(os_context_t *ctx);
410 void attach_os_thread(init_thread_data *);
411 void detach_os_thread(init_thread_data *);
413 # if defined(LISP_FEATURE_SB_SAFEPOINT_STRICTLY) && !defined(LISP_FEATURE_WIN32)
415 void signal_handler_callback(lispobj, int, void *, void *);
416 # endif
418 #endif
420 extern void create_initial_thread(lispobj);
422 #ifdef LISP_FEATURE_SB_THREAD
423 extern pthread_mutex_t all_threads_lock;
424 #endif
426 #endif /* _INCLUDE_THREAD_H_ */