Merge pull request #3040 from xmcclure/debugger-step-recursive
[mono.git] / mono / utils / mono-threads.h
1 /*
2  * mono-threads.h: Low-level threading
3  *
4  * Author:
5  *      Rodrigo Kumpera (kumpera@gmail.com)
6  *
7  * (C) 2011 Novell, Inc
8  */
9
10 #ifndef __MONO_THREADS_H__
11 #define __MONO_THREADS_H__
12
13 #include <mono/utils/mono-os-semaphore.h>
14 #include <mono/utils/mono-stack-unwinding.h>
15 #include <mono/utils/mono-linked-list-set.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-coop-semaphore.h>
18
19 #include <mono/io-layer/io-layer.h>
20
21 #include <glib.h>
22 #include <config.h>
23 #ifdef HOST_WIN32
24
25 #include <windows.h>
26
27 typedef DWORD MonoNativeThreadId;
28 typedef HANDLE MonoNativeThreadHandle; /* unused */
29
30 typedef DWORD mono_native_thread_return_t;
31
32 #define MONO_NATIVE_THREAD_ID_TO_UINT(tid) (tid)
33 #define MONO_UINT_TO_NATIVE_THREAD_ID(tid) ((MonoNativeThreadId)(tid))
34
35 #else
36
37 #include <pthread.h>
38
39 #if defined(__MACH__)
40 #include <mono/utils/mach-support.h>
41
42 typedef thread_port_t MonoNativeThreadHandle;
43
44 #else
45
46 #include <unistd.h>
47
48 typedef pid_t MonoNativeThreadHandle;
49
50 #endif /* defined(__MACH__) */
51
52 typedef pthread_t MonoNativeThreadId;
53
54 typedef void* mono_native_thread_return_t;
55
56 #define MONO_NATIVE_THREAD_ID_TO_UINT(tid) (gsize)(tid)
57 #define MONO_UINT_TO_NATIVE_THREAD_ID(tid) (MonoNativeThreadId)(gsize)(tid)
58
59 #endif /* #ifdef HOST_WIN32 */
60
61 /*
62 THREAD_INFO_TYPE is a way to make the mono-threads module parametric - or sort of.
63 The GC using mono-threads might extend the MonoThreadInfo struct to add its own
64 data, this avoid a pointer indirection on what is on a lot of hot paths.
65
66 But extending MonoThreadInfo has de disavantage that all functions here return type
67 would require a cast, something like the following:
68
69 typedef struct {
70         MonoThreadInfo info;
71         int stuff;
72 }  MyThreadInfo;
73
74 ...
75 ((MyThreadInfo*)mono_thread_info_current ())->stuff = 1;
76
77 While porting sgen to use mono-threads, the number of casts required was too much and
78 code ended up looking horrible. So we use this cute little hack. The idea is that
79 whomever is including this header can set the expected type to be used by functions here
80 and reduce the number of casts drastically.
81
82 */
83 #ifndef THREAD_INFO_TYPE
84 #define THREAD_INFO_TYPE MonoThreadInfo
85 #endif
86
87 /* Mono Threads internal configuration knows*/
88
89 /* Logging - enable them below if you need specific logging for the category you need */
90 #define MOSTLY_ASYNC_SAFE_PRINTF(...) do { \
91         char __buff[1024];      __buff [0] = '\0'; \
92         g_snprintf (__buff, sizeof (__buff), __VA_ARGS__);      \
93         write (1, __buff, strlen (__buff));     \
94 } while (0)
95
96
97 #if 1
98 #define THREADS_DEBUG(...)
99 #else
100 #define THREADS_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
101 #endif
102
103 #if 1
104 #define THREADS_STW_DEBUG(...)
105 #else
106 #define THREADS_STW_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
107 #endif
108
109 #if 1
110 #define THREADS_SUSPEND_DEBUG(...)
111 #else
112 #define THREADS_SUSPEND_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
113 #endif
114
115 #if 1
116 #define THREADS_STATE_MACHINE_DEBUG(...)
117 #else
118 #define THREADS_STATE_MACHINE_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
119 #endif
120
121 #if 1
122 #define THREADS_INTERRUPT_DEBUG(...)
123 #else
124 #define THREADS_INTERRUPT_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
125 #endif
126
127 /* If this is defined, use the signals backed on Mach. Debug only as signals can't be made usable on OSX. */
128 // #define USE_SIGNALS_ON_MACH
129
130 #if defined (_POSIX_VERSION) || defined (__native_client__)
131 #if defined (__MACH__) && !defined (USE_SIGNALS_ON_MACH)
132 #define USE_MACH_BACKEND
133 #else
134 #define USE_POSIX_BACKEND
135 #endif
136 #elif HOST_WIN32
137 #define USE_WINDOWS_BACKEND
138 #else
139 #error "no backend support for current platform"
140 #endif /* defined (_POSIX_VERSION) || defined (__native_client__) */
141
142 enum {
143         STATE_STARTING                          = 0x00,
144         STATE_RUNNING                           = 0x01,
145         STATE_DETACHED                          = 0x02,
146
147         STATE_ASYNC_SUSPENDED                   = 0x03,
148         STATE_SELF_SUSPENDED                    = 0x04,
149         STATE_ASYNC_SUSPEND_REQUESTED   = 0x05,
150         STATE_SELF_SUSPEND_REQUESTED    = 0x06,
151         STATE_BLOCKING                                  = 0x07,
152         STATE_BLOCKING_AND_SUSPENDED    = 0x8,
153
154         STATE_MAX                                               = 0x08,
155
156         THREAD_STATE_MASK                       = 0x00FF,
157         THREAD_SUSPEND_COUNT_MASK       = 0xFF00,
158         THREAD_SUSPEND_COUNT_SHIFT      = 8,
159         THREAD_SUSPEND_COUNT_MAX        = 0xFF,
160
161         SELF_SUSPEND_STATE_INDEX = 0,
162         ASYNC_SUSPEND_STATE_INDEX = 1,
163 };
164
165 typedef struct _MonoThreadInfoInterruptToken MonoThreadInfoInterruptToken;
166
167 typedef struct {
168         MonoLinkedListSetNode node;
169         guint32 small_id; /*Used by hazard pointers */
170         MonoNativeThreadHandle native_handle; /* Valid on mach and android */
171         int thread_state;
172
173         /*Tells if this thread was created by the runtime or not.*/
174         gboolean runtime_thread;
175
176         /* Tells if this thread should be ignored or not by runtime services such as GC and profiling */
177         gboolean tools_thread;
178
179         /* Max stack bounds, all valid addresses must be between [stack_start_limit, stack_end[ */
180         void *stack_start_limit, *stack_end;
181
182         /* suspend machinery, fields protected by suspend_semaphore */
183         MonoSemType suspend_semaphore;
184         int suspend_count;
185
186         MonoSemType resume_semaphore;
187
188         /* only needed by the posix backend */
189 #if defined(USE_POSIX_BACKEND)
190         MonoSemType finish_resume_semaphore;
191         gboolean syscall_break_signal;
192         int signal;
193 #endif
194
195         gboolean suspend_can_continue;
196
197         /* This memory pool is used by coop GC to save stack data roots between GC unsafe regions */
198         GByteArray *stackdata;
199
200         /*In theory, only the posix backend needs this, but having it on mach/win32 simplifies things a lot.*/
201         MonoThreadUnwindState thread_saved_state [2]; //0 is self suspend, 1 is async suspend.
202
203         /*async call machinery, thread MUST be suspended before accessing those fields*/
204         void (*async_target)(void*);
205         void *user_data;
206
207         /*
208         If true, this thread is running a critical region of code and cannot be suspended.
209         A critical session is implicitly started when you call mono_thread_info_safe_suspend_sync
210         and is ended when you call either mono_thread_info_resume or mono_thread_info_finish_suspend.
211         */
212         gboolean inside_critical_region;
213
214         /*
215          * If TRUE, the thread is in async context. Code can use this information to avoid async-unsafe
216          * operations like locking without having to pass an 'async' parameter around.
217          */
218         gboolean is_async_context;
219
220         gboolean create_suspended;
221
222         /* Semaphore used to implement CREATE_SUSPENDED */
223         MonoCoopSem create_suspended_sem;
224
225         /*
226          * Values of TLS variables for this thread.
227          * This can be used to obtain the values of TLS variable for threads
228          * other than the current one.
229          */
230         gpointer tls [TLS_KEY_NUM];
231
232         /* IO layer handle for this thread */
233         /* Set when the thread is started, or in _wapi_thread_duplicate () */
234         HANDLE handle;
235
236         void *jit_data;
237
238         MonoThreadInfoInterruptToken *interrupt_token;
239
240         /* MonoHandleArena for coop handles */
241         gpointer handle_arena;
242 } MonoThreadInfo;
243
244 typedef struct {
245         void* (*thread_register)(THREAD_INFO_TYPE *info, void *baseaddr);
246         /*
247         This callback is called with @info still on the thread list.
248         This call is made while holding the suspend lock, so don't do callbacks.
249         SMR remains functional as its small_id has not been reclaimed.
250         */
251         void (*thread_unregister)(THREAD_INFO_TYPE *info);
252         /*
253         This callback is called right before thread_unregister. This is called
254         without any locks held so it's the place for complicated cleanup.
255
256         The thread must remain operational between this call and thread_unregister.
257         It must be possible to successfully suspend it after thread_unregister completes.
258         */
259         void (*thread_detach)(THREAD_INFO_TYPE *info);
260         void (*thread_attach)(THREAD_INFO_TYPE *info);
261         gboolean (*mono_method_is_critical) (void *method);
262         gboolean (*mono_thread_in_critical_region) (THREAD_INFO_TYPE *info);
263 } MonoThreadInfoCallbacks;
264
265 typedef struct {
266         void (*setup_async_callback) (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data);
267         gboolean (*thread_state_init_from_sigctx) (MonoThreadUnwindState *state, void *sigctx);
268         gboolean (*thread_state_init_from_handle) (MonoThreadUnwindState *tctx, MonoThreadInfo *info);
269         void (*thread_state_init) (MonoThreadUnwindState *tctx);
270 } MonoThreadInfoRuntimeCallbacks;
271
272 //Not using 0 and 1 to ensure callbacks are not returning bad data
273 typedef enum {
274         MonoResumeThread = 0x1234,
275         KeepSuspended = 0x4321,
276 } SuspendThreadResult;
277
278 typedef SuspendThreadResult (*MonoSuspendThreadCallback) (THREAD_INFO_TYPE *info, gpointer user_data);
279
280 static inline gboolean
281 mono_threads_filter_tools_threads (THREAD_INFO_TYPE *info)
282 {
283         return !((MonoThreadInfo*)info)->tools_thread;
284 }
285
286 /*
287 Requires the world to be stoped
288 */
289 #define FOREACH_THREAD(thread) \
290         MONO_LLS_FOREACH_FILTERED (mono_thread_info_list_head (), THREAD_INFO_TYPE, thread, mono_threads_filter_tools_threads)
291
292 #define FOREACH_THREAD_END \
293         MONO_LLS_FOREACH_END
294
295 /*
296 Snapshot iteration.
297 */
298 #define FOREACH_THREAD_SAFE(thread) \
299         MONO_LLS_FOREACH_FILTERED_SAFE (mono_thread_info_list_head (), THREAD_INFO_TYPE, thread, mono_threads_filter_tools_threads)
300
301 #define FOREACH_THREAD_SAFE_END \
302         MONO_LLS_FOREACH_SAFE_END
303
304 static inline MonoNativeThreadId
305 mono_thread_info_get_tid (THREAD_INFO_TYPE *info)
306 {
307         return MONO_UINT_TO_NATIVE_THREAD_ID (((MonoThreadInfo*) info)->node.key);
308 }
309
310 static inline void
311 mono_thread_info_set_tid (THREAD_INFO_TYPE *info, MonoNativeThreadId tid)
312 {
313         ((MonoThreadInfo*) info)->node.key = (uintptr_t) MONO_NATIVE_THREAD_ID_TO_UINT (tid);
314 }
315
316 /*
317  * @thread_info_size is sizeof (GcThreadInfo), a struct the GC defines to make it possible to have
318  * a single block with info from both camps. 
319  */
320 void
321 mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t thread_info_size);
322
323 void
324 mono_threads_runtime_init (MonoThreadInfoRuntimeCallbacks *callbacks);
325
326 MonoThreadInfoRuntimeCallbacks *
327 mono_threads_get_runtime_callbacks (void);
328
329 int
330 mono_thread_info_register_small_id (void);
331
332 THREAD_INFO_TYPE *
333 mono_thread_info_attach (void *baseptr);
334
335 MONO_API void
336 mono_thread_info_detach (void);
337
338 gboolean
339 mono_thread_info_is_exiting (void);
340
341 THREAD_INFO_TYPE *
342 mono_thread_info_current (void);
343
344 THREAD_INFO_TYPE*
345 mono_thread_info_current_unchecked (void);
346
347 int
348 mono_thread_info_get_small_id (void);
349
350 MonoLinkedListSet*
351 mono_thread_info_list_head (void);
352
353 THREAD_INFO_TYPE*
354 mono_thread_info_lookup (MonoNativeThreadId id);
355
356 gboolean
357 mono_thread_info_resume (MonoNativeThreadId tid);
358
359 void
360 mono_thread_info_safe_suspend_and_run (MonoNativeThreadId id, gboolean interrupt_kernel, MonoSuspendThreadCallback callback, gpointer user_data);
361
362 //XXX new API, fix the world
363 void
364 mono_thread_info_begin_self_suspend (void);
365
366 void
367 mono_thread_info_end_self_suspend (void);
368
369 //END of new API
370
371 gboolean
372 mono_thread_info_unified_management_enabled (void);
373
374 void
375 mono_thread_info_setup_async_call (THREAD_INFO_TYPE *info, void (*target_func)(void*), void *user_data);
376
377 void
378 mono_thread_info_suspend_lock (void);
379
380 void
381 mono_thread_info_suspend_unlock (void);
382
383 void
384 mono_thread_info_abort_socket_syscall_for_close (MonoNativeThreadId tid);
385
386 void
387 mono_thread_info_set_is_async_context (gboolean async_context);
388
389 gboolean
390 mono_thread_info_is_async_context (void);
391
392 void
393 mono_thread_info_get_stack_bounds (guint8 **staddr, size_t *stsize);
394
395 gboolean
396 mono_thread_info_yield (void);
397
398 gint
399 mono_thread_info_sleep (guint32 ms, gboolean *alerted);
400
401 gint
402 mono_thread_info_usleep (guint64 us);
403
404 gpointer
405 mono_thread_info_tls_get (THREAD_INFO_TYPE *info, MonoTlsKey key);
406
407 void
408 mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value);
409
410 void
411 mono_thread_info_exit (void);
412
413 HANDLE
414 mono_thread_info_open_handle (void);
415
416 void
417 mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted);
418
419 void
420 mono_thread_info_uninstall_interrupt (gboolean *interrupted);
421
422 MonoThreadInfoInterruptToken*
423 mono_thread_info_prepare_interrupt (THREAD_INFO_TYPE *info);
424
425 void
426 mono_thread_info_finish_interrupt (MonoThreadInfoInterruptToken *token);
427
428 void
429 mono_thread_info_self_interrupt (void);
430
431 void
432 mono_thread_info_clear_self_interrupt (void);
433
434 gboolean
435 mono_thread_info_is_interrupt_state (THREAD_INFO_TYPE *info);
436
437 void
438 mono_thread_info_describe_interrupt_token (THREAD_INFO_TYPE *info, GString *text);
439
440 gboolean
441 mono_thread_info_is_live (THREAD_INFO_TYPE *info);
442
443 HANDLE
444 mono_threads_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid);
445
446 int
447 mono_threads_get_max_stack_size (void);
448
449 HANDLE
450 mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
451
452 MONO_API void
453 mono_threads_attach_tools_thread (void);
454
455
456 #if !defined(HOST_WIN32)
457
458 /*Use this instead of pthread_kill */
459 int
460 mono_threads_pthread_kill (THREAD_INFO_TYPE *info, int signum);
461
462 #endif /* !defined(HOST_WIN32) */
463
464 /* Internal API between mono-threads and its backends. */
465
466 /* Backend functions - a backend must implement all of the following */
467 /*
468 This is called very early in the runtime, it cannot access any runtime facilities.
469
470 */
471 void mono_threads_init_platform (void); //ok
472
473 void mono_threads_init_coop (void);
474
475 void mono_threads_init_abort_syscall (void);
476
477 /*
478 This begins async suspend. This function must do the following:
479
480 -Ensure the target will EINTR any syscalls if @interrupt_kernel is true
481 -Call mono_threads_transition_finish_async_suspend as part of its async suspend.
482 -Register the thread for pending suspend with mono_threads_add_to_pending_operation_set if needed.
483
484 If begin suspend fails the thread must be left uninterrupted and resumed.
485 */
486 gboolean mono_threads_core_begin_async_suspend (THREAD_INFO_TYPE *info, gboolean interrupt_kernel);
487
488 /*
489 This verifies the outcome of an async suspend operation.
490
491 Some targets, such as posix, verify suspend results assynchronously. Suspend results must be
492 available (in a non blocking way) after mono_threads_wait_pending_operations completes.
493 */
494 gboolean mono_threads_core_check_suspend_result (THREAD_INFO_TYPE *info);
495
496 /*
497 This begins async resume. This function must do the following:
498
499 - Install an async target if one was requested.
500 - Notify the target to resume.
501 - Register the thread for pending ack with mono_threads_add_to_pending_operation_set if needed.
502 */
503 gboolean mono_threads_core_begin_async_resume (THREAD_INFO_TYPE *info);
504
505 void mono_threads_platform_register (THREAD_INFO_TYPE *info); //ok
506 void mono_threads_platform_free (THREAD_INFO_TYPE *info);
507 void mono_threads_core_abort_syscall (THREAD_INFO_TYPE *info);
508 gboolean mono_threads_core_needs_abort_syscall (void);
509 HANDLE mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid);
510 void mono_threads_core_resume_created (THREAD_INFO_TYPE *info, MonoNativeThreadId tid);
511 void mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize);
512 gboolean mono_threads_core_yield (void);
513 void mono_threads_core_exit (int exit_code);
514 void mono_threads_core_unregister (THREAD_INFO_TYPE *info);
515 HANDLE mono_threads_core_open_handle (void);
516 HANDLE mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
517
518 void mono_threads_coop_begin_global_suspend (void);
519 void mono_threads_coop_end_global_suspend (void);
520
521 MONO_API MonoNativeThreadId
522 mono_native_thread_id_get (void);
523
524 gboolean
525 mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2);
526
527 gboolean
528 mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg);
529
530 MONO_API void
531 mono_native_thread_set_name (MonoNativeThreadId tid, const char *name);
532
533 /*Mach specific internals */
534 void mono_threads_init_dead_letter (void);
535 void mono_threads_install_dead_letter (void);
536
537 /* mono-threads internal API used by the backends. */
538 /*
539 This tells the suspend initiator that we completed suspend and will now be waiting for resume.
540 */
541 void mono_threads_notify_initiator_of_suspend (THREAD_INFO_TYPE* info);
542 /*
543 This tells the resume initiator that we completed resume duties and will return to runnable state.
544 */
545 void mono_threads_notify_initiator_of_resume (THREAD_INFO_TYPE* info);
546
547 /*
548 This tells the resume initiator that we completed abort duties and will return to previous state.
549 */
550 void mono_threads_notify_initiator_of_abort (THREAD_INFO_TYPE* info);
551
552 /* Thread state machine functions */
553
554 typedef enum {
555         ResumeError,
556         ResumeOk,
557         ResumeInitSelfResume,
558         ResumeInitAsyncResume,
559         ResumeInitBlockingResume,
560 } MonoResumeResult;
561
562 typedef enum {
563         SelfSuspendResumed,
564         SelfSuspendWait,
565         SelfSuspendNotifyAndWait,
566 } MonoSelfSupendResult;
567
568 typedef enum {
569         AsyncSuspendAlreadySuspended,
570         AsyncSuspendWait,
571         AsyncSuspendInitSuspend,
572         AsyncSuspendBlocking,
573 } MonoRequestAsyncSuspendResult;
574
575 typedef enum {
576         DoBlockingContinue, //in blocking mode, continue
577         DoBlockingPollAndRetry, //async suspend raced blocking and won, pool and retry
578 } MonoDoBlockingResult;
579
580 typedef enum {
581         DoneBlockingOk, //exited blocking fine
582         DoneBlockingWait, //thread should end suspended
583 } MonoDoneBlockingResult;
584
585
586 typedef enum {
587         AbortBlockingIgnore, //Ignore
588         AbortBlockingIgnoreAndPoll, //Ignore and poll
589         AbortBlockingOk, //Abort worked
590         AbortBlockingWait, //Abort worked, but should wait for resume
591 } MonoAbortBlockingResult;
592
593
594 void mono_threads_transition_attach (THREAD_INFO_TYPE* info);
595 gboolean mono_threads_transition_detach (THREAD_INFO_TYPE *info);
596 void mono_threads_transition_request_self_suspension (THREAD_INFO_TYPE *info);
597 MonoRequestAsyncSuspendResult mono_threads_transition_request_async_suspension (THREAD_INFO_TYPE *info);
598 MonoSelfSupendResult mono_threads_transition_state_poll (THREAD_INFO_TYPE *info);
599 MonoResumeResult mono_threads_transition_request_resume (THREAD_INFO_TYPE* info);
600 gboolean mono_threads_transition_finish_async_suspend (THREAD_INFO_TYPE* info);
601 MonoDoBlockingResult mono_threads_transition_do_blocking (THREAD_INFO_TYPE* info);
602 MonoDoneBlockingResult mono_threads_transition_done_blocking (THREAD_INFO_TYPE* info);
603 MonoAbortBlockingResult mono_threads_transition_abort_blocking (THREAD_INFO_TYPE* info);
604
605 MonoThreadUnwindState* mono_thread_info_get_suspend_state (THREAD_INFO_TYPE *info);
606
607 gpointer
608 mono_threads_enter_gc_unsafe_region_cookie (void);
609
610
611 void mono_thread_info_wait_for_resume (THREAD_INFO_TYPE *info);
612 /* Advanced suspend API, used for suspending multiple threads as once. */
613 gboolean mono_thread_info_is_running (THREAD_INFO_TYPE *info);
614 gboolean mono_thread_info_is_live (THREAD_INFO_TYPE *info);
615 int mono_thread_info_suspend_count (THREAD_INFO_TYPE *info);
616 int mono_thread_info_current_state (THREAD_INFO_TYPE *info);
617 const char* mono_thread_state_name (int state);
618
619 gboolean mono_thread_info_in_critical_location (THREAD_INFO_TYPE *info);
620 gboolean mono_thread_info_begin_suspend (THREAD_INFO_TYPE *info);
621 gboolean mono_thread_info_begin_resume (THREAD_INFO_TYPE *info);
622
623 void mono_threads_add_to_pending_operation_set (THREAD_INFO_TYPE* info); //XXX rename to something to reflect the fact that this is used for both suspend and resume
624 gboolean mono_threads_wait_pending_operations (void);
625 void mono_threads_begin_global_suspend (void);
626 void mono_threads_end_global_suspend (void);
627
628 gboolean
629 mono_thread_info_is_current (THREAD_INFO_TYPE *info);
630
631 #endif /* __MONO_THREADS_H__ */