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