void* mono_threads_try_prepare_blocking (void* stackdata) { MonoThreadInfo *info; if (!mono_threads_is_coop_enabled ()) return NULL; ++coop_try_blocking_count; info = mono_thread_info_current_unchecked (); /* If the thread is not attached, it doesn't make sense prepare for suspend. */ if (!info || !mono_thread_info_is_live (info) || mono_thread_info_current_state (info) == STATE_BLOCKING) { THREADS_SUSPEND_DEBUG ("PREPARE-TRY-BLOCKING failed %p\n", mono_thread_info_get_tid (info)); return NULL; } copy_stack_data (info, stackdata); retry: ++coop_save_count; mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]); switch (mono_threads_transition_do_blocking (info)) { case DoBlockingContinue: break; case DoBlockingPollAndRetry: mono_threads_state_poll (); goto retry; } return info; }
gpointer mono_threads_enter_gc_unsafe_region_unbalanced_with_info (MonoThreadInfo *info, gpointer *stackdata) { if (!mono_threads_is_coop_enabled ()) return NULL; ++coop_reset_blocking_count; check_info (info, "enter", "unsafe"); copy_stack_data (info, stackdata); switch (mono_threads_transition_abort_blocking (info)) { case AbortBlockingIgnore: info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE; return NULL; case AbortBlockingIgnoreAndPoll: mono_threads_state_poll_with_info (info); return NULL; case AbortBlockingOk: info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE; break; case AbortBlockingWait: mono_thread_info_wait_for_resume (info); break; default: g_error ("Unknown thread state"); } return info; }
void* mono_threads_reset_blocking_start (void* stackdata) { MonoThreadInfo *info; if (!mono_threads_is_coop_enabled ()) return NULL; ++coop_reset_blocking_count; info = mono_thread_info_current_unchecked (); /* If the thread is not attached, it doesn't make sense prepare for suspend. */ if (!info || !mono_thread_info_is_live (info)) return NULL; copy_stack_data (info, stackdata); switch (mono_threads_transition_abort_blocking (info)) { case AbortBlockingIgnore: info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE; return NULL; case AbortBlockingIgnoreAndPoll: mono_threads_state_poll (); return NULL; case AbortBlockingOk: info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE; return info; case AbortBlockingOkAndPool: mono_threads_state_poll (); return info; default: g_error ("Unknown thread state"); } }
static gpointer mono_threads_enter_gc_safe_region_unbalanced_with_info (MonoThreadInfo *info, gpointer *stackdata) { if (!mono_threads_is_coop_enabled ()) return NULL; ++coop_do_blocking_count; check_info (info, "enter", "safe"); copy_stack_data (info, stackdata); retry: ++coop_save_count; mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]); switch (mono_threads_transition_do_blocking (info)) { case DoBlockingContinue: break; case DoBlockingPollAndRetry: mono_threads_state_poll_with_info (info); goto retry; } return info; }