[cxx] externC for some icalls, for wasm and ios. (#17444)
[mono-project.git] / mono / metadata / threads-types.h
blob909ad4ffb3c800e761ad0ff6218a04a437e6770b
1 /**
2 * \file
3 * Generic thread typedef support (includes system-specific files)
5 * Author:
6 * Dick Porter (dick@ximian.com)
8 * (C) 2001 Ximian, Inc
9 * (C) Copyright 2002-2006 Novell, Inc
10 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
13 #ifndef _MONO_METADATA_THREADS_TYPES_H_
14 #define _MONO_METADATA_THREADS_TYPES_H_
16 #include <glib.h>
18 #include <mono/utils/mono-forward-internal.h>
19 #include <mono/metadata/object.h>
20 #include "mono/metadata/handle.h"
21 #include "mono/utils/mono-compiler.h"
22 #include "mono/utils/mono-membar.h"
23 #include "mono/utils/mono-threads.h"
24 #include "mono/metadata/class-internals.h"
25 #include <mono/metadata/icalls.h>
27 /* This is a copy of System.Threading.ThreadState */
28 typedef enum {
29 ThreadState_Running = 0x00000000,
30 ThreadState_SuspendRequested = 0x00000002,
31 ThreadState_Background = 0x00000004,
32 ThreadState_Unstarted = 0x00000008,
33 ThreadState_Stopped = 0x00000010,
34 ThreadState_WaitSleepJoin = 0x00000020,
35 ThreadState_Suspended = 0x00000040,
36 ThreadState_AbortRequested = 0x00000080,
37 ThreadState_Aborted = 0x00000100
38 } MonoThreadState;
40 G_ENUM_FUNCTIONS (MonoThreadState)
42 /* This is a copy of System.Threading.ApartmentState */
43 typedef enum {
44 ThreadApartmentState_STA = 0x00000000,
45 ThreadApartmentState_MTA = 0x00000001,
46 ThreadApartmentState_Unknown = 0x00000002
47 } MonoThreadApartmentState;
49 typedef enum {
50 // These values match System.Threading.ThreadPriority.
51 // These values match System.Diagnostics.ThreadPriorityLevel and Windows, but are offset by 2.
52 MONO_THREAD_PRIORITY_LOWEST = 0,
53 MONO_THREAD_PRIORITY_BELOW_NORMAL = 1,
54 MONO_THREAD_PRIORITY_NORMAL = 2,
55 MONO_THREAD_PRIORITY_ABOVE_NORMAL = 3,
56 MONO_THREAD_PRIORITY_HIGHEST = 4,
57 } MonoThreadPriority;
59 #define SPECIAL_STATIC_NONE 0
60 #define SPECIAL_STATIC_THREAD 1
61 #define SPECIAL_STATIC_CONTEXT 2
63 /* It's safe to access System.Threading.InternalThread from native code via a
64 * raw pointer because all instances should be pinned. But for uniformity of
65 * icall wrapping, let's declare a MonoInternalThreadHandle anyway.
67 TYPED_HANDLE_DECL (MonoInternalThread);
69 typedef void (*MonoThreadCleanupFunc) (MonoNativeThreadId tid);
70 /* INFO has type MonoThreadInfo* */
71 typedef void (*MonoThreadNotifyPendingExcFunc) (gpointer info);
73 void
74 mono_thread_callbacks_init (void);
76 typedef enum {
77 MONO_THREAD_CREATE_FLAGS_NONE = 0x0,
78 MONO_THREAD_CREATE_FLAGS_THREADPOOL = 0x1,
79 MONO_THREAD_CREATE_FLAGS_DEBUGGER = 0x2,
80 MONO_THREAD_CREATE_FLAGS_FORCE_CREATE = 0x4,
81 MONO_THREAD_CREATE_FLAGS_SMALL_STACK = 0x8,
82 } MonoThreadCreateFlags;
84 // FIXME func should be MonoThreadStart and remove the template
85 MonoInternalThread*
86 mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error);
88 #ifdef __cplusplus
89 template <typename T>
90 inline MonoInternalThread*
91 mono_thread_create_internal (MonoDomain *domain, T func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error)
93 return mono_thread_create_internal(domain, (gpointer)func, arg, flags, error);
95 #endif
97 MonoInternalThreadHandle
98 mono_thread_create_internal_handle (MonoDomain *domain, gpointer func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error);
100 #ifdef __cplusplus
101 template <typename T>
102 inline MonoInternalThreadHandle
103 mono_thread_create_internal_handle (MonoDomain *domain, T func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error)
105 return mono_thread_create_internal_handle(domain, (gpointer)func, arg, flags, error);
107 #endif
109 /* Data owned by a MonoInternalThread that must live until both the finalizer
110 * for MonoInternalThread has run, and the underlying machine thread has
111 * detached.
113 * Normally a thread is first detached and then the InternalThread object is
114 * finalized and collected. However during shutdown, when the root domain is
115 * finalized, all the InternalThread objects are finalized first and the
116 * machine threads are detached later.
118 typedef struct {
119 MonoRefCount ref;
120 MonoCoopMutex *synch_cs;
121 } MonoLongLivedThreadData;
123 void mono_threads_install_cleanup (MonoThreadCleanupFunc func);
125 ICALL_EXPORT
126 void ves_icall_System_Threading_Thread_SetName_internal (MonoInternalThread *this_obj, MonoString *name);
128 ICALL_EXPORT
129 MonoObject* ves_icall_System_Threading_Thread_GetCachedCurrentCulture (MonoInternalThread *this_obj);
131 ICALL_EXPORT
132 void ves_icall_System_Threading_Thread_SetCachedCurrentCulture (MonoThread *this_obj, MonoObject *culture);
134 ICALL_EXPORT
135 MonoObject* ves_icall_System_Threading_Thread_GetCachedCurrentUICulture (MonoInternalThread *this_obj);
137 ICALL_EXPORT
138 void ves_icall_System_Threading_Thread_SetCachedCurrentUICulture (MonoThread *this_obj, MonoObject *culture);
140 ICALL_EXPORT
141 gint32 ves_icall_System_Threading_Interlocked_Increment_Int(gint32 *location);
143 ICALL_EXPORT
144 gint64 ves_icall_System_Threading_Interlocked_Increment_Long(gint64 *location);
146 ICALL_EXPORT
147 gint32 ves_icall_System_Threading_Interlocked_Decrement_Int(gint32 *location);
149 ICALL_EXPORT
150 gint64 ves_icall_System_Threading_Interlocked_Decrement_Long(gint64 * location);
152 ICALL_EXPORT
153 gint32 ves_icall_System_Threading_Interlocked_Exchange_Int(gint32 *location, gint32 value);
155 ICALL_EXPORT
156 gint64 ves_icall_System_Threading_Interlocked_Exchange_Long(gint64 *location, gint64 value);
158 ICALL_EXPORT
159 void ves_icall_System_Threading_Interlocked_Exchange_Object (MonoObject *volatile*location, MonoObject *volatile*value, MonoObject *volatile*res);
161 ICALL_EXPORT
162 gpointer ves_icall_System_Threading_Interlocked_Exchange_IntPtr(gpointer *location, gpointer value);
164 ICALL_EXPORT
165 gfloat ves_icall_System_Threading_Interlocked_Exchange_Single(gfloat *location, gfloat value);
167 ICALL_EXPORT
168 gdouble ves_icall_System_Threading_Interlocked_Exchange_Double(gdouble *location, gdouble value);
170 ICALL_EXPORT
171 gint32 ves_icall_System_Threading_Interlocked_CompareExchange_Int(gint32 *location, gint32 value, gint32 comparand);
173 ICALL_EXPORT
174 gint32 ves_icall_System_Threading_Interlocked_CompareExchange_Int_Success(gint32 *location, gint32 value, gint32 comparand, MonoBoolean *success);
176 ICALL_EXPORT
177 gint64 ves_icall_System_Threading_Interlocked_CompareExchange_Long(gint64 *location, gint64 value, gint64 comparand);
179 ICALL_EXPORT
180 void ves_icall_System_Threading_Interlocked_CompareExchange_Object (MonoObject *volatile*location, MonoObject *volatile*value, MonoObject *volatile*comparand, MonoObject *volatile*res);
182 ICALL_EXPORT
183 gpointer ves_icall_System_Threading_Interlocked_CompareExchange_IntPtr(gpointer *location, gpointer value, gpointer comparand);
185 ICALL_EXPORT
186 gfloat ves_icall_System_Threading_Interlocked_CompareExchange_Single(gfloat *location, gfloat value, gfloat comparand);
188 ICALL_EXPORT
189 gdouble ves_icall_System_Threading_Interlocked_CompareExchange_Double(gdouble *location, gdouble value, gdouble comparand);
191 ICALL_EXPORT
192 void ves_icall_System_Threading_Interlocked_CompareExchange_T (MonoObject *volatile*location, MonoObject *volatile*value, MonoObject *volatile*comparand, MonoObject *volatile*res);
194 ICALL_EXPORT
195 void ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject *volatile*location, MonoObject *volatile*value, MonoObject *volatile*res);
197 ICALL_EXPORT
198 gint32 ves_icall_System_Threading_Interlocked_Add_Int(gint32 *location, gint32 value);
200 ICALL_EXPORT
201 gint64 ves_icall_System_Threading_Interlocked_Add_Long(gint64 *location, gint64 value);
203 ICALL_EXPORT
204 gint64 ves_icall_System_Threading_Interlocked_Read_Long(gint64 *location);
206 ICALL_EXPORT
207 gint32 ves_icall_System_Threading_Interlocked_Increment_Int(gint32 *location);
209 ICALL_EXPORT
210 gint64 ves_icall_System_Threading_Interlocked_Increment_Long(gint64 *location);
212 ICALL_EXPORT
213 gint32 ves_icall_System_Threading_Interlocked_Decrement_Int(gint32 *location);
215 ICALL_EXPORT
216 gint64 ves_icall_System_Threading_Interlocked_Decrement_Long(gint64 * location);
218 ICALL_EXPORT
219 void ves_icall_System_Threading_Interlocked_MemoryBarrierProcessWide (void);
221 ICALL_EXPORT
222 gint8 ves_icall_System_Threading_Thread_VolatileRead1 (void *ptr);
224 ICALL_EXPORT
225 gint16 ves_icall_System_Threading_Thread_VolatileRead2 (void *ptr);
227 ICALL_EXPORT
228 gint32 ves_icall_System_Threading_Thread_VolatileRead4 (void *ptr);
230 ICALL_EXPORT
231 gint64 ves_icall_System_Threading_Thread_VolatileRead8 (void *ptr);
233 ICALL_EXPORT
234 void * ves_icall_System_Threading_Thread_VolatileReadIntPtr (void *ptr);
236 ICALL_EXPORT
237 void * ves_icall_System_Threading_Thread_VolatileReadObject (void *ptr);
239 ICALL_EXPORT
240 double ves_icall_System_Threading_Thread_VolatileReadDouble (void *ptr);
242 ICALL_EXPORT
243 float ves_icall_System_Threading_Thread_VolatileReadFloat (void *ptr);
245 ICALL_EXPORT
246 void ves_icall_System_Threading_Thread_VolatileWrite1 (void *ptr, gint8);
248 ICALL_EXPORT
249 void ves_icall_System_Threading_Thread_VolatileWrite2 (void *ptr, gint16);
251 ICALL_EXPORT
252 void ves_icall_System_Threading_Thread_VolatileWrite4 (void *ptr, gint32);
254 ICALL_EXPORT
255 void ves_icall_System_Threading_Thread_VolatileWrite8 (void *ptr, gint64);
257 ICALL_EXPORT
258 void ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void *ptr, void *);
260 ICALL_EXPORT
261 void ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr, MonoObject *);
263 ICALL_EXPORT
264 void ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr, float);
266 ICALL_EXPORT
267 void ves_icall_System_Threading_Thread_VolatileWriteDouble (void *ptr, double);
269 ICALL_EXPORT
270 gint64 ves_icall_System_Threading_Volatile_Read8 (void *ptr);
272 ICALL_EXPORT
273 guint64 ves_icall_System_Threading_Volatile_ReadU8 (void *ptr);
275 ICALL_EXPORT
276 double ves_icall_System_Threading_Volatile_ReadDouble (void *ptr);
278 ICALL_EXPORT
279 void ves_icall_System_Threading_Volatile_Write8 (void *ptr, gint64);
281 ICALL_EXPORT
282 void ves_icall_System_Threading_Volatile_WriteU8 (void *ptr, guint64);
284 ICALL_EXPORT
285 void ves_icall_System_Threading_Volatile_WriteDouble (void *ptr, double);
287 ICALL_EXPORT
288 void ves_icall_System_Threading_Thread_MemoryBarrier (void);
290 void
291 mono_threads_register_app_context (MonoAppContextHandle ctx, MonoError *error);
292 void
293 mono_threads_release_app_context (MonoAppContext* ctx, MonoError *error);
295 MONO_PROFILER_API MonoInternalThread *mono_thread_internal_current (void);
297 MonoInternalThreadHandle
298 mono_thread_internal_current_handle (void);
300 void mono_thread_internal_abort (MonoInternalThread *thread, gboolean appdomain_unload);
301 void mono_thread_internal_suspend_for_shutdown (MonoInternalThread *thread);
303 gboolean mono_thread_internal_has_appdomain_ref (MonoInternalThread *thread, MonoDomain *domain);
305 void mono_thread_internal_reset_abort (MonoInternalThread *thread);
307 void mono_thread_internal_unhandled_exception (MonoObject* exc);
309 void mono_alloc_special_static_data_free (GHashTable *special_static_fields);
310 gboolean mono_thread_current_check_pending_interrupt (void);
312 void mono_thread_set_state (MonoInternalThread *thread, MonoThreadState state);
313 void mono_thread_clr_state (MonoInternalThread *thread, MonoThreadState state);
314 gboolean mono_thread_test_state (MonoInternalThread *thread, MonoThreadState test);
315 gboolean mono_thread_test_and_set_state (MonoInternalThread *thread, MonoThreadState test, MonoThreadState set);
316 void mono_thread_clear_and_set_state (MonoInternalThread *thread, MonoThreadState clear, MonoThreadState set);
318 void mono_thread_init_apartment_state (void);
319 void mono_thread_cleanup_apartment_state (void);
321 void mono_threads_set_shutting_down (void);
323 MONO_API MonoException* mono_thread_get_undeniable_exception (void);
325 ICALL_EXPORT
326 void ves_icall_thread_finish_async_abort (void);
328 #if HOST_WIN32
330 void
331 mono_thread_set_name_windows (HANDLE thread_handle, PCWSTR thread_name);
333 #define MONO_THREAD_NAME_WINDOWS_CONSTANT(x) L ## x
335 #else
337 #define mono_thread_set_name_windows(thread_handle, thread_name) /* nothing */
339 #define MONO_THREAD_NAME_WINDOWS_CONSTANT(x) NULL
341 #endif
343 typedef enum {
344 MonoSetThreadNameFlag_None = 0x0000,
345 MonoSetThreadNameFlag_Permanent = 0x0001,
346 MonoSetThreadNameFlag_Reset = 0x0002,
347 MonoSetThreadNameFlag_Constant = 0x0004,
348 } MonoSetThreadNameFlags;
350 G_ENUM_FUNCTIONS (MonoSetThreadNameFlags)
352 MONO_PROFILER_API
353 gsize
354 mono_thread_set_name (MonoInternalThread *thread,
355 const char* name8, size_t name8_length, const gunichar2* name16,
356 MonoSetThreadNameFlags flags, MonoError *error);
358 #define mono_thread_set_name_constant_ignore_error(thread, name, flags) \
359 mono_thread_set_name ((thread), name, G_N_ELEMENTS (name) - 1, \
360 MONO_THREAD_NAME_WINDOWS_CONSTANT (name), \
361 (flags) | MonoSetThreadNameFlag_Constant, NULL)
363 #ifndef ENABLE_NETCORE
364 void mono_thread_suspend_all_other_threads (void);
365 #endif
366 gboolean mono_threads_abort_appdomain_threads (MonoDomain *domain, int timeout);
368 void mono_thread_push_appdomain_ref (MonoDomain *domain);
369 void mono_thread_pop_appdomain_ref (void);
370 gboolean mono_thread_has_appdomain_ref (MonoThread *thread, MonoDomain *domain);
372 gboolean mono_thread_interruption_requested (void);
374 ICALL_EXTERN_C
375 MonoException*
376 mono_thread_interruption_checkpoint (void);
378 gboolean
379 mono_thread_interruption_checkpoint_bool (void);
381 void
382 mono_thread_interruption_checkpoint_void (void);
384 MonoExceptionHandle
385 mono_thread_interruption_checkpoint_handle (void);
387 ICALL_EXTERN_C
388 MonoException* mono_thread_force_interruption_checkpoint_noraise (void);
391 * mono_thread_interruption_request_flag:
393 * A flag that will be non-zero if an interruption has
394 * been requested for a thread. The thread to interrupt may not be the current
395 * thread, so an additional call to mono_thread_interruption_requested () or
396 * mono_thread_interruption_checkpoint () is always needed if the flag is not
397 * zero.
399 extern gint32 mono_thread_interruption_request_flag;
401 uint32_t mono_alloc_special_static_data (uint32_t static_type, uint32_t size, uint32_t align, uintptr_t *bitmap, int numbits);
403 ICALL_EXTERN_C
404 void* mono_get_special_static_data (uint32_t offset);
406 gpointer mono_get_special_static_data_for_thread (MonoInternalThread *thread, guint32 offset);
408 void
409 mono_thread_resume_interruption (gboolean exec);
410 void mono_threads_perform_thread_dump (void);
412 // FIXME Correct the type of func and remove the template.
413 gboolean
414 mono_thread_create_checked (MonoDomain *domain, gpointer func, gpointer arg, MonoError *error);
416 #ifdef __cplusplus
417 template <typename T>
418 inline gboolean
419 mono_thread_create_checked (MonoDomain *domain, T func, gpointer arg, MonoError *error)
421 return mono_thread_create_checked (domain, (gpointer)func, arg, error);
423 #endif
425 void mono_threads_add_joinable_runtime_thread (MonoThreadInfo *thread_info);
426 void mono_threads_add_joinable_thread (gpointer tid);
427 void mono_threads_join_threads (void);
428 void mono_thread_join (gpointer tid);
430 MONO_API gpointer
431 mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy);
433 MONO_API void
434 mono_threads_detach_coop (gpointer cookie, gpointer *dummy);
436 MonoDomain*
437 mono_threads_attach_coop_internal (MonoDomain *domain, gpointer *cookie, MonoStackData *stackdata);
439 void
440 mono_threads_detach_coop_internal (MonoDomain *orig_domain, gpointer cookie, MonoStackData *stackdata);
442 void mono_threads_begin_abort_protected_block (void);
443 gboolean mono_threads_end_abort_protected_block (void);
445 gboolean
446 mono_thread_internal_current_is_attached (void);
448 void
449 mono_thread_internal_describe (MonoInternalThread *internal, GString *str);
451 gboolean
452 mono_thread_internal_is_current (MonoInternalThread *internal);
454 gboolean
455 mono_threads_is_current_thread_in_protected_block (void);
457 gboolean
458 mono_threads_is_critical_method (MonoMethod *method);
460 gpointer
461 mono_threads_enter_gc_unsafe_region_unbalanced_internal (MonoStackData *stackdata);
463 void
464 mono_threads_exit_gc_unsafe_region_unbalanced_internal (gpointer cookie, MonoStackData *stackdata);
466 gpointer
467 mono_threads_enter_gc_safe_region_unbalanced_internal (MonoStackData *stackdata);
469 void
470 mono_threads_exit_gc_safe_region_unbalanced_internal (gpointer cookie, MonoStackData *stackdata);
472 // Set directory to store thread dumps captured by SIGQUIT
473 void
474 mono_set_thread_dump_dir(gchar* dir);
476 MONO_COLD void
477 mono_set_pending_exception_handle (MonoExceptionHandle exc);
479 #define MONO_MAX_SUMMARY_NAME_LEN 140
480 #define MONO_MAX_THREAD_NAME_LEN 140
481 #define MONO_MAX_SUMMARY_THREADS 32
482 #define MONO_MAX_SUMMARY_FRAMES 80
483 #define MONO_MAX_SUMMARY_EXCEPTIONS 15
485 typedef struct {
486 gboolean is_managed;
487 char str_descr [MONO_MAX_SUMMARY_NAME_LEN];
488 struct {
489 int token;
490 int il_offset;
491 int native_offset;
492 const char *guid;
494 #ifndef MONO_PRIVATE_CRASHES
495 // We use ifdef to make it a compile-time error to store this
496 // symbolicated string on release builds
497 const char *name;
498 #endif
499 const char *filename;
500 guint32 image_size;
501 guint32 time_date_stamp;
502 } managed_data;
503 struct {
504 intptr_t ip;
505 gint32 offset;
506 char module [MONO_MAX_SUMMARY_NAME_LEN];
507 gboolean is_trampoline;
508 gboolean has_name;
509 } unmanaged_data;
510 } MonoFrameSummary;
512 typedef struct {
513 MonoClass *managed_exc_type;
515 int num_managed_frames;
516 MonoFrameSummary managed_frames [MONO_MAX_SUMMARY_FRAMES];
517 } MonoExcSummary;
519 typedef struct {
520 guint64 offset_free_hash;
521 guint64 offset_rich_hash;
522 } MonoStackHash;
524 typedef struct {
525 gboolean done; // Needed because cond wait can have spurious wakeups
526 MonoSemType done_wait; // Readers are finished with this
528 // For managed stack walking
530 MonoDomain *domain;
531 MonoJitTlsData *jit_tls;
532 MonoLMF *lmf;
534 // Emitted attributes
536 gboolean is_managed;
538 char name [MONO_MAX_THREAD_NAME_LEN];
540 intptr_t info_addr;
541 intptr_t native_thread_id;
543 // Print reason we don't have a complete
544 // managed trace
545 const char *error_msg;
547 int num_managed_frames;
548 MonoFrameSummary managed_frames [MONO_MAX_SUMMARY_FRAMES];
550 int num_unmanaged_frames;
551 MonoFrameSummary unmanaged_frames [MONO_MAX_SUMMARY_FRAMES];
553 int num_exceptions;
554 MonoExcSummary exceptions [MONO_MAX_SUMMARY_EXCEPTIONS];
556 MonoStackHash hashes;
558 MonoContext *ctx;
559 MonoContext ctx_mem;
560 } MonoThreadSummary;
562 void
563 mono_threads_summarize_init (void);
565 gboolean
566 mono_threads_summarize (MonoContext *ctx, gchar **out, MonoStackHash *hashes, gboolean silent, gboolean signal_handler_controller, gchar *mem, size_t provided_size);
568 gboolean
569 mono_threads_summarize_execute (MonoContext *ctx, gchar **out, MonoStackHash *hashes, gboolean silent, gchar *mem, size_t provided_size);
571 gboolean
572 mono_threads_summarize_one (MonoThreadSummary *out, MonoContext *ctx);
574 #endif /* _MONO_METADATA_THREADS_TYPES_H_ */