3 * Generic thread typedef support (includes system-specific files)
6 * Dick Porter (dick@ximian.com)
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_
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 */
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
40 G_ENUM_FUNCTIONS (MonoThreadState
)
42 /* This is a copy of System.Threading.ApartmentState */
44 ThreadApartmentState_STA
= 0x00000000,
45 ThreadApartmentState_MTA
= 0x00000001,
46 ThreadApartmentState_Unknown
= 0x00000002
47 } MonoThreadApartmentState
;
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,
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
);
74 mono_thread_callbacks_init (void);
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
86 mono_thread_create_internal (MonoDomain
*domain
, gpointer func
, gpointer arg
, MonoThreadCreateFlags flags
, MonoError
*error
);
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
);
97 MonoInternalThreadHandle
98 mono_thread_create_internal_handle (MonoDomain
*domain
, gpointer func
, gpointer arg
, MonoThreadCreateFlags flags
, MonoError
*error
);
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
);
109 /* Data owned by a MonoInternalThread that must live until both the finalizer
110 * for MonoInternalThread has run, and the underlying machine thread has
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.
120 MonoCoopMutex
*synch_cs
;
121 } MonoLongLivedThreadData
;
123 void mono_threads_install_cleanup (MonoThreadCleanupFunc func
);
126 void ves_icall_System_Threading_Thread_SetName_internal (MonoInternalThread
*this_obj
, MonoString
*name
);
129 MonoObject
* ves_icall_System_Threading_Thread_GetCachedCurrentCulture (MonoInternalThread
*this_obj
);
132 void ves_icall_System_Threading_Thread_SetCachedCurrentCulture (MonoThread
*this_obj
, MonoObject
*culture
);
135 MonoObject
* ves_icall_System_Threading_Thread_GetCachedCurrentUICulture (MonoInternalThread
*this_obj
);
138 void ves_icall_System_Threading_Thread_SetCachedCurrentUICulture (MonoThread
*this_obj
, MonoObject
*culture
);
141 gint32
ves_icall_System_Threading_Interlocked_Increment_Int(gint32
*location
);
144 gint64
ves_icall_System_Threading_Interlocked_Increment_Long(gint64
*location
);
147 gint32
ves_icall_System_Threading_Interlocked_Decrement_Int(gint32
*location
);
150 gint64
ves_icall_System_Threading_Interlocked_Decrement_Long(gint64
* location
);
153 gint32
ves_icall_System_Threading_Interlocked_Exchange_Int(gint32
*location
, gint32 value
);
156 gint64
ves_icall_System_Threading_Interlocked_Exchange_Long(gint64
*location
, gint64 value
);
159 void ves_icall_System_Threading_Interlocked_Exchange_Object (MonoObject
*volatile*location
, MonoObject
*volatile*value
, MonoObject
*volatile*res
);
162 gpointer
ves_icall_System_Threading_Interlocked_Exchange_IntPtr(gpointer
*location
, gpointer value
);
165 gfloat
ves_icall_System_Threading_Interlocked_Exchange_Single(gfloat
*location
, gfloat value
);
168 gdouble
ves_icall_System_Threading_Interlocked_Exchange_Double(gdouble
*location
, gdouble value
);
171 gint32
ves_icall_System_Threading_Interlocked_CompareExchange_Int(gint32
*location
, gint32 value
, gint32 comparand
);
174 gint32
ves_icall_System_Threading_Interlocked_CompareExchange_Int_Success(gint32
*location
, gint32 value
, gint32 comparand
, MonoBoolean
*success
);
177 gint64
ves_icall_System_Threading_Interlocked_CompareExchange_Long(gint64
*location
, gint64 value
, gint64 comparand
);
180 void ves_icall_System_Threading_Interlocked_CompareExchange_Object (MonoObject
*volatile*location
, MonoObject
*volatile*value
, MonoObject
*volatile*comparand
, MonoObject
*volatile*res
);
183 gpointer
ves_icall_System_Threading_Interlocked_CompareExchange_IntPtr(gpointer
*location
, gpointer value
, gpointer comparand
);
186 gfloat
ves_icall_System_Threading_Interlocked_CompareExchange_Single(gfloat
*location
, gfloat value
, gfloat comparand
);
189 gdouble
ves_icall_System_Threading_Interlocked_CompareExchange_Double(gdouble
*location
, gdouble value
, gdouble comparand
);
192 void ves_icall_System_Threading_Interlocked_CompareExchange_T (MonoObject
*volatile*location
, MonoObject
*volatile*value
, MonoObject
*volatile*comparand
, MonoObject
*volatile*res
);
195 void ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject
*volatile*location
, MonoObject
*volatile*value
, MonoObject
*volatile*res
);
198 gint32
ves_icall_System_Threading_Interlocked_Add_Int(gint32
*location
, gint32 value
);
201 gint64
ves_icall_System_Threading_Interlocked_Add_Long(gint64
*location
, gint64 value
);
204 gint64
ves_icall_System_Threading_Interlocked_Read_Long(gint64
*location
);
207 gint32
ves_icall_System_Threading_Interlocked_Increment_Int(gint32
*location
);
210 gint64
ves_icall_System_Threading_Interlocked_Increment_Long(gint64
*location
);
213 gint32
ves_icall_System_Threading_Interlocked_Decrement_Int(gint32
*location
);
216 gint64
ves_icall_System_Threading_Interlocked_Decrement_Long(gint64
* location
);
219 void ves_icall_System_Threading_Interlocked_MemoryBarrierProcessWide (void);
222 gint8
ves_icall_System_Threading_Thread_VolatileRead1 (void *ptr
);
225 gint16
ves_icall_System_Threading_Thread_VolatileRead2 (void *ptr
);
228 gint32
ves_icall_System_Threading_Thread_VolatileRead4 (void *ptr
);
231 gint64
ves_icall_System_Threading_Thread_VolatileRead8 (void *ptr
);
234 void * ves_icall_System_Threading_Thread_VolatileReadIntPtr (void *ptr
);
237 void * ves_icall_System_Threading_Thread_VolatileReadObject (void *ptr
);
240 double ves_icall_System_Threading_Thread_VolatileReadDouble (void *ptr
);
243 float ves_icall_System_Threading_Thread_VolatileReadFloat (void *ptr
);
246 void ves_icall_System_Threading_Thread_VolatileWrite1 (void *ptr
, gint8
);
249 void ves_icall_System_Threading_Thread_VolatileWrite2 (void *ptr
, gint16
);
252 void ves_icall_System_Threading_Thread_VolatileWrite4 (void *ptr
, gint32
);
255 void ves_icall_System_Threading_Thread_VolatileWrite8 (void *ptr
, gint64
);
258 void ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void *ptr
, void *);
261 void ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr
, MonoObject
*);
264 void ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr
, float);
267 void ves_icall_System_Threading_Thread_VolatileWriteDouble (void *ptr
, double);
270 gint64
ves_icall_System_Threading_Volatile_Read8 (void *ptr
);
273 guint64
ves_icall_System_Threading_Volatile_ReadU8 (void *ptr
);
276 double ves_icall_System_Threading_Volatile_ReadDouble (void *ptr
);
279 void ves_icall_System_Threading_Volatile_Write8 (void *ptr
, gint64
);
282 void ves_icall_System_Threading_Volatile_WriteU8 (void *ptr
, guint64
);
285 void ves_icall_System_Threading_Volatile_WriteDouble (void *ptr
, double);
288 void ves_icall_System_Threading_Thread_MemoryBarrier (void);
291 mono_threads_register_app_context (MonoAppContextHandle ctx
, MonoError
*error
);
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);
326 void ves_icall_thread_finish_async_abort (void);
331 mono_thread_set_name_windows (HANDLE thread_handle
, PCWSTR thread_name
);
333 #define MONO_THREAD_NAME_WINDOWS_CONSTANT(x) L ## x
337 #define mono_thread_set_name_windows(thread_handle, thread_name) /* nothing */
339 #define MONO_THREAD_NAME_WINDOWS_CONSTANT(x) NULL
344 MonoSetThreadNameFlag_None
= 0x0000,
345 MonoSetThreadNameFlag_Permanent
= 0x0001,
346 MonoSetThreadNameFlag_Reset
= 0x0002,
347 MonoSetThreadNameFlag_Constant
= 0x0004,
348 } MonoSetThreadNameFlags
;
350 G_ENUM_FUNCTIONS (MonoSetThreadNameFlags
)
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);
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);
376 mono_thread_interruption_checkpoint (void);
379 mono_thread_interruption_checkpoint_bool (void);
382 mono_thread_interruption_checkpoint_void (void);
385 mono_thread_interruption_checkpoint_handle (void);
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
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
);
404 void* mono_get_special_static_data (uint32_t offset
);
406 gpointer
mono_get_special_static_data_for_thread (MonoInternalThread
*thread
, guint32 offset
);
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.
414 mono_thread_create_checked (MonoDomain
*domain
, gpointer func
, gpointer arg
, MonoError
*error
);
417 template <typename T
>
419 mono_thread_create_checked (MonoDomain
*domain
, T func
, gpointer arg
, MonoError
*error
)
421 return mono_thread_create_checked (domain
, (gpointer
)func
, arg
, error
);
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
);
431 mono_threads_attach_coop (MonoDomain
*domain
, gpointer
*dummy
);
434 mono_threads_detach_coop (gpointer cookie
, gpointer
*dummy
);
437 mono_threads_attach_coop_internal (MonoDomain
*domain
, gpointer
*cookie
, MonoStackData
*stackdata
);
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);
446 mono_thread_internal_current_is_attached (void);
449 mono_thread_internal_describe (MonoInternalThread
*internal
, GString
*str
);
452 mono_thread_internal_is_current (MonoInternalThread
*internal
);
455 mono_threads_is_current_thread_in_protected_block (void);
458 mono_threads_is_critical_method (MonoMethod
*method
);
461 mono_threads_enter_gc_unsafe_region_unbalanced_internal (MonoStackData
*stackdata
);
464 mono_threads_exit_gc_unsafe_region_unbalanced_internal (gpointer cookie
, MonoStackData
*stackdata
);
467 mono_threads_enter_gc_safe_region_unbalanced_internal (MonoStackData
*stackdata
);
470 mono_threads_exit_gc_safe_region_unbalanced_internal (gpointer cookie
, MonoStackData
*stackdata
);
472 // Set directory to store thread dumps captured by SIGQUIT
474 mono_set_thread_dump_dir(gchar
* dir
);
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
487 char str_descr
[MONO_MAX_SUMMARY_NAME_LEN
];
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
499 const char *filename
;
501 guint32 time_date_stamp
;
506 char module
[MONO_MAX_SUMMARY_NAME_LEN
];
507 gboolean is_trampoline
;
513 MonoClass
*managed_exc_type
;
515 int num_managed_frames
;
516 MonoFrameSummary managed_frames
[MONO_MAX_SUMMARY_FRAMES
];
520 guint64 offset_free_hash
;
521 guint64 offset_rich_hash
;
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
531 MonoJitTlsData
*jit_tls
;
534 // Emitted attributes
538 char name
[MONO_MAX_THREAD_NAME_LEN
];
541 intptr_t native_thread_id
;
543 // Print reason we don't have a complete
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
];
554 MonoExcSummary exceptions
[MONO_MAX_SUMMARY_EXCEPTIONS
];
556 MonoStackHash hashes
;
563 mono_threads_summarize_init (void);
566 mono_threads_summarize (MonoContext
*ctx
, gchar
**out
, MonoStackHash
*hashes
, gboolean silent
, gboolean signal_handler_controller
, gchar
*mem
, size_t provided_size
);
569 mono_threads_summarize_execute (MonoContext
*ctx
, gchar
**out
, MonoStackHash
*hashes
, gboolean silent
, gchar
*mem
, size_t provided_size
);
572 mono_threads_summarize_one (MonoThreadSummary
*out
, MonoContext
*ctx
);
574 #endif /* _MONO_METADATA_THREADS_TYPES_H_ */