X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-threads.h;h=e86dc5068267095ecbbd5637555bb3be5d5341a4;hb=a0173a7e76ad48889ade46116e516731b170e7c5;hp=43dd376fe8b77ae70c2245222c472ff8d6a83325;hpb=7899d2f452fadddaa6e505bd89690aaa67d56b40;p=mono.git diff --git a/mono/utils/mono-threads.h b/mono/utils/mono-threads.h index 43dd376fe8b..e86dc506826 100644 --- a/mono/utils/mono-threads.h +++ b/mono/utils/mono-threads.h @@ -13,9 +13,8 @@ #include #include #include - -/* FIXME used for CRITICAL_SECTION replace with mono-mutex */ -#include +#include +#include #include @@ -28,6 +27,8 @@ typedef HANDLE MonoNativeThreadHandle; /* unused */ typedef DWORD mono_native_thread_return_t; +#define MONO_NATIVE_THREAD_ID_TO_UINT(tid) (tid) + #else #include @@ -49,6 +50,8 @@ typedef pthread_t MonoNativeThreadId; typedef void* mono_native_thread_return_t; +#define MONO_NATIVE_THREAD_ID_TO_UINT(tid) (gsize)(tid) + #endif /* #ifdef HOST_WIN32 */ /* @@ -78,10 +81,10 @@ and reduce the number of casts drastically. #endif enum { - STATE_STARTING = 0x01, - STATE_RUNNING = 0x02, - STATE_SHUTTING_DOWN = 0x03, - STATE_DEAD = 0x04, + STATE_STARTING = 0x00, + STATE_RUNNING = 0x01, + STATE_SHUTTING_DOWN = 0x02, + STATE_DEAD = 0x03, RUN_STATE_MASK = 0x0F, STATE_SUSPENDED = 0x10, @@ -89,8 +92,8 @@ enum { SUSPEND_STATE_MASK = 0xF0, }; -#define mono_thread_info_run_state(info) ((info)->thread_state & RUN_STATE_MASK) -#define mono_thread_info_suspend_state(info) ((info)->thread_state & SUSPEND_STATE_MASK) +#define mono_thread_info_run_state(info) (((MonoThreadInfo*)info)->thread_state & RUN_STATE_MASK) +#define mono_thread_info_suspend_state(info) (((MonoThreadInfo*)info)->thread_state & SUSPEND_STATE_MASK) typedef struct { MonoLinkedListSetNode node; @@ -98,8 +101,11 @@ typedef struct { MonoNativeThreadHandle native_handle; /* Valid on mach and android */ int thread_state; - /* suspend machinery, fields protected by the suspend_lock */ - CRITICAL_SECTION suspend_lock; + /*Tells if this thread was created by the runtime or not.*/ + gboolean runtime_thread; + + /* suspend machinery, fields protected by suspend_semaphore */ + MonoSemType suspend_semaphore; int suspend_count; MonoSemType finish_resume_semaphore; @@ -107,7 +113,7 @@ typedef struct { /* only needed by the posix backend */ #if (defined(_POSIX_VERSION) || defined(__native_client__)) && !defined (__MACH__) - MonoSemType suspend_semaphore; + MonoSemType begin_suspend_semaphore; gboolean syscall_break_signal; gboolean suspend_can_continue; #endif @@ -118,17 +124,56 @@ typedef struct { /*async call machinery, thread MUST be suspended before accessing those fields*/ void (*async_target)(void*); void *user_data; + + /* + If true, this thread is running a critical region of code and cannot be suspended. + A critical session is implicitly started when you call mono_thread_info_safe_suspend_sync + and is ended when you call either mono_thread_info_resume or mono_thread_info_finish_suspend. + */ + gboolean inside_critical_region; + + /* + * If TRUE, the thread is in async context. Code can use this information to avoid async-unsafe + * operations like locking without having to pass an 'async' parameter around. + */ + gboolean is_async_context; + + gboolean create_suspended; + + /* Semaphore used to implement CREATE_SUSPENDED */ + MonoSemType create_suspended_sem; + + /* + * Values of TLS variables for this thread. + * This can be used to obtain the values of TLS variable for threads + * other than the current one. + */ + gpointer tls [TLS_KEY_NUM]; + + /* IO layer handle for this thread */ + /* Set when the thread is started, or in _wapi_thread_duplicate () */ + HANDLE handle; } MonoThreadInfo; typedef struct { void* (*thread_register)(THREAD_INFO_TYPE *info, void *baseaddr); /* - This callback is called after @info is removed from the thread list. + This callback is called with @info still on the thread list. + This call is made while holding the suspend lock, so don't do callbacks. SMR remains functional as its small_id has not been reclaimed. */ void (*thread_unregister)(THREAD_INFO_TYPE *info); + /* + This callback is called right before thread_unregister. This is called + without any locks held so it's the place for complicated cleanup. + + The thread must remain operational between this call and thread_unregister. + It must be possible to successfully suspend it after thread_unregister completes. + */ + void (*thread_detach)(THREAD_INFO_TYPE *info); void (*thread_attach)(THREAD_INFO_TYPE *info); gboolean (*mono_method_is_critical) (void *method); + void (*thread_exit)(void *retval); #ifndef HOST_WIN32 int (*mono_gc_pthread_create) (pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); #endif @@ -143,13 +188,13 @@ typedef struct { /* Requires the world to be stoped */ -#define FOREACH_THREAD(thread) MONO_LLS_FOREACH (mono_thread_info_list_head (), thread, SgenThreadInfo*) +#define FOREACH_THREAD(thread) MONO_LLS_FOREACH (mono_thread_info_list_head (), thread, THREAD_INFO_TYPE*) #define END_FOREACH_THREAD MONO_LLS_END_FOREACH /* Snapshot iteration. */ -#define FOREACH_THREAD_SAFE(thread) MONO_LLS_FOREACH_SAFE (mono_thread_info_list_head (), thread, SgenThreadInfo*) +#define FOREACH_THREAD_SAFE(thread) MONO_LLS_FOREACH_SAFE (mono_thread_info_list_head (), thread, THREAD_INFO_TYPE*) #define END_FOREACH_THREAD_SAFE MONO_LLS_END_FOREACH_SAFE #define mono_thread_info_get_tid(info) ((MonoNativeThreadId)((MonoThreadInfo*)info)->node.key) @@ -178,7 +223,7 @@ THREAD_INFO_TYPE * mono_thread_info_attach (void *baseptr) MONO_INTERNAL; void -mono_thread_info_dettach (void) MONO_INTERNAL; +mono_thread_info_detach (void) MONO_INTERNAL; THREAD_INFO_TYPE * mono_thread_info_current (void) MONO_INTERNAL; @@ -189,15 +234,18 @@ mono_thread_info_get_small_id (void) MONO_INTERNAL; MonoLinkedListSet* mono_thread_info_list_head (void) MONO_INTERNAL; -MonoThreadInfo* +THREAD_INFO_TYPE* mono_thread_info_lookup (MonoNativeThreadId id) MONO_INTERNAL; -MonoThreadInfo* +THREAD_INFO_TYPE* mono_thread_info_safe_suspend_sync (MonoNativeThreadId tid, gboolean interrupt_kernel) MONO_INTERNAL; gboolean mono_thread_info_resume (MonoNativeThreadId tid) MONO_INTERNAL; +void +mono_thread_info_finish_suspend (void) MONO_INTERNAL; + void mono_thread_info_self_suspend (void) MONO_INTERNAL; @@ -205,7 +253,7 @@ gboolean mono_thread_info_new_interrupt_enabled (void) MONO_INTERNAL; void -mono_thread_info_setup_async_call (MonoThreadInfo *info, void (*target_func)(void*), void *user_data) MONO_INTERNAL; +mono_thread_info_setup_async_call (THREAD_INFO_TYPE *info, void (*target_func)(void*), void *user_data) MONO_INTERNAL; void mono_thread_info_suspend_lock (void) MONO_INTERNAL; @@ -213,19 +261,40 @@ mono_thread_info_suspend_lock (void) MONO_INTERNAL; void mono_thread_info_suspend_unlock (void) MONO_INTERNAL; -void -mono_threads_unregister_current_thread (THREAD_INFO_TYPE *info) MONO_INTERNAL; - void mono_thread_info_disable_new_interrupt (gboolean disable) MONO_INTERNAL; void mono_thread_info_abort_socket_syscall_for_close (MonoNativeThreadId tid) MONO_INTERNAL; -#if !defined(HOST_WIN32) +void +mono_thread_info_set_is_async_context (gboolean async_context) MONO_INTERNAL; -int -mono_threads_pthread_create (pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) MONO_INTERNAL; +gboolean +mono_thread_info_is_async_context (void) MONO_INTERNAL; + +void +mono_thread_info_get_stack_bounds (guint8 **staddr, size_t *stsize); + +gboolean +mono_thread_info_yield (void) MONO_INTERNAL; + +gpointer +mono_thread_info_tls_get (THREAD_INFO_TYPE *info, MonoTlsKey key); + +void +mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value); + +void +mono_thread_info_exit (void); + +HANDLE +mono_thread_info_open_handle (void); + +HANDLE +mono_threads_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid); + +#if !defined(HOST_WIN32) #if !defined(__MACH__) /*Use this instead of pthread_kill */ @@ -233,23 +302,24 @@ int mono_threads_pthread_kill (THREAD_INFO_TYPE *info, int signum) MONO_INTERNAL; #endif -#else /* !defined(HOST_WIN32) */ - -HANDLE - mono_threads_CreateThread (LPSECURITY_ATTRIBUTES attributes, SIZE_T stack_size, LPTHREAD_START_ROUTINE start_routine, LPVOID arg, DWORD creation_flags, LPDWORD thread_id); - - #endif /* !defined(HOST_WIN32) */ /* Plartform specific functions DON'T use them */ void mono_threads_init_platform (void) MONO_INTERNAL; //ok -gboolean mono_threads_core_suspend (MonoThreadInfo *info) MONO_INTERNAL; -gboolean mono_threads_core_resume (MonoThreadInfo *info) MONO_INTERNAL; -void mono_threads_platform_register (MonoThreadInfo *info) MONO_INTERNAL; //ok -void mono_threads_platform_free (MonoThreadInfo *info) MONO_INTERNAL; -void mono_threads_core_interrupt (MonoThreadInfo *info) MONO_INTERNAL; -void mono_threads_core_abort_syscall (MonoThreadInfo *info) MONO_INTERNAL; +gboolean mono_threads_core_suspend (THREAD_INFO_TYPE *info) MONO_INTERNAL; +gboolean mono_threads_core_resume (THREAD_INFO_TYPE *info) MONO_INTERNAL; +void mono_threads_platform_register (THREAD_INFO_TYPE *info) MONO_INTERNAL; //ok +void mono_threads_platform_free (THREAD_INFO_TYPE *info) MONO_INTERNAL; +void mono_threads_core_interrupt (THREAD_INFO_TYPE *info) MONO_INTERNAL; +void mono_threads_core_abort_syscall (THREAD_INFO_TYPE *info) MONO_INTERNAL; gboolean mono_threads_core_needs_abort_syscall (void) MONO_INTERNAL; +HANDLE mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid) MONO_INTERNAL; +void mono_threads_core_resume_created (THREAD_INFO_TYPE *info, MonoNativeThreadId tid) MONO_INTERNAL; +void mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize) MONO_INTERNAL; +gboolean mono_threads_core_yield (void) MONO_INTERNAL; +void mono_threads_core_exit (int exit_code) MONO_INTERNAL; +void mono_threads_core_unregister (THREAD_INFO_TYPE *info) MONO_INTERNAL; +HANDLE mono_threads_core_open_handle (void) MONO_INTERNAL; MonoNativeThreadId mono_native_thread_id_get (void) MONO_INTERNAL;