mono_thread_get_tls_key ()
{
  pthread_key_t D.22542;

  D.22542 = current_object_key;
  return D.22542;
}


mono_thread_get_tls_offset ()
{
  gint32 D.22544;
  int offset;

  __asm__("	ldr	%0, 1f; b 2f; 1: .word tls_current_object(tpoff); 2:" : "=r" offset);
  D.22544 = offset;
  return D.22544;
}


mono_thread_new_init (intptr_t tid, void * stack_start, void * func)
{
  void (*<T1d76>) (intptr_t, void *, void *) mono_thread_start_cb.0;

  mono_thread_start_cb.0 = mono_thread_start_cb;
  if (mono_thread_start_cb.0 != 0B) goto <D.22547>; else goto <D.22548>;
  <D.22547>:
  mono_thread_start_cb.0 = mono_thread_start_cb;
  mono_thread_start_cb.0 (tid, stack_start, func);
  <D.22548>:
}


mono_threads_set_default_stacksize (guint32 stacksize)
{
  default_stacksize = stacksize;
}


mono_threads_get_default_stacksize ()
{
  uint32_t D.22549;

  D.22549 = default_stacksize;
  return D.22549;
}


mono_thread_create_internal (struct MonoDomain * domain, void * func, void * arg, gboolean threadpool_thread, gboolean no_detach, guint32 stack_size)
{
  struct _MonoInternalThread * * D.22551;
  guint32 (*<T3bc6>) (void *) func.1;
  struct MonoInternalThread * D.22555;
  const char * D.22556;
  struct MonoClass * D.22559;
  struct MonoClassField * D.22560;
  unsigned int D.22561;
  sizetype D.22562;
  sizetype D.22563;
  struct MonoClassField * D.22564;
  int D.22565;
  _Bool D.22566;
  long int D.22567;
  long int D.22568;
  struct MonoThread * thread;
  struct MonoInternalThread * internal;
  struct StartInfo * start_info;
  gboolean res;

  thread = create_thread_object (domain);
  internal = create_internal_thread ();
  D.22551 = &thread->internal_thread;
  mono_gc_wbarrier_set_field (thread, D.22551, internal);
  start_info = monoeg_malloc0 (16);
  func.1 = (guint32 (*<T3bc6>) (void *)) func;
  start_info->func = func.1;
  start_info->obj = thread;
  start_info->start_arg = arg;
  res = create_thread (thread, internal, start_info, threadpool_thread, no_detach, stack_size, 1);
  if (res == 0) goto <D.22553>; else goto <D.22554>;
  <D.22553>:
  D.22555 = 0B;
  return D.22555;
  <D.22554>:
  D.22556 = mono_check_corlib_version ();
  if (D.22556 == 0B) goto <D.22557>; else goto <D.22558>;
  <D.22557>:
  D.22559 = mono_defaults.internal_thread_class;
  D.22560 = D.22559->fields;
  D.22559 = mono_defaults.internal_thread_class;
  D.22561 = D.22559->field.count;
  D.22562 = D.22561 + 268435455;
  D.22563 = D.22562 * 16;
  D.22564 = D.22560 + D.22563;
  D.22565 = D.22564->offset;
  D.22566 = D.22565 != 172;
  D.22567 = (long int) D.22566;
  D.22568 = __builtin_expect (D.22567, 0);
  if (D.22568 != 0) goto <D.22569>; else goto <D.22570>;
  <D.22569>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 850, "((char*)&internal->unused2 - (char*)internal) == mono_defaults.internal_thread_class->fields [mono_defaults.internal_thread_class->field.count - 1].offset");
  <D.22570>:
  <D.22558>:
  D.22555 = internal;
  return D.22555;
}


create_thread_object (struct MonoDomain * domain)
{
  struct MonoClass * D.22572;
  struct MonoThread * D.22573;
  struct MonoVTable * vt;

  D.22572 = mono_defaults.thread_class;
  vt = mono_class_vtable (domain, D.22572);
  D.22573 = mono_gc_alloc_mature (vt);
  return D.22573;
}


create_internal_thread ()
{
  struct MonoDomain * D.22575;
  struct MonoClass * D.22576;
  void * D.22577;
  struct CRITICAL_SECTION * D.22578;
  unsigned int D.22579;
  int D.22580;
  int D.22581;
  void * * D.22584;
  struct MonoInternalThread * D.22585;
  struct MonoInternalThread * thread;
  struct MonoVTable * vt;

  D.22575 = mono_get_root_domain ();
  D.22576 = mono_defaults.internal_thread_class;
  vt = mono_class_vtable (D.22575, D.22576);
  thread = mono_gc_alloc_mature (vt);
  D.22577 = monoeg_malloc0 (28);
  thread->synch_cs = D.22577;
  D.22578 = thread->synch_cs;
  InitializeCriticalSection (D.22578);
  thread->apartment_state = 2;
  D.22579 = get_next_managed_thread_id ();
  D.22580 = (int) D.22579;
  thread->managed_id = D.22580;
  D.22581 = mono_gc_is_moving ();
  if (D.22581 != 0) goto <D.22582>; else goto <D.22583>;
  <D.22582>:
  thread->thread_pinning_ref = thread;
  D.22584 = &thread->thread_pinning_ref;
  mono_gc_register_root (D.22584, 4, 0B);
  <D.22583>:
  D.22585 = thread;
  return D.22585;
}


get_next_managed_thread_id ()
{
  guint32 D.22587;
  int D.22588;

  D.22588 = InterlockedIncrement (&managed_thread_id_counter);
  D.22587 = (guint32) D.22588;
  return D.22587;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.22590;
  unsigned int D.22591;

  D.22591 = __sync_add_and_fetch_4 (val, 1);
  D.22590 = (gint32) D.22591;
  return D.22590;
}


create_thread (struct MonoThread * thread, struct MonoInternalThread * internal, struct StartInfo * start_info, gboolean threadpool_thread, gboolean no_detach, guint32 stack_size, gboolean throw_on_failure)
{
  _Bool D.22595;
  long int D.22596;
  long int D.22597;
  int shutting_down.2;
  _Bool D.22605;
  long int D.22606;
  long int D.22607;
  gboolean D.22610;
  struct MonoGHashTable * thread_start_args.3;
  int D.22614;
  struct MonoGHashTable * thread_start_args.4;
  void * D.22618;
  struct MonoGHashTable * threads_starting_up.5;
  int D.22622;
  struct MonoGHashTable * threads_starting_up.6;
  _Bool D.22628;
  long int D.22629;
  long int D.22630;
  void * D.22633;
  void * D.22634;
  _Bool D.22639;
  long int D.22640;
  long int D.22641;
  _Bool D.22646;
  long int D.22647;
  long int D.22648;
  unsigned int D.22651;
  guint32 iftmp.7;
  int D.22655;
  _Bool D.22665;
  long int D.22666;
  long int D.22667;
  _Bool D.22672;
  long int D.22673;
  long int D.22674;
  struct MonoException * D.22679;
  unsigned int D.22681;
  long unsigned int tid.8;
  long long unsigned int D.22683;
  unsigned char D.22684;
  int D.22687;
  void * D.22690;
  void * thread_handle;
  MonoNativeThreadId tid;
  guint32 create_flags;
  static const char __func__[14] = "create_thread";

  try
    {
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22593>; else goto <D.22594>;
        <D.22593>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22594>:
        D.22595 = ret != 0;
        D.22596 = (long int) D.22595;
        D.22597 = __builtin_expect (D.22596, 0);
        if (D.22597 != 0) goto <D.22598>; else goto <D.22599>;
        <D.22598>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 705, "ret == 0");
        <D.22599>:
      }
      shutting_down.2 = shutting_down;
      if (shutting_down.2 != 0) goto <D.22601>; else goto <D.22602>;
      <D.22601>:
      monoeg_g_free (start_info);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22603>; else goto <D.22604>;
        <D.22603>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22604>:
        D.22605 = ret != 0;
        D.22606 = (long int) D.22605;
        D.22607 = __builtin_expect (D.22606, 0);
        if (D.22607 != 0) goto <D.22608>; else goto <D.22609>;
        <D.22608>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 708, "ret == 0");
        <D.22609>:
      }
      D.22610 = 0;
      return D.22610;
      <D.22602>:
      thread_start_args.3 = thread_start_args;
      if (thread_start_args.3 == 0B) goto <D.22612>; else goto <D.22613>;
      <D.22612>:
      D.22614 = mono_gc_is_moving ();
      if (D.22614 == 0) goto <D.22615>; else goto <D.22616>;
      <D.22615>:
      mono_gc_register_root (&thread_start_args, 4, 0B);
      <D.22616>:
      thread_start_args.4 = mono_g_hash_table_new (0B, 0B);
      thread_start_args = thread_start_args.4;
      <D.22613>:
      thread_start_args.3 = thread_start_args;
      D.22618 = start_info->start_arg;
      mono_g_hash_table_insert (thread_start_args.3, thread, D.22618);
      threads_starting_up.5 = threads_starting_up;
      if (threads_starting_up.5 == 0B) goto <D.22620>; else goto <D.22621>;
      <D.22620>:
      D.22622 = mono_gc_is_moving ();
      if (D.22622 == 0) goto <D.22623>; else goto <D.22624>;
      <D.22623>:
      mono_gc_register_root (&threads_starting_up, 4, 0B);
      <D.22624>:
      threads_starting_up.6 = mono_g_hash_table_new_type (0B, 0B, 3);
      threads_starting_up = threads_starting_up.6;
      <D.22621>:
      threads_starting_up.5 = threads_starting_up;
      mono_g_hash_table_insert (threads_starting_up.5, thread, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22626>; else goto <D.22627>;
        <D.22626>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22627>:
        D.22628 = ret != 0;
        D.22629 = (long int) D.22628;
        D.22630 = __builtin_expect (D.22629, 0);
        if (D.22630 != 0) goto <D.22631>; else goto <D.22632>;
        <D.22631>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 727, "ret == 0");
        <D.22632>:
      }
      D.22633 = CreateSemaphore (0B, 0, 2147483647, 0B);
      internal->start_notify = D.22633;
      D.22634 = internal->start_notify;
      if (D.22634 == 0B) goto <D.22635>; else goto <D.22636>;
      <D.22635>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22637>; else goto <D.22638>;
        <D.22637>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22638>:
        D.22639 = ret != 0;
        D.22640 = (long int) D.22639;
        D.22641 = __builtin_expect (D.22640, 0);
        if (D.22641 != 0) goto <D.22642>; else goto <D.22643>;
        <D.22642>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 731, "ret == 0");
        <D.22643>:
      }
      threads_starting_up.5 = threads_starting_up;
      mono_g_hash_table_remove (threads_starting_up.5, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22644>; else goto <D.22645>;
        <D.22644>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22645>:
        D.22646 = ret != 0;
        D.22647 = (long int) D.22646;
        D.22648 = __builtin_expect (D.22647, 0);
        if (D.22648 != 0) goto <D.22649>; else goto <D.22650>;
        <D.22649>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 733, "ret == 0");
        <D.22650>:
      }
      D.22651 = GetLastError ();
      monoeg_g_log (0B, 16, "%s: CreateSemaphore error 0x%x", &__func__, D.22651);
      monoeg_g_free (start_info);
      D.22610 = 0;
      return D.22610;
      <D.22636>:
      if (stack_size == 0) goto <D.22652>; else goto <D.22653>;
      <D.22652>:
      D.22655 = internal->stack_size;
      if (D.22655 != 0) goto <D.22656>; else goto <D.22657>;
      <D.22656>:
      D.22655 = internal->stack_size;
      iftmp.7 = (guint32) D.22655;
      goto <D.22658>;
      <D.22657>:
      iftmp.7 = default_stacksize;
      <D.22658>:
      stack_size = iftmp.7;
      <D.22653>:
      create_flags = 4;
      if (no_detach != 0) goto <D.22659>; else goto <D.22660>;
      <D.22659>:
      create_flags = create_flags | 268435456;
      <D.22660>:
      thread_handle = mono_threads_create_thread (start_wrapper, start_info, stack_size, create_flags, &tid);
      if (thread_handle == 0B) goto <D.22661>; else goto <D.22662>;
      <D.22661>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22663>; else goto <D.22664>;
        <D.22663>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22664>:
        D.22665 = ret != 0;
        D.22666 = (long int) D.22665;
        D.22667 = __builtin_expect (D.22666, 0);
        if (D.22667 != 0) goto <D.22668>; else goto <D.22669>;
        <D.22668>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 754, "ret == 0");
        <D.22669>:
      }
      threads_starting_up.5 = threads_starting_up;
      mono_g_hash_table_remove (threads_starting_up.5, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22670>; else goto <D.22671>;
        <D.22670>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22671>:
        D.22672 = ret != 0;
        D.22673 = (long int) D.22672;
        D.22674 = __builtin_expect (D.22673, 0);
        if (D.22674 != 0) goto <D.22675>; else goto <D.22676>;
        <D.22675>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 756, "ret == 0");
        <D.22676>:
      }
      monoeg_g_free (start_info);
      if (throw_on_failure != 0) goto <D.22677>; else goto <D.22678>;
      <D.22677>:
      D.22679 = mono_get_exception_execution_engine ("Couldn\'t create thread");
      mono_raise_exception (D.22679);
      goto <D.22680>;
      <D.22678>:
      D.22681 = GetLastError ();
      monoeg_g_log (0B, 16, "%s: CreateThread error 0x%x", &__func__, D.22681);
      <D.22680>:
      D.22610 = 0;
      return D.22610;
      <D.22662>:
      internal->handle = thread_handle;
      tid.8 = tid;
      D.22683 = (long long unsigned int) tid.8;
      internal->tid = D.22683;
      D.22684 = (unsigned char) threadpool_thread;
      internal->threadpool_thread = D.22684;
      if (threadpool_thread != 0) goto <D.22685>; else goto <D.22686>;
      <D.22685>:
      mono_thread_set_state (internal, 4);
      <D.22686>:
      D.22687 = handle_store (thread, 0);
      if (D.22687 == 0) goto <D.22688>; else goto <D.22689>;
      <D.22688>:
      D.22610 = 0;
      return D.22610;
      <D.22689>:
      D.22690 = internal->handle;
      ResumeThread (D.22690);
      D.22634 = internal->start_notify;
      if (D.22634 != 0B) goto <D.22691>; else goto <D.22692>;
      <D.22691>:
      D.22634 = internal->start_notify;
      WaitForSingleObjectEx (D.22634, 4294967295, 0);
      D.22634 = internal->start_notify;
      CloseHandle (D.22634);
      internal->start_notify = 0B;
      <D.22692>:
      D.22610 = 1;
      return D.22610;
    }
  finally
    {
      tid = {CLOBBER};
    }
}


start_wrapper (void * data)
{
  guint32 D.22695;
  volatile int dummy;

  mono_gc_set_stack_end (&dummy);
  D.22695 = start_wrapper_internal (data);
  return D.22695;
}


start_wrapper_internal (void * data)
{
  struct MonoThread * D.22697;
  struct MonoVTable * D.22698;
  _Bool D.22699;
  long int D.22700;
  long int D.22701;
  long long unsigned int D.22704;
  unsigned int tid.9;
  unsigned int current_object_key.10;
  int D.22707;
  guint32 D.22710;
  unsigned int tid.11;
  int tid.12;
  unsigned char D.22713;
  void * D.22716;
  _Bool D.22721;
  long int D.22722;
  long int D.22723;
  struct MonoGHashTable * thread_start_args.13;
  _Bool D.22729;
  long int D.22730;
  long int D.22731;
  struct MonoObject * D.22734;
  _Bool D.22738;
  long int D.22739;
  long int D.22740;
  struct MonoThreadInfo * info;
  struct StartInfo * start_info;
  guint32 (*<T3bc6>) (void *) start_func;
  void * start_arg;
  gsize tid;
  struct MonoInternalThread * internal;
  struct MonoObject * start_delegate;
  struct MonoDomain * domain;

  try
    {
      start_info = data;
      D.22697 = start_info->obj;
      internal = D.22697->internal_thread;
      start_delegate = start_info->delegate;
      D.22697 = start_info->obj;
      D.22698 = D.22697->obj.vtable;
      domain = D.22698->domain;
      info = mono_thread_info_current ();
      D.22699 = info == 0B;
      D.22700 = (long int) D.22699;
      D.22701 = __builtin_expect (D.22700, 0);
      if (D.22701 != 0) goto <D.22702>; else goto <D.22703>;
      <D.22702>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 570, "info");
      <D.22703>:
      internal->thread_info = info;
      D.22704 = internal->tid;
      tid.9 = (unsigned int) D.22704;
      tid = tid.9;
      tls_current_object = internal;
      current_object_key.10 = current_object_key;
      mono_native_tls_set_value (current_object_key.10, internal);
      mono_monitor_init_tls ();
      mono_thread_push_appdomain_ref (domain);
      D.22707 = mono_domain_set (domain, 0);
      if (D.22707 == 0) goto <D.22708>; else goto <D.22709>;
      <D.22708>:
      mono_thread_pop_appdomain_ref ();
      D.22710 = 0;
      return D.22710;
      <D.22709>:
      start_func = start_info->func;
      start_arg = start_info->start_arg;
      thread_adjust_static_data (internal);
      D.22697 = start_info->obj;
      init_root_domain_thread (internal, D.22697);
      tid.11 = tid;
      tid.12 = (int) tid.11;
      mono_thread_new_init (tid.12, &tid, start_func);
      internal->stack_ptr = &tid;
      D.22713 = internal->apartment_state;
      if (D.22713 == 2) goto <D.22714>; else goto <D.22715>;
      <D.22714>:
      internal->apartment_state = 1;
      <D.22715>:
      mono_thread_init_apartment_state ();
      D.22716 = internal->start_notify;
      if (D.22716 != 0B) goto <D.22717>; else goto <D.22718>;
      <D.22717>:
      D.22716 = internal->start_notify;
      ReleaseSemaphore (D.22716, 1, 0B);
      <D.22718>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22719>; else goto <D.22720>;
        <D.22719>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22720>:
        D.22721 = ret != 0;
        D.22722 = (long int) D.22721;
        D.22723 = __builtin_expect (D.22722, 0);
        if (D.22723 != 0) goto <D.22724>; else goto <D.22725>;
        <D.22724>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 623, "ret == 0");
        <D.22725>:
      }
      thread_start_args.13 = thread_start_args;
      D.22697 = start_info->obj;
      mono_g_hash_table_remove (thread_start_args.13, D.22697);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22727>; else goto <D.22728>;
        <D.22727>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22728>:
        D.22729 = ret != 0;
        D.22730 = (long int) D.22729;
        D.22731 = __builtin_expect (D.22730, 0);
        if (D.22731 != 0) goto <D.22732>; else goto <D.22733>;
        <D.22732>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 625, "ret == 0");
        <D.22733>:
      }
      D.22697 = start_info->obj;
      D.22734 = D.22697->ec_to_set;
      mono_thread_set_execution_context (D.22734);
      D.22697 = start_info->obj;
      D.22697->ec_to_set = 0B;
      monoeg_g_free (start_info);
      tid.11 = tid;
      mono_profiler_thread_start (tid.11);
      if (start_func != 0B) goto <D.22735>; else goto <D.22736>;
      <D.22735>:
      start_func (start_arg);
      goto <D.22737>;
      <D.22736>:
      {
        void * args[1];

        try
          {
            D.22738 = start_delegate == 0B;
            D.22739 = (long int) D.22738;
            D.22740 = __builtin_expect (D.22739, 0);
            if (D.22740 != 0) goto <D.22741>; else goto <D.22742>;
            <D.22741>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 646, "start_delegate != NULL");
            <D.22742>:
            args[0] = start_arg;
            mono_runtime_delegate_invoke (start_delegate, &args, 0B);
          }
        finally
          {
            args = {CLOBBER};
          }
      }
      <D.22737>:
      mono_thread_cleanup_apartment_state ();
      thread_cleanup (internal);
      tls_current_object = 0B;
      current_object_key.10 = current_object_key;
      mono_native_tls_set_value (current_object_key.10, 0B);
      D.22710 = 0;
      return D.22710;
    }
  finally
    {
      tid = {CLOBBER};
    }
}


thread_adjust_static_data (struct MonoInternalThread * thread)
{
  _Bool D.22747;
  long int D.22748;
  long int D.22749;
  int D.22754;
  int D.22756;
  int D.22757;
  int D.22758;
  int D.22759;
  void * * * D.22760;
  _Bool D.22763;
  long int D.22764;
  long int D.22765;
  guint32 offset;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22745>; else goto <D.22746>;
    <D.22745>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22746>:
    D.22747 = ret != 0;
    D.22748 = (long int) D.22747;
    D.22749 = __builtin_expect (D.22748, 0);
    if (D.22749 != 0) goto <D.22750>; else goto <D.22751>;
    <D.22750>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3819, "ret == 0");
    <D.22751>:
  }
  D.22754 = thread_static_info.offset;
  if (D.22754 != 0) goto <D.22752>; else goto <D.22755>;
  <D.22755>:
  D.22756 = thread_static_info.idx;
  if (D.22756 > 0) goto <D.22752>; else goto <D.22753>;
  <D.22752>:
  D.22754 = thread_static_info.offset;
  D.22756 = thread_static_info.idx;
  D.22757 = D.22756 + 1;
  D.22758 = D.22757 << 24;
  D.22759 = D.22754 | D.22758;
  offset = (guint32) D.22759;
  D.22760 = &thread->static_data;
  mono_alloc_static_data (D.22760, offset, 1);
  <D.22753>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22761>; else goto <D.22762>;
    <D.22761>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22762>:
    D.22763 = ret != 0;
    D.22764 = (long int) D.22763;
    D.22765 = __builtin_expect (D.22764, 0);
    if (D.22765 != 0) goto <D.22766>; else goto <D.22767>;
    <D.22766>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3825, "ret == 0");
    <D.22767>:
  }
}


mono_alloc_static_data (void * * * static_data_ptr, guint32 offset, gboolean threadlocal)
{
  unsigned int D.22768;
  int D.22771;
  void * tls_desc.14;
  void * tls_desc.15;
  int D.22778;
  unsigned int D.22779;
  void * iftmp.16;
  unsigned int i.17;
  unsigned int D.22785;
  void * * D.22786;
  void * D.22787;
  int D.22792;
  int D.22795;
  unsigned int D.22796;
  void * D.22797;
  unsigned int D.22798;
  void * D.22799;
  unsigned int i.18;
  guint idx;
  int i;
  void * * static_data;

  D.22768 = offset >> 24;
  idx = D.22768 + 4294967295;
  static_data = *static_data_ptr;
  if (static_data == 0B) goto <D.22769>; else goto <D.22770>;
  <D.22769>:
  {
    static void * tls_desc = 0B;

    D.22771 = mono_gc_user_markers_supported ();
    if (D.22771 != 0) goto <D.22772>; else goto <D.22773>;
    <D.22772>:
    tls_desc.14 = tls_desc;
    if (tls_desc.14 == 0B) goto <D.22775>; else goto <D.22776>;
    <D.22775>:
    tls_desc.15 = mono_gc_make_root_descr_user (mark_tls_slots);
    tls_desc = tls_desc.15;
    <D.22776>:
    <D.22773>:
    D.22778 = 1024;
    D.22779 = (unsigned int) D.22778;
    if (threadlocal != 0) goto <D.22781>; else goto <D.22782>;
    <D.22781>:
    iftmp.16 = tls_desc;
    goto <D.22783>;
    <D.22782>:
    iftmp.16 = 0B;
    <D.22783>:
    static_data = mono_gc_alloc_fixed (D.22779, iftmp.16);
    *static_data_ptr = static_data;
    *static_data = static_data;
  }
  <D.22770>:
  i = 1;
  goto <D.22216>;
  <D.22215>:
  i.17 = (unsigned int) i;
  D.22785 = i.17 * 4;
  D.22786 = static_data + D.22785;
  D.22787 = *D.22786;
  if (D.22787 != 0B) goto <D.22788>; else goto <D.22789>;
  <D.22788>:
  // predicted unlikely by continue predictor.
  goto <D.22214>;
  <D.22789>:
  D.22792 = mono_gc_user_markers_supported ();
  if (D.22792 != 0) goto <D.22793>; else goto <D.22790>;
  <D.22793>:
  if (threadlocal != 0) goto <D.22794>; else goto <D.22790>;
  <D.22794>:
  i.17 = (unsigned int) i;
  D.22785 = i.17 * 4;
  D.22786 = static_data + D.22785;
  D.22795 = static_data_size[i];
  D.22796 = (unsigned int) D.22795;
  D.22797 = monoeg_malloc0 (D.22796);
  *D.22786 = D.22797;
  goto <D.22791>;
  <D.22790>:
  i.17 = (unsigned int) i;
  D.22785 = i.17 * 4;
  D.22786 = static_data + D.22785;
  D.22795 = static_data_size[i];
  D.22798 = (unsigned int) D.22795;
  D.22799 = mono_gc_alloc_fixed (D.22798, 0B);
  *D.22786 = D.22799;
  <D.22791>:
  <D.22214>:
  i = i + 1;
  <D.22216>:
  i.18 = (unsigned int) i;
  if (i.18 <= idx) goto <D.22215>; else goto <D.22217>;
  <D.22217>:
}


mark_tls_slots (void * addr, void (*MonoGCMarkFunc) (void * *) mark_func)
{
  unsigned int i.19;
  unsigned int D.22802;
  void * * D.22803;
  void * D.22804;
  int D.22807;
  unsigned int D.22808;
  unsigned int D.22809;
  unsigned int D.22810;
  uintptr_t * D.22811;
  unsigned int j.20;
  unsigned int D.22813;
  uintptr_t * D.22814;
  unsigned int D.22815;
  void * D.22818;
  int i;
  void * * static_data;

  static_data = addr;
  i = 0;
  goto <D.22203>;
  <D.22202>:
  {
    int j;
    int numwords;
    void * * ptr;

    i.19 = (unsigned int) i;
    D.22802 = i.19 * 4;
    D.22803 = static_data + D.22802;
    D.22804 = *D.22803;
    if (D.22804 == 0B) goto <D.22805>; else goto <D.22806>;
    <D.22805>:
    // predicted unlikely by continue predictor.
    goto <D.22193>;
    <D.22806>:
    D.22807 = static_data_size[i];
    D.22808 = (unsigned int) D.22807;
    D.22809 = D.22808 / 128;
    D.22810 = D.22809 + 1;
    numwords = (int) D.22810;
    i.19 = (unsigned int) i;
    D.22802 = i.19 * 4;
    D.22803 = static_data + D.22802;
    ptr = *D.22803;
    j = 0;
    goto <D.22200>;
    <D.22199>:
    {
      uintptr_t bmap;
      void * * p;

      D.22811 = static_reference_bitmaps[i];
      j.20 = (unsigned int) j;
      D.22813 = j.20 * 4;
      D.22814 = D.22811 + D.22813;
      bmap = *D.22814;
      p = ptr;
      goto <D.22197>;
      <D.22196>:
      D.22815 = bmap & 1;
      if (D.22815 != 0) goto <D.22816>; else goto <D.22817>;
      <D.22816>:
      D.22818 = *p;
      if (D.22818 != 0B) goto <D.22819>; else goto <D.22820>;
      <D.22819>:
      mark_func (p);
      <D.22820>:
      <D.22817>:
      p = p + 4;
      bmap = bmap >> 1;
      <D.22197>:
      if (bmap != 0) goto <D.22196>; else goto <D.22198>;
      <D.22198>:
    }
    j = j + 1;
    ptr = ptr + 128;
    <D.22200>:
    if (j < numwords) goto <D.22199>; else goto <D.22201>;
    <D.22201>:
  }
  <D.22193>:
  i = i + 1;
  <D.22203>:
  if (i <= 7) goto <D.22202>; else goto <D.22204>;
  <D.22204>:
}


init_root_domain_thread (struct MonoInternalThread * thread, struct MonoThread * candidate)
{
  struct MonoVTable * D.22824;
  struct MonoDomain * D.22825;
  struct MonoThread * D.22826;
  _Bool D.22827;
  long int D.22828;
  long int D.22829;
  struct MonoThread * * D.22832;
  struct MonoDomain * domain;

  domain = mono_get_root_domain ();
  if (candidate == 0B) goto <D.22821>; else goto <D.22823>;
  <D.22823>:
  D.22824 = candidate->obj.vtable;
  D.22825 = D.22824->domain;
  if (D.22825 != domain) goto <D.22821>; else goto <D.22822>;
  <D.22821>:
  candidate = new_thread_with_internal (domain, thread);
  <D.22822>:
  set_current_thread_for_domain (domain, thread, candidate);
  D.22826 = thread->root_domain_thread;
  D.22827 = D.22826 != 0B;
  D.22828 = (long int) D.22827;
  D.22829 = __builtin_expect (D.22828, 0);
  if (D.22829 != 0) goto <D.22830>; else goto <D.22831>;
  <D.22830>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 542, "!thread->root_domain_thread");
  <D.22831>:
  D.22832 = &thread->root_domain_thread;
  mono_gc_wbarrier_set_field (thread, D.22832, candidate);
}


new_thread_with_internal (struct MonoDomain * domain, struct MonoInternalThread * internal)
{
  struct _MonoInternalThread * * D.22833;
  struct MonoThread * D.22834;
  struct MonoThread * thread;

  thread = create_thread_object (domain);
  D.22833 = &thread->internal_thread;
  mono_gc_wbarrier_set_field (thread, D.22833, internal);
  D.22834 = thread;
  return D.22834;
}


set_current_thread_for_domain (struct MonoDomain * domain, struct MonoInternalThread * thread, struct MonoThread * current)
{
  struct MonoVTable * D.22836;
  struct MonoDomain * D.22837;
  _Bool D.22838;
  long int D.22839;
  long int D.22840;
  struct MonoThread * D.22843;
  _Bool D.22844;
  long int D.22845;
  long int D.22846;
  struct MonoThread * * current_thread_ptr;

  current_thread_ptr = get_current_thread_ptr_for_domain (domain, thread);
  D.22836 = current->obj.vtable;
  D.22837 = D.22836->domain;
  D.22838 = D.22837 != domain;
  D.22839 = (long int) D.22838;
  D.22840 = __builtin_expect (D.22839, 0);
  if (D.22840 != 0) goto <D.22841>; else goto <D.22842>;
  <D.22841>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 491, "current->obj.vtable->domain == domain");
  <D.22842>:
  D.22843 = *current_thread_ptr;
  D.22844 = D.22843 != 0B;
  D.22845 = (long int) D.22844;
  D.22846 = __builtin_expect (D.22845, 0);
  if (D.22846 != 0) goto <D.22847>; else goto <D.22848>;
  <D.22847>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 493, "!*current_thread_ptr");
  <D.22848>:
  *current_thread_ptr = current;
}


get_current_thread_ptr_for_domain (struct MonoDomain * domain, struct MonoInternalThread * thread)
{
  struct MonoClassField * current_thread_field.21;
  struct MonoClass * D.22852;
  struct MonoClassField * current_thread_field.22;
  _Bool D.22854;
  long int D.22855;
  long int D.22856;
  union mono_mutex_t * D.22859;
  _Bool D.22862;
  long int D.22863;
  long int D.22864;
  struct GHashTable * D.22867;
  void * D.22868;
  _Bool D.22871;
  long int D.22872;
  long int D.22873;
  _Bool D.22876;
  long int D.22877;
  long int D.22878;
  struct MonoThread * * D.22881;
  static struct MonoClassField * current_thread_field = 0B;
  guint32 offset;

  current_thread_field.21 = current_thread_field;
  if (current_thread_field.21 == 0B) goto <D.22850>; else goto <D.22851>;
  <D.22850>:
  D.22852 = mono_defaults.thread_class;
  current_thread_field.22 = mono_class_get_field_from_name (D.22852, "current_thread");
  current_thread_field = current_thread_field.22;
  current_thread_field.21 = current_thread_field;
  D.22854 = current_thread_field.21 == 0B;
  D.22855 = (long int) D.22854;
  D.22856 = __builtin_expect (D.22855, 0);
  if (D.22856 != 0) goto <D.22857>; else goto <D.22858>;
  <D.22857>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 474, "current_thread_field");
  <D.22858>:
  <D.22851>:
  D.22852 = mono_defaults.thread_class;
  mono_class_vtable (domain, D.22852);
  {
    int ret;

    D.22859 = &domain->lock.mutex;
    ret = pthread_mutex_lock (D.22859);
    if (ret != 0) goto <D.22860>; else goto <D.22861>;
    <D.22860>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22861>:
    D.22862 = ret != 0;
    D.22863 = (long int) D.22862;
    D.22864 = __builtin_expect (D.22863, 0);
    if (D.22864 != 0) goto <D.22865>; else goto <D.22866>;
    <D.22865>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 478, "ret == 0");
    <D.22866>:
  }
  D.22867 = domain->special_static_fields;
  current_thread_field.21 = current_thread_field;
  D.22868 = monoeg_g_hash_table_lookup (D.22867, current_thread_field.21);
  offset = (guint32) D.22868;
  {
    int ret;

    D.22859 = &domain->lock.mutex;
    ret = pthread_mutex_unlock (D.22859);
    if (ret != 0) goto <D.22869>; else goto <D.22870>;
    <D.22869>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22870>:
    D.22871 = ret != 0;
    D.22872 = (long int) D.22871;
    D.22873 = __builtin_expect (D.22872, 0);
    if (D.22873 != 0) goto <D.22874>; else goto <D.22875>;
    <D.22874>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 480, "ret == 0");
    <D.22875>:
  }
  D.22876 = offset == 0;
  D.22877 = (long int) D.22876;
  D.22878 = __builtin_expect (D.22877, 0);
  if (D.22878 != 0) goto <D.22879>; else goto <D.22880>;
  <D.22879>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 481, "offset");
  <D.22880>:
  D.22881 = get_thread_static_data (thread, offset);
  return D.22881;
}


get_thread_static_data (struct MonoInternalThread * thread, guint32 offset)
{
  signed int offset.23;
  _Bool D.22884;
  long int D.22885;
  long int D.22886;
  unsigned int D.22889;
  unsigned int D.22890;
  void * D.22891;
  void * * D.22892;
  unsigned int idx.24;
  unsigned int D.22894;
  void * * D.22895;
  void * D.22896;
  sizetype D.22897;
  int idx;

  offset.23 = (signed int) offset;
  D.22884 = offset.23 < 0;
  D.22885 = (long int) D.22884;
  D.22886 = __builtin_expect (D.22885, 0);
  if (D.22886 != 0) goto <D.22887>; else goto <D.22888>;
  <D.22887>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 459, "(offset & 0x80000000) == 0");
  <D.22888>:
  offset = offset & 2147483647;
  D.22889 = offset >> 24;
  D.22890 = D.22889 + 4294967295;
  idx = (int) D.22890;
  D.22892 = thread->static_data;
  idx.24 = (unsigned int) idx;
  D.22894 = idx.24 * 4;
  D.22895 = D.22892 + D.22894;
  D.22896 = *D.22895;
  D.22897 = offset & 16777215;
  D.22891 = D.22896 + D.22897;
  return D.22891;
}


thread_cleanup (struct MonoInternalThread * thread)
{
  _Bool D.22899;
  long int D.22900;
  long int D.22901;
  int D.22904;
  unsigned int D.22907;
  struct MonoArray * D.22908;
  unsigned int i.25;
  struct CRITICAL_SECTION * D.22912;
  int shutting_down.26;
  _Bool D.22917;
  long int D.22918;
  long int D.22919;
  unsigned int D.22922;
  unsigned int D.22923;
  unsigned int D.22924;
  gint32 * D.22927;
  int D.22928;
  int D.22931;
  struct MonoInternalThread * D.22934;
  void (*<T2b56>) (struct MonoInternalThread *) mono_thread_cleanup_fn.27;
  long long unsigned int D.22940;
  unsigned int D.22941;
  struct MonoInternalThread * D.22942;
  struct MonoInternalThread * D.22945;
  void * * D.22948;
  void * D.22949;
  int D.22952;
  void * * D.22955;

  D.22899 = thread == 0B;
  D.22900 = (long int) D.22899;
  D.22901 = __builtin_expect (D.22900, 0);
  if (D.22901 != 0) goto <D.22902>; else goto <D.22903>;
  <D.22902>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 368, "thread != NULL");
  <D.22903>:
  D.22904 = thread->abort_state_handle;
  if (D.22904 != 0) goto <D.22905>; else goto <D.22906>;
  <D.22905>:
  D.22904 = thread->abort_state_handle;
  D.22907 = (unsigned int) D.22904;
  mono_gchandle_free (D.22907);
  thread->abort_state_handle = 0;
  <D.22906>:
  thread->abort_exc = 0B;
  thread->current_appcontext = 0B;
  D.22908 = thread->cached_culture_info;
  if (D.22908 != 0B) goto <D.22909>; else goto <D.22910>;
  <D.22909>:
  {
    int i;

    i = 0;
    goto <D.21197>;
    <D.21196>:
    {
      struct MonoObject * * __p;

      D.22908 = thread->cached_culture_info;
      i.25 = (unsigned int) i;
      __p = mono_array_addr_with_size (D.22908, 4, i.25);
      *__p = 0B;
    }
    i = i + 1;
    <D.21197>:
    if (i <= 7) goto <D.21196>; else goto <D.21198>;
    <D.21198>:
  }
  <D.22910>:
  D.22912 = thread->synch_cs;
  if (D.22912 != 0B) goto <D.22913>; else goto <D.22914>;
  <D.22913>:
  lock_thread (thread);
  goto <D.22915>;
  <D.22914>:
  shutting_down.26 = shutting_down;
  D.22917 = shutting_down.26 == 0;
  D.22918 = (long int) D.22917;
  D.22919 = __builtin_expect (D.22918, 0);
  if (D.22919 != 0) goto <D.22920>; else goto <D.22921>;
  <D.22920>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 391, "shutting_down");
  <D.22921>:
  <D.22915>:
  D.22922 = thread->state;
  D.22923 = D.22922 | 16;
  thread->state = D.22923;
  D.22922 = thread->state;
  D.22924 = D.22922 & 4294967291;
  thread->state = D.22924;
  D.22912 = thread->synch_cs;
  if (D.22912 != 0B) goto <D.22925>; else goto <D.22926>;
  <D.22925>:
  unlock_thread (thread);
  <D.22926>:
  D.22927 = &thread->interruption_requested;
  D.22928 = InterlockedExchange (D.22927, 0);
  if (D.22928 != 0) goto <D.22929>; else goto <D.22930>;
  <D.22929>:
  InterlockedDecrement (&thread_interruption_requested);
  <D.22930>:
  D.22931 = handle_remove (thread);
  if (D.22931 == 0) goto <D.22932>; else goto <D.22933>;
  <D.22932>:
  D.22934 = mono_thread_internal_current ();
  if (D.22934 == thread) goto <D.22935>; else goto <D.22936>;
  <D.22935>:
  mono_domain_unset ();
  mono_memory_barrier ();
  <D.22936>:
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  if (mono_thread_cleanup_fn.27 != 0B) goto <D.22938>; else goto <D.22939>;
  <D.22938>:
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  mono_thread_cleanup_fn.27 (thread);
  <D.22939>:
  return;
  <D.22933>:
  mono_release_type_locks (thread);
  D.22940 = thread->tid;
  D.22941 = (unsigned int) D.22940;
  mono_profiler_thread_end (D.22941);
  D.22942 = mono_thread_internal_current ();
  if (D.22942 == thread) goto <D.22943>; else goto <D.22944>;
  <D.22943>:
  mono_domain_unset ();
  mono_memory_barrier ();
  <D.22944>:
  D.22945 = mono_thread_internal_current ();
  if (D.22945 == thread) goto <D.22946>; else goto <D.22947>;
  <D.22946>:
  mono_thread_pop_appdomain_ref ();
  <D.22947>:
  thread->cached_culture_info = 0B;
  D.22948 = thread->static_data;
  mono_free_static_data (D.22948, 1);
  thread->static_data = 0B;
  D.22949 = thread->appdomain_refs;
  ref_stack_destroy (D.22949);
  thread->appdomain_refs = 0B;
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  if (mono_thread_cleanup_fn.27 != 0B) goto <D.22950>; else goto <D.22951>;
  <D.22950>:
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  mono_thread_cleanup_fn.27 (thread);
  <D.22951>:
  D.22952 = mono_gc_is_moving ();
  if (D.22952 != 0) goto <D.22953>; else goto <D.22954>;
  <D.22953>:
  D.22955 = &thread->thread_pinning_ref;
  mono_gc_deregister_root (D.22955);
  thread->thread_pinning_ref = 0B;
  <D.22954>:
}


lock_thread (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.22957;
  _Bool D.22960;
  long int D.22961;
  long int D.22962;
  union mono_mutex_t * D.22965;
  _Bool D.22968;
  long int D.22969;
  long int D.22970;

  D.22957 = thread->synch_cs;
  if (D.22957 == 0B) goto <D.22958>; else goto <D.22959>;
  <D.22958>:
  ensure_synch_cs_set (thread);
  <D.22959>:
  D.22957 = thread->synch_cs;
  D.22960 = D.22957 == 0B;
  D.22961 = (long int) D.22960;
  D.22962 = __builtin_expect (D.22961, 0);
  if (D.22962 != 0) goto <D.22963>; else goto <D.22964>;
  <D.22963>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 351, "thread->synch_cs");
  <D.22964>:
  {
    int ret;

    D.22957 = thread->synch_cs;
    D.22965 = &D.22957->mutex;
    ret = pthread_mutex_lock (D.22965);
    if (ret != 0) goto <D.22966>; else goto <D.22967>;
    <D.22966>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22967>:
    D.22968 = ret != 0;
    D.22969 = (long int) D.22968;
    D.22970 = __builtin_expect (D.22969, 0);
    if (D.22970 != 0) goto <D.22971>; else goto <D.22972>;
    <D.22971>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 352, "ret == 0");
    <D.22972>:
  }
}


ensure_synch_cs_set (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.22973;
  struct CRITICAL_SECTION * * D.22976;
  void * D.22977;
  struct CRITICAL_SECTION * synch_cs;

  D.22973 = thread->synch_cs;
  if (D.22973 != 0B) goto <D.22974>; else goto <D.22975>;
  <D.22974>:
  return;
  <D.22975>:
  synch_cs = monoeg_malloc0 (28);
  InitializeCriticalSection (synch_cs);
  D.22976 = &thread->synch_cs;
  D.22977 = InterlockedCompareExchangePointer (D.22976, synch_cs, 0B);
  if (D.22977 != 0B) goto <D.22978>; else goto <D.22979>;
  <D.22978>:
  DeleteCriticalSection (synch_cs);
  monoeg_g_free (synch_cs);
  <D.22979>:
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.22981;
  unsigned int comp.28;
  unsigned int exch.29;
  unsigned int D.22984;

  comp.28 = (unsigned int) comp;
  exch.29 = (unsigned int) exch;
  D.22984 = __sync_val_compare_and_swap_4 (dest, comp.28, exch.29);
  D.22981 = (void *) D.22984;
  return D.22981;
}


unlock_thread (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.22986;
  union mono_mutex_t * D.22987;
  _Bool D.22990;
  long int D.22991;
  long int D.22992;

  {
    int ret;

    D.22986 = thread->synch_cs;
    D.22987 = &D.22986->mutex;
    ret = pthread_mutex_unlock (D.22987);
    if (ret != 0) goto <D.22988>; else goto <D.22989>;
    <D.22988>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22989>:
    D.22990 = ret != 0;
    D.22991 = (long int) D.22990;
    D.22992 = __builtin_expect (D.22991, 0);
    if (D.22992 != 0) goto <D.22993>; else goto <D.22994>;
    <D.22993>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 358, "ret == 0");
    <D.22994>:
  }
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int old_val.30;
  unsigned int new_val.31;
  unsigned int D.22997;
  int D.22998;
  gint32 D.22999;
  gint32 old_val;

  <D.20978>:
  old_val = *val;
  old_val.30 = (unsigned int) old_val;
  new_val.31 = (unsigned int) new_val;
  D.22997 = __sync_val_compare_and_swap_4 (val, old_val.30, new_val.31);
  D.22998 = (int) D.22997;
  if (D.22998 != old_val) goto <D.20978>; else goto <D.20979>;
  <D.20979>:
  D.22999 = old_val;
  return D.22999;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.23001;
  unsigned int D.23002;

  D.23002 = __sync_sub_and_fetch_4 (val, 1);
  D.23001 = (gint32) D.23002;
  return D.23001;
}


handle_remove (struct MonoInternalThread * thread)
{
  long long unsigned int D.23004;
  _Bool D.23007;
  long int D.23008;
  long int D.23009;
  struct MonoGHashTable * threads.32;
  const void * tid.33;
  void * D.23016;
  _Bool D.23023;
  long int D.23024;
  long int D.23025;
  gboolean D.23028;
  gboolean ret;
  gsize tid;

  D.23004 = thread->tid;
  tid = (gsize) D.23004;
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.23005>; else goto <D.23006>;
    <D.23005>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.23006>:
    D.23007 = ret != 0;
    D.23008 = (long int) D.23007;
    D.23009 = __builtin_expect (D.23008, 0);
    if (D.23009 != 0) goto <D.23010>; else goto <D.23011>;
    <D.23010>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 289, "ret == 0");
    <D.23011>:
  }
  threads.32 = threads;
  if (threads.32 != 0B) goto <D.23013>; else goto <D.23014>;
  <D.23013>:
  threads.32 = threads;
  tid.33 = (const void *) tid;
  D.23016 = mono_g_hash_table_lookup (threads.32, tid.33);
  if (D.23016 == thread) goto <D.23017>; else goto <D.23018>;
  <D.23017>:
  threads.32 = threads;
  tid.33 = (const void *) tid;
  mono_g_hash_table_remove (threads.32, tid.33);
  ret = 1;
  goto <D.23019>;
  <D.23018>:
  ret = 0;
  <D.23019>:
  goto <D.23020>;
  <D.23014>:
  ret = 0;
  <D.23020>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.23021>; else goto <D.23022>;
    <D.23021>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.23022>:
    D.23023 = ret != 0;
    D.23024 = (long int) D.23023;
    D.23025 = __builtin_expect (D.23024, 0);
    if (D.23025 != 0) goto <D.23026>; else goto <D.23027>;
    <D.23026>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 308, "ret == 0");
    <D.23027>:
  }
  D.23028 = ret;
  return D.23028;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_free_static_data (void * * static_data, gboolean threadlocal)
{
  unsigned int i.34;
  unsigned int D.23031;
  void * * D.23032;
  int D.23037;
  int i;

  i = 1;
  goto <D.22226>;
  <D.22225>:
  {
    void * p;

    i.34 = (unsigned int) i;
    D.23031 = i.34 * 4;
    D.23032 = static_data + D.23031;
    p = *D.23032;
    if (p == 0B) goto <D.23033>; else goto <D.23034>;
    <D.23033>:
    // predicted unlikely by continue predictor.
    goto <D.22224>;
    <D.23034>:
    i.34 = (unsigned int) i;
    D.23031 = i.34 * 4;
    D.23032 = static_data + D.23031;
    *D.23032 = 0B;
    mono_memory_write_barrier ();
    D.23037 = mono_gc_user_markers_supported ();
    if (D.23037 != 0) goto <D.23038>; else goto <D.23035>;
    <D.23038>:
    if (threadlocal != 0) goto <D.23039>; else goto <D.23035>;
    <D.23039>:
    monoeg_g_free (p);
    goto <D.23036>;
    <D.23035>:
    mono_gc_free_fixed (p);
    <D.23036>:
  }
  <D.22224>:
  i = i + 1;
  <D.22226>:
  if (i <= 7) goto <D.22225>; else goto <D.22227>;
  <D.22227>:
  mono_gc_free_fixed (static_data);
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


ref_stack_destroy (void * ptr)
{
  void * * D.23042;
  struct RefStack * rs;

  rs = ptr;
  if (rs != 0B) goto <D.23040>; else goto <D.23041>;
  <D.23040>:
  D.23042 = rs->refs;
  monoeg_g_free (D.23042);
  monoeg_g_free (rs);
  <D.23041>:
}


mono_native_tls_set_value (pthread_key_t key, void * value)
{
  int D.23043;
  int D.23044;
  _Bool D.23045;

  D.23044 = pthread_setspecific (key, value);
  D.23045 = D.23044 == 0;
  D.23043 = (int) D.23045;
  return D.23043;
}


handle_store (struct MonoThread * thread, gboolean force_attach)
{
  _Bool D.23049;
  long int D.23050;
  long int D.23051;
  struct MonoGHashTable * threads_starting_up.35;
  int shutting_down.36;
  _Bool D.23064;
  long int D.23065;
  long int D.23066;
  gboolean D.23069;
  struct MonoGHashTable * threads.37;
  int D.23073;
  struct MonoGHashTable * threads.38;
  struct _MonoInternalThread * D.23077;
  _Bool D.23078;
  long int D.23079;
  long int D.23080;
  long long unsigned int D.23083;
  unsigned int D.23084;
  void * D.23085;
  _Bool D.23088;
  long int D.23089;
  long int D.23090;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.23047>; else goto <D.23048>;
    <D.23047>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.23048>:
    D.23049 = ret != 0;
    D.23050 = (long int) D.23049;
    D.23051 = __builtin_expect (D.23050, 0);
    if (D.23051 != 0) goto <D.23052>; else goto <D.23053>;
    <D.23052>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 253, "ret == 0");
    <D.23053>:
  }
  threads_starting_up.35 = threads_starting_up;
  if (threads_starting_up.35 != 0B) goto <D.23055>; else goto <D.23056>;
  <D.23055>:
  threads_starting_up.35 = threads_starting_up;
  mono_g_hash_table_remove (threads_starting_up.35, thread);
  <D.23056>:
  shutting_down.36 = shutting_down;
  if (shutting_down.36 != 0) goto <D.23058>; else goto <D.23059>;
  <D.23058>:
  if (force_attach == 0) goto <D.23060>; else goto <D.23061>;
  <D.23060>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.23062>; else goto <D.23063>;
    <D.23062>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.23063>:
    D.23064 = ret != 0;
    D.23065 = (long int) D.23064;
    D.23066 = __builtin_expect (D.23065, 0);
    if (D.23066 != 0) goto <D.23067>; else goto <D.23068>;
    <D.23067>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 261, "ret == 0");
    <D.23068>:
  }
  D.23069 = 0;
  return D.23069;
  <D.23061>:
  <D.23059>:
  threads.37 = threads;
  if (threads.37 == 0B) goto <D.23071>; else goto <D.23072>;
  <D.23071>:
  D.23073 = mono_gc_is_moving ();
  if (D.23073 == 0) goto <D.23074>; else goto <D.23075>;
  <D.23074>:
  mono_gc_register_root (&threads, 4, 0B);
  <D.23075>:
  threads.38 = mono_g_hash_table_new_type (0B, 0B, 2);
  threads = threads.38;
  <D.23072>:
  D.23077 = thread->internal_thread;
  D.23078 = D.23077 == 0B;
  D.23079 = (long int) D.23078;
  D.23080 = __builtin_expect (D.23079, 0);
  if (D.23080 != 0) goto <D.23081>; else goto <D.23082>;
  <D.23081>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 273, "thread->internal_thread");
  <D.23082>:
  threads.37 = threads;
  D.23077 = thread->internal_thread;
  D.23083 = D.23077->tid;
  D.23084 = (unsigned int) D.23083;
  D.23085 = (void *) D.23084;
  D.23077 = thread->internal_thread;
  mono_g_hash_table_insert (threads.37, D.23085, D.23077);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.23086>; else goto <D.23087>;
    <D.23086>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.23087>:
    D.23088 = ret != 0;
    D.23089 = (long int) D.23088;
    D.23090 = __builtin_expect (D.23089, 0);
    if (D.23090 != 0) goto <D.23091>; else goto <D.23092>;
    <D.23091>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 277, "ret == 0");
    <D.23092>:
  }
  D.23069 = 1;
  return D.23069;
}


mono_thread_create (struct MonoDomain * domain, void * func, void * arg)
{
  mono_thread_create_internal (domain, func, arg, 0, 0, 0);
}


mono_thread_get_stack_bounds (guint8 * * staddr, size_t * stsize)
{
  long unsigned int D.23094;
  guint8 * D.23095;
  int iftmp.39;
  unsigned int D.23103;
  guint8 * D.23104;
  _Bool D.23105;
  long int D.23106;
  long int D.23107;
  int D.23110;
  int D.23111;
  int D.23112;
  int D.23113;
  guint8 * D.23114;
  union pthread_attr_t attr;
  guint8 * current;

  try
    {
      current = &attr;
      *staddr = 0B;
      *stsize = 4294967295;
      pthread_attr_init (&attr);
      D.23094 = pthread_self ();
      pthread_getattr_np (D.23094, &attr);
      pthread_attr_getstack (&attr, staddr, stsize);
      pthread_attr_destroy (&attr);
      D.23095 = *staddr;
      if (D.23095 != 0B) goto <D.23096>; else goto <D.23097>;
      <D.23096>:
      D.23095 = *staddr;
      if (D.23095 >= current) goto <D.23099>; else goto <D.23102>;
      <D.23102>:
      D.23095 = *staddr;
      D.23103 = *stsize;
      D.23104 = D.23095 + D.23103;
      if (D.23104 <= current) goto <D.23099>; else goto <D.23100>;
      <D.23099>:
      iftmp.39 = 1;
      goto <D.23101>;
      <D.23100>:
      iftmp.39 = 0;
      <D.23101>:
      D.23105 = iftmp.39 != 0;
      D.23106 = (long int) D.23105;
      D.23107 = __builtin_expect (D.23106, 0);
      if (D.23107 != 0) goto <D.23108>; else goto <D.23109>;
      <D.23108>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 944, "(current > *staddr) && (current < *staddr + *stsize)");
      <D.23109>:
      <D.23097>:
      D.23095 = *staddr;
      D.23110 = (int) D.23095;
      D.23111 = mono_pagesize ();
      D.23112 = -D.23111;
      D.23113 = D.23110 & D.23112;
      D.23114 = (guint8 *) D.23113;
      *staddr = D.23114;
      return;
    }
  finally
    {
      attr = {CLOBBER};
    }
}


mono_thread_attach (struct MonoDomain * domain)
{
  struct MonoThread * D.23117;

  D.23117 = mono_thread_attach_full (domain, 0);
  return D.23117;
}


mono_thread_attach_full (struct MonoDomain * domain, gboolean force_attach)
{
  struct MonoDomain * D.23121;
  struct MonoDomain * domain.40;
  struct MonoThread * D.23125;
  int D.23126;
  unsigned int D.23129;
  void * thread_handle.41;
  void * thread_handle.42;
  _Bool D.23132;
  long int D.23133;
  long int D.23134;
  unsigned int tid.43;
  void * D.23138;
  void * D.23139;
  unsigned int tid.44;
  long long unsigned int D.23141;
  _Bool D.23142;
  long int D.23143;
  long int D.23144;
  int D.23147;
  unsigned int current_object_key.45;
  struct MonoDomain * D.23151;
  void (*<T1d7b>) (intptr_t, void *) mono_thread_attach_cb.46;
  guint8 * staddr.47;
  int tid.48;
  unsigned int stsize.49;
  void * D.23163;
  struct MonoThreadInfo * info;
  struct MonoInternalThread * thread;
  struct MonoThread * current_thread;
  void * thread_handle;
  gsize tid;

  try
    {
      thread = mono_thread_internal_current ();
      if (thread != 0B) goto <D.23119>; else goto <D.23120>;
      <D.23119>:
      D.23121 = mono_domain_get ();
      domain.40 = domain;
      if (D.23121 != domain.40) goto <D.23123>; else goto <D.23124>;
      <D.23123>:
      domain.40 = domain;
      mono_domain_set (domain.40, 1);
      <D.23124>:
      D.23125 = mono_thread_current ();
      return D.23125;
      <D.23120>:
      D.23126 = mono_gc_register_thread (&domain);
      if (D.23126 == 0) goto <D.23127>; else goto <D.23128>;
      <D.23127>:
      D.23129 = GetCurrentThreadId ();
      monoeg_g_log (0B, 4, "Thread %u calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", D.23129);
      <D.21322>:
      goto <D.21322>;
      <D.23128>:
      thread = create_internal_thread ();
      thread_handle.41 = GetCurrentThread ();
      thread_handle = thread_handle.41;
      thread_handle.42 = thread_handle;
      D.23132 = thread_handle.42 == 0B;
      D.23133 = (long int) D.23132;
      D.23134 = __builtin_expect (D.23133, 0);
      if (D.23134 != 0) goto <D.23135>; else goto <D.23136>;
      <D.23135>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1028, "thread_handle");
      <D.23136>:
      tid.43 = GetCurrentThreadId ();
      tid = tid.43;
      D.23138 = GetCurrentProcess ();
      thread_handle.42 = thread_handle;
      D.23139 = GetCurrentProcess ();
      DuplicateHandle (D.23138, thread_handle.42, D.23139, &thread_handle, 2032639, 1, 0);
      thread_handle.42 = thread_handle;
      thread->handle = thread_handle.42;
      tid.44 = tid;
      D.23141 = (long long unsigned int) tid.44;
      thread->tid = D.23141;
      thread->stack_ptr = &tid;
      info = mono_thread_info_current ();
      D.23142 = info == 0B;
      D.23143 = (long int) D.23142;
      D.23144 = __builtin_expect (D.23143, 0);
      if (D.23144 != 0) goto <D.23145>; else goto <D.23146>;
      <D.23145>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1049, "info");
      <D.23146>:
      thread->thread_info = info;
      domain.40 = domain;
      current_thread = new_thread_with_internal (domain.40, thread);
      D.23147 = handle_store (current_thread, force_attach);
      if (D.23147 == 0) goto <D.23148>; else goto <D.23149>;
      <D.23148>:
      <D.21323>:
      Sleep (10000);
      goto <D.21323>;
      <D.23149>:
      tls_current_object = thread;
      current_object_key.45 = current_object_key;
      mono_native_tls_set_value (current_object_key.45, thread);
      domain.40 = domain;
      mono_domain_set (domain.40, 1);
      mono_monitor_init_tls ();
      thread_adjust_static_data (thread);
      init_root_domain_thread (thread, current_thread);
      D.23151 = mono_get_root_domain ();
      domain.40 = domain;
      if (D.23151 != domain.40) goto <D.23152>; else goto <D.23153>;
      <D.23152>:
      domain.40 = domain;
      set_current_thread_for_domain (domain.40, thread, current_thread);
      <D.23153>:
      mono_thread_attach_cb.46 = mono_thread_attach_cb;
      if (mono_thread_attach_cb.46 != 0B) goto <D.23155>; else goto <D.23156>;
      <D.23155>:
      {
        guint8 * staddr;
        size_t stsize;

        try
          {
            mono_thread_get_stack_bounds (&staddr, &stsize);
            staddr.47 = staddr;
            if (staddr.47 == 0B) goto <D.23158>; else goto <D.23159>;
            <D.23158>:
            mono_thread_attach_cb.46 = mono_thread_attach_cb;
            tid.44 = tid;
            tid.48 = (int) tid.44;
            mono_thread_attach_cb.46 (tid.48, &tid);
            goto <D.23161>;
            <D.23159>:
            mono_thread_attach_cb.46 = mono_thread_attach_cb;
            tid.44 = tid;
            tid.48 = (int) tid.44;
            staddr.47 = staddr;
            stsize.49 = stsize;
            D.23163 = staddr.47 + stsize.49;
            mono_thread_attach_cb.46 (tid.48, D.23163);
            <D.23161>:
          }
        finally
          {
            staddr = {CLOBBER};
            stsize = {CLOBBER};
          }
      }
      <D.23156>:
      tid.44 = tid;
      mono_profiler_thread_start (tid.44);
      D.23125 = current_thread;
      return D.23125;
    }
  finally
    {
      thread_handle = {CLOBBER};
      tid = {CLOBBER};
    }
}


mono_thread_detach (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.23168;
  unsigned int current_object_key.50;

  if (thread == 0B) goto <D.23166>; else goto <D.23167>;
  <D.23166>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "threads.c", 1095, "thread != NULL");
  return;
  <D.23167>:
  D.23168 = thread->internal_thread;
  thread_cleanup (D.23168);
  tls_current_object = 0B;
  current_object_key.50 = current_object_key;
  mono_native_tls_set_value (current_object_key.50, 0B);
  mono_domain_unset ();
}


mono_thread_exit ()
{
  unsigned int current_object_key.51;
  struct MonoThread * D.23172;
  struct MonoThread * D.23175;
  struct _MonoInternalThread * D.23176;
  int D.23179;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  thread_cleanup (thread);
  tls_current_object = 0B;
  current_object_key.51 = current_object_key;
  mono_native_tls_set_value (current_object_key.51, 0B);
  mono_domain_unset ();
  D.23172 = mono_thread_get_main ();
  if (D.23172 != 0B) goto <D.23173>; else goto <D.23174>;
  <D.23173>:
  D.23175 = mono_thread_get_main ();
  D.23176 = D.23175->internal_thread;
  if (D.23176 == thread) goto <D.23177>; else goto <D.23178>;
  <D.23177>:
  D.23179 = mono_environment_exitcode_get ();
  exit (D.23179);
  <D.23178>:
  <D.23174>:
  ExitThread (4294967295);
}


ves_icall_System_Threading_Thread_ConstructInternalThread (struct MonoThread * this)
{
  struct _MonoInternalThread * * D.23180;
  struct MonoInternalThread * internal;

  internal = create_internal_thread ();
  internal->state = 8;
  D.23180 = &this->internal_thread;
  InterlockedCompareExchangePointer (D.23180, internal, 0B);
}


ves_icall_System_Threading_Thread_Thread_internal (struct MonoThread * this, struct MonoObject * start)
{
  struct _MonoInternalThread * D.23181;
  unsigned int D.23184;
  unsigned int D.23185;
  struct MonoException * D.23188;
  void * D.23189;
  unsigned int D.23190;
  struct MonoObject * D.23193;
  struct MonoVTable * D.23194;
  struct MonoDomain * D.23195;
  struct MonoDomain * D.23196;
  _Bool D.23197;
  long int D.23198;
  long int D.23199;
  unsigned int D.23204;
  struct StartInfo * start_info;
  struct MonoInternalThread * internal;
  gboolean res;

  D.23181 = this->internal_thread;
  if (D.23181 == 0B) goto <D.23182>; else goto <D.23183>;
  <D.23182>:
  ves_icall_System_Threading_Thread_ConstructInternalThread (this);
  <D.23183>:
  internal = this->internal_thread;
  lock_thread (internal);
  D.23184 = internal->state;
  D.23185 = D.23184 & 8;
  if (D.23185 == 0) goto <D.23186>; else goto <D.23187>;
  <D.23186>:
  unlock_thread (internal);
  D.23188 = mono_get_exception_thread_state ("Thread has already been started.");
  mono_raise_exception (D.23188);
  D.23189 = 0B;
  return D.23189;
  <D.23187>:
  D.23184 = internal->state;
  D.23190 = D.23184 & 256;
  if (D.23190 != 0) goto <D.23191>; else goto <D.23192>;
  <D.23191>:
  unlock_thread (internal);
  D.23189 = this;
  return D.23189;
  <D.23192>:
  start_info = monoeg_malloc0 (16);
  start_info->func = 0B;
  D.23193 = this->start_obj;
  start_info->start_arg = D.23193;
  start_info->delegate = start;
  start_info->obj = this;
  D.23194 = this->obj.vtable;
  D.23195 = D.23194->domain;
  D.23196 = mono_domain_get ();
  D.23197 = D.23195 != D.23196;
  D.23198 = (long int) D.23197;
  D.23199 = __builtin_expect (D.23198, 0);
  if (D.23199 != 0) goto <D.23200>; else goto <D.23201>;
  <D.23200>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1169, "this->obj.vtable->domain == mono_domain_get ()");
  <D.23201>:
  res = create_thread (this, internal, start_info, 0, 0, 0, 0);
  if (res == 0) goto <D.23202>; else goto <D.23203>;
  <D.23202>:
  unlock_thread (internal);
  D.23189 = 0B;
  return D.23189;
  <D.23203>:
  D.23184 = internal->state;
  D.23204 = D.23184 & 4294967287;
  internal->state = D.23204;
  unlock_thread (internal);
  D.23189 = internal->handle;
  return D.23189;
}


ves_icall_System_Threading_InternalThread_Thread_free_internal (struct MonoInternalThread * this, void * thread)
{
  struct CRITICAL_SECTION * D.23208;
  gunichar2 * D.23211;

  if (thread != 0B) goto <D.23206>; else goto <D.23207>;
  <D.23206>:
  CloseHandle (thread);
  <D.23207>:
  D.23208 = this->synch_cs;
  if (D.23208 != 0B) goto <D.23209>; else goto <D.23210>;
  <D.23209>:
  {
    struct CRITICAL_SECTION * synch_cs;

    synch_cs = this->synch_cs;
    this->synch_cs = 0B;
    DeleteCriticalSection (synch_cs);
    monoeg_g_free (synch_cs);
  }
  <D.23210>:
  D.23211 = this->name;
  if (D.23211 != 0B) goto <D.23212>; else goto <D.23213>;
  <D.23212>:
  {
    void * name;

    name = this->name;
    this->name = 0B;
    monoeg_g_free (name);
  }
  <D.23213>:
}


ves_icall_System_Threading_Thread_Sleep_internal (gint32 ms)
{
  unsigned int ms.52;
  guint32 res;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  <D.21356>:
  mono_thread_set_state (thread, 32);
  ms.52 = (unsigned int) ms;
  res = SleepEx (ms.52, 1);
  mono_thread_clr_state (thread, 32);
  if (res == 192) goto <D.23215>; else goto <D.21355>;
  <D.23215>:
  {
    struct MonoException * exc;

    exc = mono_thread_execute_interruption (thread);
    if (exc != 0B) goto <D.23216>; else goto <D.23217>;
    <D.23216>:
    mono_raise_exception (exc);
    goto <D.23218>;
    <D.23217>:
    if (ms != -1) goto <D.21355>; else goto <D.23219>;
    <D.23219>:
    <D.23218>:
  }
  goto <D.21356>;
  <D.21355>:
}


mono_thread_execute_interruption (struct MonoInternalThread * thread)
{
  gint32 * D.23220;
  int D.23221;
  void * D.23224;
  unsigned int D.23225;
  unsigned int D.23226;
  struct MonoException * D.23229;
  struct MonoException * * D.23232;
  struct MonoException * D.23233;
  struct MonoException * D.23234;
  unsigned int D.23235;
  unsigned int D.23238;
  struct MonoException * D.23241;
  unsigned char D.23244;

  lock_thread (thread);
  D.23220 = &thread->interruption_requested;
  D.23221 = InterlockedCompareExchange (D.23220, 0, 1);
  if (D.23221 != 0) goto <D.23222>; else goto <D.23223>;
  <D.23222>:
  D.23224 = GetCurrentThread ();
  WaitForSingleObjectEx (D.23224, 0, 1);
  InterlockedDecrement (&thread_interruption_requested);
  wapi_clear_interruption ();
  <D.23223>:
  D.23225 = thread->state;
  D.23226 = D.23225 & 128;
  if (D.23226 != 0) goto <D.23227>; else goto <D.23228>;
  <D.23227>:
  unlock_thread (thread);
  D.23229 = thread->abort_exc;
  if (D.23229 == 0B) goto <D.23230>; else goto <D.23231>;
  <D.23230>:
  D.23232 = &thread->abort_exc;
  D.23233 = mono_get_exception_thread_abort ();
  mono_gc_wbarrier_set_field (thread, D.23232, D.23233);
  <D.23231>:
  D.23234 = thread->abort_exc;
  return D.23234;
  <D.23228>:
  D.23225 = thread->state;
  D.23235 = D.23225 & 2;
  if (D.23235 != 0) goto <D.23236>; else goto <D.23237>;
  <D.23236>:
  self_suspend_internal (thread);
  D.23234 = 0B;
  return D.23234;
  <D.23237>:
  D.23225 = thread->state;
  D.23238 = D.23225 & 1;
  if (D.23238 != 0) goto <D.23239>; else goto <D.23240>;
  <D.23239>:
  unlock_thread (thread);
  mono_thread_exit ();
  D.23234 = 0B;
  return D.23234;
  <D.23240>:
  D.23241 = thread->pending_exception;
  if (D.23241 != 0B) goto <D.23242>; else goto <D.23243>;
  <D.23242>:
  {
    struct MonoException * exc;

    exc = thread->pending_exception;
    thread->pending_exception = 0B;
    unlock_thread (thread);
    D.23234 = exc;
    return D.23234;
  }
  <D.23243>:
  D.23244 = thread->thread_interrupt_requested;
  if (D.23244 != 0) goto <D.23245>; else goto <D.23246>;
  <D.23245>:
  thread->thread_interrupt_requested = 0;
  unlock_thread (thread);
  D.23234 = mono_get_exception_thread_interrupted ();
  return D.23234;
  <D.23246>:
  unlock_thread (thread);
  D.23234 = 0B;
  return D.23234;
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.23248;
  unsigned int comp.53;
  unsigned int exch.54;
  unsigned int D.23251;

  comp.53 = (unsigned int) comp;
  exch.54 = (unsigned int) exch;
  D.23251 = __sync_val_compare_and_swap_4 (dest, comp.53, exch.54);
  D.23248 = (gint32) D.23251;
  return D.23248;
}


self_suspend_internal (struct MonoInternalThread * thread)
{
  int D.23253;
  unsigned int D.23256;
  unsigned int D.23257;
  unsigned int D.23258;
  void * D.23259;
  void * D.23260;
  void * D.23263;
  int shutting_down.55;
  unsigned int D.23269;
  void * D.23270;

  D.23253 = mono_thread_info_new_interrupt_enabled ();
  if (D.23253 == 0) goto <D.23254>; else goto <D.23255>;
  <D.23254>:
  D.23256 = thread->state;
  D.23257 = D.23256 & 4294967293;
  thread->state = D.23257;
  D.23256 = thread->state;
  D.23258 = D.23256 | 64;
  thread->state = D.23258;
  D.23259 = CreateEvent (0B, 1, 0, 0B);
  thread->suspend_event = D.23259;
  D.23260 = thread->suspend_event;
  if (D.23260 == 0B) goto <D.23261>; else goto <D.23262>;
  <D.23261>:
  unlock_thread (thread);
  return;
  <D.23262>:
  D.23263 = thread->suspended_event;
  if (D.23263 != 0B) goto <D.23264>; else goto <D.23265>;
  <D.23264>:
  D.23263 = thread->suspended_event;
  SetEvent (D.23263);
  <D.23265>:
  unlock_thread (thread);
  shutting_down.55 = shutting_down;
  if (shutting_down.55 != 0) goto <D.23267>; else goto <D.23268>;
  <D.23267>:
  <D.22531>:
  Sleep (1000);
  goto <D.22531>;
  <D.23268>:
  D.23260 = thread->suspend_event;
  WaitForSingleObject (D.23260, 4294967295);
  lock_thread (thread);
  D.23260 = thread->suspend_event;
  CloseHandle (D.23260);
  thread->suspend_event = 0B;
  D.23256 = thread->state;
  D.23269 = D.23256 & 4294967231;
  thread->state = D.23269;
  D.23270 = thread->resume_event;
  SetEvent (D.23270);
  unlock_thread (thread);
  return;
  <D.23255>:
  transition_to_suspended (thread);
  mono_thread_info_self_suspend ();
}


transition_to_suspended (struct MonoInternalThread * thread)
{
  unsigned int D.23272;
  unsigned int D.23273;
  long long unsigned int D.23278;
  long unsigned int D.23279;
  unsigned int D.23281;
  unsigned int D.23282;

  D.23272 = thread->state;
  D.23273 = D.23272 & 2;
  if (D.23273 == 0) goto <D.23274>; else goto <D.23275>;
  <D.23274>:
  if (1 != 0) goto <D.23276>; else goto <D.23277>;
  <D.23276>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4693, "0");
  <D.23277>:
  D.23278 = thread->tid;
  D.23279 = (long unsigned int) D.23278;
  mono_thread_info_resume (D.23279);
  goto <D.23280>;
  <D.23275>:
  D.23272 = thread->state;
  D.23281 = D.23272 & 4294967293;
  thread->state = D.23281;
  D.23272 = thread->state;
  D.23282 = D.23272 | 64;
  thread->state = D.23282;
  mono_thread_info_finish_suspend ();
  <D.23280>:
  unlock_thread (thread);
}


ves_icall_System_Threading_Thread_SpinWait_nop ()
{

}


ves_icall_System_Threading_Thread_GetDomainID ()
{
  gint32 D.23283;
  struct MonoDomain * D.23284;

  D.23284 = mono_domain_get ();
  D.23283 = D.23284->domain_id;
  return D.23283;
}


ves_icall_System_Threading_Thread_Yield ()
{
  gboolean D.23286;
  int D.23287;
  _Bool D.23288;

  D.23287 = sched_yield ();
  D.23288 = D.23287 == 0;
  D.23286 = (gboolean) D.23288;
  return D.23286;
}


mono_thread_get_name (struct MonoInternalThread * this_obj, guint32 * name_len)
{
  gunichar2 * D.23290;
  unsigned int D.23294;
  unsigned int D.23295;
  gunichar2 * D.23296;
  gunichar2 * res;

  lock_thread (this_obj);
  D.23290 = this_obj->name;
  if (D.23290 == 0B) goto <D.23291>; else goto <D.23292>;
  <D.23291>:
  *name_len = 0;
  res = 0B;
  goto <D.23293>;
  <D.23292>:
  D.23294 = this_obj->name_len;
  *name_len = D.23294;
  D.23294 = this_obj->name_len;
  D.23295 = D.23294 * 2;
  res = monoeg_malloc (D.23295);
  D.23290 = this_obj->name;
  D.23294 = this_obj->name_len;
  D.23295 = D.23294 * 2;
  memcpy (res, D.23290, D.23295);
  <D.23293>:
  unlock_thread (this_obj);
  D.23296 = res;
  return D.23296;
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.23298;
  unsigned int D.23299;

  D.23299 = __builtin_object_size (__dest, 0);
  D.23298 = __builtin___memcpy_chk (__dest, __src, __len, D.23299);
  return D.23298;
}


ves_icall_System_Threading_Thread_GetName_internal (struct MonoInternalThread * this_obj)
{
  gunichar2 * D.23301;
  struct MonoDomain * D.23305;
  unsigned int D.23306;
  int D.23307;
  struct MonoString * D.23308;
  struct MonoString * str;

  lock_thread (this_obj);
  D.23301 = this_obj->name;
  if (D.23301 == 0B) goto <D.23302>; else goto <D.23303>;
  <D.23302>:
  str = 0B;
  goto <D.23304>;
  <D.23303>:
  D.23305 = mono_domain_get ();
  D.23301 = this_obj->name;
  D.23306 = this_obj->name_len;
  D.23307 = (int) D.23306;
  str = mono_string_new_utf16 (D.23305, D.23301, D.23307);
  <D.23304>:
  unlock_thread (this_obj);
  D.23308 = str;
  return D.23308;
}


mono_thread_set_name_internal (struct MonoInternalThread * this_obj, struct MonoString * name, gboolean managed)
{
  unsigned int D.23310;
  unsigned int D.23311;
  struct MonoException * D.23314;
  int D.23317;
  unsigned int D.23318;
  unsigned int D.23319;
  void * D.23320;
  gunichar2 * D.23321;
  mono_unichar2 * D.23322;
  int D.23323;
  int D.23324;
  unsigned int D.23325;
  int D.23326;
  unsigned int D.23327;
  unsigned int D.23331;
  long long unsigned int D.23334;
  unsigned int D.23335;

  lock_thread (this_obj);
  D.23310 = this_obj->flags;
  D.23311 = D.23310 & 2;
  if (D.23311 != 0) goto <D.23312>; else goto <D.23313>;
  <D.23312>:
  unlock_thread (this_obj);
  D.23314 = mono_get_exception_invalid_operation ("Thread.Name can only be set once.");
  mono_raise_exception (D.23314);
  return;
  <D.23313>:
  if (name != 0B) goto <D.23315>; else goto <D.23316>;
  <D.23315>:
  D.23317 = mono_string_length (name);
  D.23318 = (unsigned int) D.23317;
  D.23319 = D.23318 * 2;
  D.23320 = monoeg_malloc (D.23319);
  this_obj->name = D.23320;
  D.23321 = this_obj->name;
  D.23322 = mono_string_chars (name);
  D.23323 = mono_string_length (name);
  D.23324 = D.23323 * 2;
  D.23325 = (unsigned int) D.23324;
  memcpy (D.23321, D.23322, D.23325);
  D.23326 = mono_string_length (name);
  D.23327 = (unsigned int) D.23326;
  this_obj->name_len = D.23327;
  goto <D.23328>;
  <D.23316>:
  this_obj->name = 0B;
  <D.23328>:
  if (managed != 0) goto <D.23329>; else goto <D.23330>;
  <D.23329>:
  D.23310 = this_obj->flags;
  D.23331 = D.23310 | 2;
  this_obj->flags = D.23331;
  <D.23330>:
  unlock_thread (this_obj);
  D.23321 = this_obj->name;
  if (D.23321 != 0B) goto <D.23332>; else goto <D.23333>;
  <D.23332>:
  {
    char * tname;

    tname = mono_string_to_utf8 (name);
    D.23334 = this_obj->tid;
    D.23335 = (unsigned int) D.23334;
    mono_profiler_thread_name (D.23335, tname);
    mono_free (tname);
  }
  <D.23333>:
}


ves_icall_System_Threading_Thread_SetName_internal (struct MonoInternalThread * this_obj, struct MonoString * name)
{
  mono_thread_set_name_internal (this_obj, name, 1);
}


ves_icall_System_Threading_Thread_ByteArrayToRootDomain (struct MonoArray * arr)
{
  struct MonoArray * D.23337;
  struct MonoDomain * D.23338;

  D.23338 = mono_get_root_domain ();
  D.23337 = byte_array_to_domain (arr, D.23338);
  return D.23337;
}


byte_array_to_domain (struct MonoArray * arr, struct MonoDomain * domain)
{
  struct MonoArray * D.23342;
  struct MonoVTable * D.23343;
  struct MonoDomain * D.23344;
  struct MonoClass * D.23347;
  unsigned int D.23348;
  char * D.23349;
  char * D.23350;
  struct MonoArray * copy;

  if (arr == 0B) goto <D.23340>; else goto <D.23341>;
  <D.23340>:
  D.23342 = 0B;
  return D.23342;
  <D.23341>:
  D.23343 = MEM[(struct MonoObject *)arr].vtable;
  D.23344 = D.23343->domain;
  if (D.23344 == domain) goto <D.23345>; else goto <D.23346>;
  <D.23345>:
  D.23342 = arr;
  return D.23342;
  <D.23346>:
  D.23347 = mono_defaults.byte_class;
  D.23348 = arr->max_length;
  copy = mono_array_new (domain, D.23347, D.23348);
  D.23349 = mono_array_addr_with_size (copy, 1, 0);
  D.23350 = mono_array_addr_with_size (arr, 1, 0);
  D.23348 = arr->max_length;
  memmove (D.23349, D.23350, D.23348);
  D.23342 = copy;
  return D.23342;
}


memmove (void * __dest, const void * __src, size_t __len)
{
  void * D.23352;
  unsigned int D.23353;

  D.23353 = __builtin_object_size (__dest, 0);
  D.23352 = __builtin___memmove_chk (__dest, __src, __len, D.23353);
  return D.23352;
}


ves_icall_System_Threading_Thread_ByteArrayToCurrentDomain (struct MonoArray * arr)
{
  struct MonoArray * D.23355;
  struct MonoDomain * D.23356;

  D.23356 = mono_domain_get ();
  D.23355 = byte_array_to_domain (arr, D.23356);
  return D.23355;
}


mono_thread_current ()
{
  _Bool D.23358;
  long int D.23359;
  long int D.23360;
  struct MonoThread * D.23363;
  struct MonoDomain * D.23366;
  _Bool D.23367;
  long int D.23368;
  long int D.23369;
  struct MonoThread * D.23372;
  struct MonoThread * D.23373;
  struct MonoDomain * domain;
  struct MonoInternalThread * internal;
  struct MonoThread * * current_thread_ptr;

  domain = mono_domain_get ();
  internal = mono_thread_internal_current ();
  D.23358 = internal == 0B;
  D.23359 = (long int) D.23358;
  D.23360 = __builtin_expect (D.23359, 0);
  if (D.23360 != 0) goto <D.23361>; else goto <D.23362>;
  <D.23361>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1382, "internal");
  <D.23362>:
  current_thread_ptr = get_current_thread_ptr_for_domain (domain, internal);
  D.23363 = *current_thread_ptr;
  if (D.23363 == 0B) goto <D.23364>; else goto <D.23365>;
  <D.23364>:
  D.23366 = mono_get_root_domain ();
  D.23367 = D.23366 == domain;
  D.23368 = (long int) D.23367;
  D.23369 = __builtin_expect (D.23368, 0);
  if (D.23369 != 0) goto <D.23370>; else goto <D.23371>;
  <D.23370>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1386, "domain != mono_get_root_domain ()");
  <D.23371>:
  D.23372 = new_thread_with_internal (domain, internal);
  *current_thread_ptr = D.23372;
  <D.23365>:
  D.23373 = *current_thread_ptr;
  return D.23373;
}


mono_thread_internal_current ()
{
  struct MonoInternalThread * D.23375;
  struct MonoInternalThread * res;

  res = tls_current_object;
  D.23375 = res;
  return D.23375;
}


ves_icall_System_Threading_Thread_Join_internal (struct MonoInternalThread * this, int ms, void * thread)
{
  unsigned int D.23377;
  unsigned int D.23378;
  struct MonoException * D.23381;
  gboolean D.23382;
  unsigned int ms.56;
  unsigned int D.23386;
  struct MonoInternalThread * cur_thread;
  gboolean ret;

  cur_thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  lock_thread (this);
  D.23377 = this->state;
  D.23378 = D.23377 & 8;
  if (D.23378 != 0) goto <D.23379>; else goto <D.23380>;
  <D.23379>:
  unlock_thread (this);
  D.23381 = mono_get_exception_thread_state ("Thread has not been started.");
  mono_raise_exception (D.23381);
  D.23382 = 0;
  return D.23382;
  <D.23380>:
  unlock_thread (this);
  if (ms == -1) goto <D.23383>; else goto <D.23384>;
  <D.23383>:
  ms = -1;
  <D.23384>:
  mono_thread_set_state (cur_thread, 32);
  ms.56 = (unsigned int) ms;
  D.23386 = WaitForSingleObjectEx (thread, ms.56, 1);
  ret = (gboolean) D.23386;
  mono_thread_clr_state (cur_thread, 32);
  if (ret == 0) goto <D.23387>; else goto <D.23388>;
  <D.23387>:
  D.23382 = 1;
  return D.23382;
  <D.23388>:
  D.23382 = 0;
  return D.23382;
}


ves_icall_System_Threading_WaitHandle_WaitAll_internal (struct MonoArray * mono_handles, gint32 ms, gboolean exitContext)
{
  unsigned int D.23390;
  char * D.23391;
  unsigned int D.23392;
  void * * D.23393;
  void * D.23394;
  int D.23397;
  gboolean D.23400;
  void * * handles;
  guint32 numhandles;
  guint32 ret;
  guint32 i;
  struct MonoObject * waitHandle;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  numhandles = mono_array_length (mono_handles);
  D.23390 = numhandles * 4;
  handles = monoeg_malloc0 (D.23390);
  i = 0;
  goto <D.21442>;
  <D.21441>:
  D.23391 = mono_array_addr_with_size (mono_handles, 4, i);
  waitHandle = MEM[(struct MonoObject * *)D.23391];
  D.23392 = i * 4;
  D.23393 = handles + D.23392;
  D.23394 = mono_wait_handle_get_handle (waitHandle);
  *D.23393 = D.23394;
  i = i + 1;
  <D.21442>:
  if (i < numhandles) goto <D.21441>; else goto <D.21443>;
  <D.21443>:
  if (ms == -1) goto <D.23395>; else goto <D.23396>;
  <D.23395>:
  ms = -1;
  <D.23396>:
  mono_thread_set_state (thread, 32);
  D.23397 = mono_wait_uninterrupted (thread, 1, numhandles, handles, 1, ms, 1);
  ret = (guint32) D.23397;
  mono_thread_clr_state (thread, 32);
  monoeg_g_free (handles);
  if (ret == 4294967295) goto <D.23398>; else goto <D.23399>;
  <D.23398>:
  D.23400 = 0;
  return D.23400;
  <D.23399>:
  if (ret == 258) goto <D.23401>; else goto <D.23402>;
  <D.23401>:
  D.23400 = 0;
  return D.23400;
  <D.23402>:
  D.23400 = 1;
  return D.23400;
}


mono_wait_uninterrupted (struct MonoInternalThread * thread, gboolean multiple, guint32 numhandles, void * * handles, gboolean waitall, gint32 ms, gboolean alertable)
{
  gint64 iftmp.57;
  unsigned int wait.58;
  void * D.23412;
  unsigned int ms.59;
  long long int D.23419;
  long long int D.23420;
  long long int D.23421;
  gint32 D.23424;
  struct MonoException * exc;
  guint32 ret;
  gint64 start;
  gint32 diff_ms;
  gint32 wait;

  wait = ms;
  if (ms != -1) goto <D.23405>; else goto <D.23406>;
  <D.23405>:
  iftmp.57 = mono_100ns_ticks ();
  goto <D.23407>;
  <D.23406>:
  iftmp.57 = 0;
  <D.23407>:
  start = iftmp.57;
  <D.21429>:
  if (multiple != 0) goto <D.23408>; else goto <D.23409>;
  <D.23408>:
  wait.58 = (unsigned int) wait;
  ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait.58, alertable);
  goto <D.23411>;
  <D.23409>:
  D.23412 = *handles;
  ms.59 = (unsigned int) ms;
  ret = WaitForSingleObjectEx (D.23412, ms.59, alertable);
  <D.23411>:
  if (ret != 192) goto <D.21427>; else goto <D.23414>;
  <D.23414>:
  exc = mono_thread_execute_interruption (thread);
  if (exc != 0B) goto <D.23415>; else goto <D.23416>;
  <D.23415>:
  mono_raise_exception (exc);
  <D.23416>:
  if (ms == -1) goto <D.23417>; else goto <D.23418>;
  <D.23417>:
  // predicted unlikely by continue predictor.
  goto <D.21428>;
  <D.23418>:
  D.23419 = mono_100ns_ticks ();
  D.23420 = D.23419 - start;
  D.23421 = D.23420 / 10000;
  diff_ms = (gint32) D.23421;
  if (diff_ms >= ms) goto <D.23422>; else goto <D.23423>;
  <D.23422>:
  ret = 258;
  goto <D.21427>;
  <D.23423>:
  wait = ms - diff_ms;
  <D.21428>:
  goto <D.21429>;
  <D.21427>:
  D.23424 = (gint32) ret;
  return D.23424;
}


ves_icall_System_Threading_WaitHandle_WaitAny_internal (struct MonoArray * mono_handles, gint32 ms, gboolean exitContext)
{
  gint32 D.23428;
  char * D.23429;
  void * D.23430;
  int D.23433;
  unsigned int D.23434;
  unsigned int D.23439;
  unsigned int D.23441;
  void * handles[64];
  guint32 numhandles;
  guint32 ret;
  guint32 i;
  struct MonoObject * waitHandle;
  struct MonoInternalThread * thread;

  try
    {
      thread = mono_thread_internal_current ();
      mono_thread_current_check_pending_interrupt ();
      numhandles = mono_array_length (mono_handles);
      if (numhandles > 64) goto <D.23426>; else goto <D.23427>;
      <D.23426>:
      D.23428 = -1;
      return D.23428;
      <D.23427>:
      i = 0;
      goto <D.21456>;
      <D.21455>:
      D.23429 = mono_array_addr_with_size (mono_handles, 4, i);
      waitHandle = MEM[(struct MonoObject * *)D.23429];
      D.23430 = mono_wait_handle_get_handle (waitHandle);
      handles[i] = D.23430;
      i = i + 1;
      <D.21456>:
      if (i < numhandles) goto <D.21455>; else goto <D.21457>;
      <D.21457>:
      if (ms == -1) goto <D.23431>; else goto <D.23432>;
      <D.23431>:
      ms = -1;
      <D.23432>:
      mono_thread_set_state (thread, 32);
      D.23433 = mono_wait_uninterrupted (thread, 1, numhandles, &handles, 0, ms, 1);
      ret = (guint32) D.23433;
      mono_thread_clr_state (thread, 32);
      D.23434 = numhandles + 4294967295;
      if (D.23434 >= ret) goto <D.23435>; else goto <D.23436>;
      <D.23435>:
      D.23428 = (gint32) ret;
      return D.23428;
      <D.23436>:
      if (ret > 127) goto <D.23438>; else goto <D.23437>;
      <D.23438>:
      D.23439 = numhandles + 127;
      if (D.23439 >= ret) goto <D.23440>; else goto <D.23437>;
      <D.23440>:
      D.23441 = ret + 4294967168;
      D.23428 = (gint32) D.23441;
      return D.23428;
      <D.23437>:
      D.23428 = (gint32) ret;
      return D.23428;
    }
  finally
    {
      handles = {CLOBBER};
    }
}


ves_icall_System_Threading_WaitHandle_WaitOne_internal (struct MonoObject * this, void * handle, gint32 ms, gboolean exitContext)
{
  int D.23446;
  gboolean D.23449;
  guint32 ret;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (ms == -1) goto <D.23444>; else goto <D.23445>;
  <D.23444>:
  ms = -1;
  <D.23445>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.23446 = mono_wait_uninterrupted (thread, 0, 1, &handle, 0, ms, 1);
  ret = (guint32) D.23446;
  mono_thread_clr_state (thread, 32);
  if (ret == 4294967295) goto <D.23447>; else goto <D.23448>;
  <D.23447>:
  D.23449 = 0;
  return D.23449;
  <D.23448>:
  if (ret == 258) goto <D.23450>; else goto <D.23451>;
  <D.23450>:
  D.23449 = 0;
  return D.23449;
  <D.23451>:
  D.23449 = 1;
  return D.23449;
}


ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (void * toSignal, void * toWait, gint32 ms, gboolean exitContext)
{
  unsigned int ms.60;
  gboolean D.23456;
  int iftmp.61;
  _Bool D.23460;
  _Bool D.23461;
  _Bool D.23462;
  guint32 ret;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (ms == -1) goto <D.23453>; else goto <D.23454>;
  <D.23453>:
  ms = -1;
  <D.23454>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  ms.60 = (unsigned int) ms;
  ret = SignalObjectAndWait (toSignal, toWait, ms.60, 1);
  mono_thread_clr_state (thread, 32);
  D.23460 = ret != 258;
  D.23461 = ret != 192;
  D.23462 = D.23460 & D.23461;
  if (D.23462 != 0) goto <D.23463>; else goto <D.23458>;
  <D.23463>:
  if (ret != 4294967295) goto <D.23464>; else goto <D.23458>;
  <D.23464>:
  iftmp.61 = 1;
  goto <D.23459>;
  <D.23458>:
  iftmp.61 = 0;
  <D.23459>:
  D.23456 = iftmp.61;
  return D.23456;
}


ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, struct MonoString * name, MonoBoolean * created)
{
  int D.23468;
  mono_unichar2 * D.23470;
  unsigned int D.23471;
  void * D.23474;
  void * mutex;

  *created = 1;
  if (name == 0B) goto <D.23466>; else goto <D.23467>;
  <D.23466>:
  D.23468 = (int) owned;
  mutex = CreateMutex (0B, D.23468, 0B);
  goto <D.23469>;
  <D.23467>:
  D.23468 = (int) owned;
  D.23470 = mono_string_chars (name);
  mutex = CreateMutex (0B, D.23468, D.23470);
  D.23471 = GetLastError ();
  if (D.23471 == 183) goto <D.23472>; else goto <D.23473>;
  <D.23472>:
  *created = 0;
  <D.23473>:
  <D.23469>:
  D.23474 = mutex;
  return D.23474;
}


ves_icall_System_Threading_Mutex_ReleaseMutex_internal (void * handle)
{
  MonoBoolean D.23476;
  int D.23477;

  D.23477 = ReleaseMutex (handle);
  D.23476 = (MonoBoolean) D.23477;
  return D.23476;
}


ves_icall_System_Threading_Mutex_OpenMutex_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.62;
  mono_unichar2 * D.23480;
  unsigned int D.23483;
  int D.23484;
  void * D.23485;
  void * ret;

  *error = 0;
  rights.62 = (unsigned int) rights;
  D.23480 = mono_string_chars (name);
  ret = OpenMutex (rights.62, 0, D.23480);
  if (ret == 0B) goto <D.23481>; else goto <D.23482>;
  <D.23481>:
  D.23483 = GetLastError ();
  D.23484 = (int) D.23483;
  *error = D.23484;
  <D.23482>:
  D.23485 = ret;
  return D.23485;
}


ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, struct MonoString * name, MonoBoolean * created)
{
  mono_unichar2 * D.23490;
  unsigned int D.23491;
  void * D.23494;
  void * sem;

  *created = 1;
  if (name == 0B) goto <D.23487>; else goto <D.23488>;
  <D.23487>:
  sem = CreateSemaphore (0B, initialCount, maximumCount, 0B);
  goto <D.23489>;
  <D.23488>:
  D.23490 = mono_string_chars (name);
  sem = CreateSemaphore (0B, initialCount, maximumCount, D.23490);
  D.23491 = GetLastError ();
  if (D.23491 == 183) goto <D.23492>; else goto <D.23493>;
  <D.23492>:
  *created = 0;
  <D.23493>:
  <D.23489>:
  D.23494 = sem;
  return D.23494;
}


ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (void * handle, gint32 releaseCount, MonoBoolean * fail)
{
  int D.23496;
  _Bool D.23497;
  unsigned char D.23498;
  gint32 D.23499;
  gint32 prevcount;

  try
    {
      D.23496 = ReleaseSemaphore (handle, releaseCount, &prevcount);
      D.23497 = D.23496 == 0;
      D.23498 = (unsigned char) D.23497;
      *fail = D.23498;
      D.23499 = prevcount;
      return D.23499;
    }
  finally
    {
      prevcount = {CLOBBER};
    }
}


ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.63;
  mono_unichar2 * D.23503;
  unsigned int D.23506;
  int D.23507;
  void * D.23508;
  void * ret;

  *error = 0;
  rights.63 = (unsigned int) rights;
  D.23503 = mono_string_chars (name);
  ret = OpenSemaphore (rights.63, 0, D.23503);
  if (ret == 0B) goto <D.23504>; else goto <D.23505>;
  <D.23504>:
  D.23506 = GetLastError ();
  D.23507 = (int) D.23506;
  *error = D.23507;
  <D.23505>:
  D.23508 = ret;
  return D.23508;
}


ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, struct MonoString * name, MonoBoolean * created)
{
  int D.23512;
  int D.23513;
  mono_unichar2 * D.23515;
  unsigned int D.23516;
  void * D.23519;
  void * event;

  *created = 1;
  if (name == 0B) goto <D.23510>; else goto <D.23511>;
  <D.23510>:
  D.23512 = (int) manual;
  D.23513 = (int) initial;
  event = CreateEvent (0B, D.23512, D.23513, 0B);
  goto <D.23514>;
  <D.23511>:
  D.23512 = (int) manual;
  D.23513 = (int) initial;
  D.23515 = mono_string_chars (name);
  event = CreateEvent (0B, D.23512, D.23513, D.23515);
  D.23516 = GetLastError ();
  if (D.23516 == 183) goto <D.23517>; else goto <D.23518>;
  <D.23517>:
  *created = 0;
  <D.23518>:
  <D.23514>:
  D.23519 = event;
  return D.23519;
}


ves_icall_System_Threading_Events_SetEvent_internal (void * handle)
{
  gboolean D.23521;

  D.23521 = SetEvent (handle);
  return D.23521;
}


ves_icall_System_Threading_Events_ResetEvent_internal (void * handle)
{
  gboolean D.23523;

  D.23523 = ResetEvent (handle);
  return D.23523;
}


ves_icall_System_Threading_Events_CloseEvent_internal (void * handle)
{
  CloseHandle (handle);
}


ves_icall_System_Threading_Events_OpenEvent_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.64;
  mono_unichar2 * D.23526;
  unsigned int D.23529;
  int D.23530;
  void * D.23531;
  void * ret;

  *error = 0;
  rights.64 = (unsigned int) rights;
  D.23526 = mono_string_chars (name);
  ret = OpenEvent (rights.64, 0, D.23526);
  if (ret == 0B) goto <D.23527>; else goto <D.23528>;
  <D.23527>:
  D.23529 = GetLastError ();
  D.23530 = (int) D.23529;
  *error = D.23530;
  <D.23528>:
  D.23531 = ret;
  return D.23531;
}


ves_icall_System_Threading_Interlocked_Increment_Int (gint32 * location)
{
  gint32 D.23533;

  D.23533 = InterlockedIncrement (location);
  return D.23533;
}


ves_icall_System_Threading_Interlocked_Increment_Long (gint64 * location)
{
  unsigned int location.65;
  unsigned int D.23536;
  _Bool D.23537;
  long int D.23538;
  long int D.23539;
  _Bool D.23544;
  long int D.23545;
  long int D.23546;
  long long int D.23549;
  long long int D.23550;
  _Bool D.23553;
  long int D.23554;
  long int D.23555;
  gint64 D.23558;

  location.65 = (unsigned int) location;
  D.23536 = location.65 & 7;
  D.23537 = D.23536 != 0;
  D.23538 = (long int) D.23537;
  D.23539 = __builtin_expect (D.23538, 0);
  if (D.23539 != 0) goto <D.23540>; else goto <D.23541>;
  <D.23540>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23542>; else goto <D.23543>;
      <D.23542>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23543>:
      D.23544 = ret != 0;
      D.23545 = (long int) D.23544;
      D.23546 = __builtin_expect (D.23545, 0);
      if (D.23546 != 0) goto <D.23547>; else goto <D.23548>;
      <D.23547>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1764, "ret == 0");
      <D.23548>:
    }
    D.23549 = *location;
    D.23550 = D.23549 + 1;
    *location = D.23550;
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23551>; else goto <D.23552>;
      <D.23551>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23552>:
      D.23553 = ret != 0;
      D.23554 = (long int) D.23553;
      D.23555 = __builtin_expect (D.23554, 0);
      if (D.23555 != 0) goto <D.23556>; else goto <D.23557>;
      <D.23556>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1767, "ret == 0");
      <D.23557>:
    }
    D.23558 = ret;
    return D.23558;
  }
  <D.23541>:
  D.23558 = InterlockedIncrement64 (location);
  return D.23558;
}


InterlockedIncrement64 (volatile gint64 * val)
{
  long long int D.23560;
  gint64 D.23561;
  gint64 get;
  gint64 set;

  <D.21037>:
  get = *val;
  set = get + 1;
  D.23560 = InterlockedCompareExchange64 (val, set, get);
  if (D.23560 != get) goto <D.21037>; else goto <D.21038>;
  <D.21038>:
  D.23561 = set;
  return D.23561;
}


ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 * location)
{
  gint32 D.23563;

  D.23563 = InterlockedDecrement (location);
  return D.23563;
}


ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
{
  unsigned int location.66;
  unsigned int D.23566;
  _Bool D.23567;
  long int D.23568;
  long int D.23569;
  _Bool D.23574;
  long int D.23575;
  long int D.23576;
  long long int D.23579;
  long long int D.23580;
  _Bool D.23583;
  long int D.23584;
  long int D.23585;
  gint64 D.23588;

  location.66 = (unsigned int) location;
  D.23566 = location.66 & 7;
  D.23567 = D.23566 != 0;
  D.23568 = (long int) D.23567;
  D.23569 = __builtin_expect (D.23568, 0);
  if (D.23569 != 0) goto <D.23570>; else goto <D.23571>;
  <D.23570>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23572>; else goto <D.23573>;
      <D.23572>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23573>:
      D.23574 = ret != 0;
      D.23575 = (long int) D.23574;
      D.23576 = __builtin_expect (D.23575, 0);
      if (D.23576 != 0) goto <D.23577>; else goto <D.23578>;
      <D.23577>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1784, "ret == 0");
      <D.23578>:
    }
    D.23579 = *location;
    D.23580 = D.23579 + -1;
    *location = D.23580;
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23581>; else goto <D.23582>;
      <D.23581>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23582>:
      D.23583 = ret != 0;
      D.23584 = (long int) D.23583;
      D.23585 = __builtin_expect (D.23584, 0);
      if (D.23585 != 0) goto <D.23586>; else goto <D.23587>;
      <D.23586>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1787, "ret == 0");
      <D.23587>:
    }
    D.23588 = ret;
    return D.23588;
  }
  <D.23571>:
  D.23588 = InterlockedDecrement64 (location);
  return D.23588;
}


InterlockedDecrement64 (volatile gint64 * val)
{
  long long int D.23590;
  gint64 D.23591;
  gint64 get;
  gint64 set;

  <D.21044>:
  get = *val;
  set = get + -1;
  D.23590 = InterlockedCompareExchange64 (val, set, get);
  if (D.23590 != get) goto <D.21044>; else goto <D.21045>;
  <D.21045>:
  D.23591 = set;
  return D.23591;
}


ves_icall_System_Threading_Interlocked_Exchange_Int (gint32 * location, gint32 value)
{
  gint32 D.23593;

  D.23593 = InterlockedExchange (location, value);
  return D.23593;
}


ves_icall_System_Threading_Interlocked_Exchange_Object (struct MonoObject * * location, struct MonoObject * value)
{
  struct MonoObject * D.23595;
  struct MonoObject * res;

  res = InterlockedExchangePointer (location, value);
  mono_gc_wbarrier_generic_nostore (location);
  D.23595 = res;
  return D.23595;
}


InterlockedExchangePointer (void * volatile * val, void * new_val)
{
  unsigned int old_val.67;
  unsigned int new_val.68;
  unsigned int D.23599;
  void * D.23600;
  void * D.23601;
  void * old_val;

  <D.20985>:
  old_val = *val;
  old_val.67 = (unsigned int) old_val;
  new_val.68 = (unsigned int) new_val;
  D.23599 = __sync_val_compare_and_swap_4 (val, old_val.67, new_val.68);
  D.23600 = (void *) D.23599;
  if (D.23600 != old_val) goto <D.20985>; else goto <D.20986>;
  <D.20986>:
  D.23601 = old_val;
  return D.23601;
}


ves_icall_System_Threading_Interlocked_Exchange_IntPtr (void * * location, void * value)
{
  void * D.23603;

  D.23603 = InterlockedExchangePointer (location, value);
  return D.23603;
}


ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat * location, gfloat value)
{
  int D.23605;
  int D.23606;
  gfloat D.23607;
  union IntFloatUnion val;
  union IntFloatUnion ret;

  try
    {
      val.fval = value;
      D.23605 = val.ival;
      D.23606 = InterlockedExchange (location, D.23605);
      ret.ival = D.23606;
      D.23607 = ret.fval;
      return D.23607;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
    }
}


ves_icall_System_Threading_Interlocked_Exchange_Long (gint64 * location, gint64 value)
{
  unsigned int location.69;
  unsigned int D.23611;
  _Bool D.23612;
  long int D.23613;
  long int D.23614;
  _Bool D.23619;
  long int D.23620;
  long int D.23621;
  _Bool D.23626;
  long int D.23627;
  long int D.23628;
  gint64 D.23631;

  location.69 = (unsigned int) location;
  D.23611 = location.69 & 7;
  D.23612 = D.23611 != 0;
  D.23613 = (long int) D.23612;
  D.23614 = __builtin_expect (D.23613, 0);
  if (D.23614 != 0) goto <D.23615>; else goto <D.23616>;
  <D.23615>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23617>; else goto <D.23618>;
      <D.23617>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23618>:
      D.23619 = ret != 0;
      D.23620 = (long int) D.23619;
      D.23621 = __builtin_expect (D.23620, 0);
      if (D.23621 != 0) goto <D.23622>; else goto <D.23623>;
      <D.23622>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1828, "ret == 0");
      <D.23623>:
    }
    ret = *location;
    *location = value;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23624>; else goto <D.23625>;
      <D.23624>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23625>:
      D.23626 = ret != 0;
      D.23627 = (long int) D.23626;
      D.23628 = __builtin_expect (D.23627, 0);
      if (D.23628 != 0) goto <D.23629>; else goto <D.23630>;
      <D.23629>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1831, "ret == 0");
      <D.23630>:
    }
    D.23631 = ret;
    return D.23631;
  }
  <D.23616>:
  D.23631 = InterlockedExchange64 (location, value);
  return D.23631;
}


InterlockedExchange64 (volatile gint64 * val, gint64 new_val)
{
  long long int D.23633;
  gint64 D.23634;
  gint64 old_val;

  <D.21069>:
  old_val = *val;
  D.23633 = InterlockedCompareExchange64 (val, new_val, old_val);
  if (D.23633 != old_val) goto <D.21069>; else goto <D.21070>;
  <D.21070>:
  D.23634 = old_val;
  return D.23634;
}


ves_icall_System_Threading_Interlocked_Exchange_Double (gdouble * location, gdouble value)
{
  long long int D.23636;
  long long int D.23637;
  gdouble D.23638;
  union LongDoubleUnion val;
  union LongDoubleUnion ret;

  try
    {
      val.fval = value;
      D.23636 = val.ival;
      D.23637 = InterlockedExchange64 (location, D.23636);
      ret.ival = D.23637;
      D.23638 = ret.fval;
      return D.23638;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
    }
}


ves_icall_System_Threading_Interlocked_CompareExchange_Int (gint32 * location, gint32 value, gint32 comparand)
{
  gint32 D.23641;

  D.23641 = InterlockedCompareExchange (location, value, comparand);
  return D.23641;
}


ves_icall_System_Threading_Interlocked_CompareExchange_Object (struct MonoObject * * location, struct MonoObject * value, struct MonoObject * comparand)
{
  struct MonoObject * D.23643;
  struct MonoObject * res;

  res = InterlockedCompareExchangePointer (location, value, comparand);
  mono_gc_wbarrier_generic_nostore (location);
  D.23643 = res;
  return D.23643;
}


ves_icall_System_Threading_Interlocked_CompareExchange_IntPtr (void * * location, void * value, void * comparand)
{
  void * D.23645;

  D.23645 = InterlockedCompareExchangePointer (location, value, comparand);
  return D.23645;
}


ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat * location, gfloat value, gfloat comparand)
{
  int D.23647;
  int D.23648;
  int D.23649;
  gfloat D.23650;
  union IntFloatUnion val;
  union IntFloatUnion ret;
  union IntFloatUnion cmp;

  try
    {
      val.fval = value;
      cmp.fval = comparand;
      D.23647 = val.ival;
      D.23648 = cmp.ival;
      D.23649 = InterlockedCompareExchange (location, D.23647, D.23648);
      ret.ival = D.23649;
      D.23650 = ret.fval;
      return D.23650;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
      cmp = {CLOBBER};
    }
}


ves_icall_System_Threading_Interlocked_CompareExchange_Double (gdouble * location, gdouble value, gdouble comparand)
{
  _Bool D.23655;
  long int D.23656;
  long int D.23657;
  _Bool D.23664;
  long int D.23665;
  long int D.23666;
  gdouble D.23669;
  gdouble old;

  {
    int ret;

    ret = pthread_mutex_lock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.23653>; else goto <D.23654>;
    <D.23653>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.23654>:
    D.23655 = ret != 0;
    D.23656 = (long int) D.23655;
    D.23657 = __builtin_expect (D.23656, 0);
    if (D.23657 != 0) goto <D.23658>; else goto <D.23659>;
    <D.23658>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1892, "ret == 0");
    <D.23659>:
  }
  old = *location;
  if (old == comparand) goto <D.23660>; else goto <D.23661>;
  <D.23660>:
  *location = value;
  <D.23661>:
  {
    int ret;

    ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.23662>; else goto <D.23663>;
    <D.23662>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.23663>:
    D.23664 = ret != 0;
    D.23665 = (long int) D.23664;
    D.23666 = __builtin_expect (D.23665, 0);
    if (D.23666 != 0) goto <D.23667>; else goto <D.23668>;
    <D.23667>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1896, "ret == 0");
    <D.23668>:
  }
  D.23669 = old;
  return D.23669;
}


ves_icall_System_Threading_Interlocked_CompareExchange_Long (gint64 * location, gint64 value, gint64 comparand)
{
  unsigned int location.70;
  unsigned int D.23672;
  _Bool D.23673;
  long int D.23674;
  long int D.23675;
  _Bool D.23680;
  long int D.23681;
  long int D.23682;
  _Bool D.23689;
  long int D.23690;
  long int D.23691;
  gint64 D.23694;

  location.70 = (unsigned int) location;
  D.23672 = location.70 & 7;
  D.23673 = D.23672 != 0;
  D.23674 = (long int) D.23673;
  D.23675 = __builtin_expect (D.23674, 0);
  if (D.23675 != 0) goto <D.23676>; else goto <D.23677>;
  <D.23676>:
  {
    gint64 old;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23678>; else goto <D.23679>;
      <D.23678>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23679>:
      D.23680 = ret != 0;
      D.23681 = (long int) D.23680;
      D.23682 = __builtin_expect (D.23681, 0);
      if (D.23682 != 0) goto <D.23683>; else goto <D.23684>;
      <D.23683>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1908, "ret == 0");
      <D.23684>:
    }
    old = *location;
    if (old == comparand) goto <D.23685>; else goto <D.23686>;
    <D.23685>:
    *location = value;
    <D.23686>:
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23687>; else goto <D.23688>;
      <D.23687>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23688>:
      D.23689 = ret != 0;
      D.23690 = (long int) D.23689;
      D.23691 = __builtin_expect (D.23690, 0);
      if (D.23691 != 0) goto <D.23692>; else goto <D.23693>;
      <D.23692>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1912, "ret == 0");
      <D.23693>:
    }
    D.23694 = old;
    return D.23694;
  }
  <D.23677>:
  D.23694 = InterlockedCompareExchange64 (location, value, comparand);
  return D.23694;
}


ves_icall_System_Threading_Interlocked_CompareExchange_T (struct MonoObject * * location, struct MonoObject * value, struct MonoObject * comparand)
{
  struct MonoObject * D.23696;
  struct MonoObject * res;

  res = InterlockedCompareExchangePointer (location, value, comparand);
  mono_gc_wbarrier_generic_nostore (location);
  D.23696 = res;
  return D.23696;
}


ves_icall_System_Threading_Interlocked_Exchange_T (struct MonoObject * * location, struct MonoObject * value)
{
  struct MonoObject * D.23698;
  struct MonoObject * res;

  res = InterlockedExchangePointer (location, value);
  mono_gc_wbarrier_generic_nostore (location);
  D.23698 = res;
  return D.23698;
}


ves_icall_System_Threading_Interlocked_Add_Int (gint32 * location, gint32 value)
{
  gint32 D.23700;

  D.23700 = InterlockedAdd (location, value);
  return D.23700;
}


InterlockedAdd (volatile gint32 * dest, gint32 add)
{
  gint32 D.23702;
  unsigned int add.71;
  unsigned int D.23704;

  add.71 = (unsigned int) add;
  D.23704 = __sync_add_and_fetch_4 (dest, add.71);
  D.23702 = (gint32) D.23704;
  return D.23702;
}


ves_icall_System_Threading_Interlocked_Add_Long (gint64 * location, gint64 value)
{
  unsigned int location.72;
  unsigned int D.23707;
  _Bool D.23708;
  long int D.23709;
  long int D.23710;
  _Bool D.23715;
  long int D.23716;
  long int D.23717;
  long long int D.23720;
  long long int D.23721;
  _Bool D.23724;
  long int D.23725;
  long int D.23726;
  gint64 D.23729;

  location.72 = (unsigned int) location;
  D.23707 = location.72 & 7;
  D.23708 = D.23707 != 0;
  D.23709 = (long int) D.23708;
  D.23710 = __builtin_expect (D.23709, 0);
  if (D.23710 != 0) goto <D.23711>; else goto <D.23712>;
  <D.23711>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23713>; else goto <D.23714>;
      <D.23713>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23714>:
      D.23715 = ret != 0;
      D.23716 = (long int) D.23715;
      D.23717 = __builtin_expect (D.23716, 0);
      if (D.23717 != 0) goto <D.23718>; else goto <D.23719>;
      <D.23718>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1949, "ret == 0");
      <D.23719>:
    }
    D.23720 = *location;
    D.23721 = D.23720 + value;
    *location = D.23721;
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23722>; else goto <D.23723>;
      <D.23722>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23723>:
      D.23724 = ret != 0;
      D.23725 = (long int) D.23724;
      D.23726 = __builtin_expect (D.23725, 0);
      if (D.23726 != 0) goto <D.23727>; else goto <D.23728>;
      <D.23727>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1952, "ret == 0");
      <D.23728>:
    }
    D.23729 = ret;
    return D.23729;
  }
  <D.23712>:
  D.23729 = InterlockedAdd64 (location, value);
  return D.23729;
}


InterlockedAdd64 (volatile gint64 * dest, gint64 add)
{
  long long int D.23731;
  gint64 D.23732;
  gint64 get;
  gint64 set;

  <D.21052>:
  get = *dest;
  set = get + add;
  D.23731 = InterlockedCompareExchange64 (dest, set, get);
  if (D.23731 != get) goto <D.21052>; else goto <D.21053>;
  <D.21053>:
  D.23732 = set;
  return D.23732;
}


ves_icall_System_Threading_Interlocked_Read_Long (gint64 * location)
{
  unsigned int location.73;
  unsigned int D.23735;
  _Bool D.23736;
  long int D.23737;
  long int D.23738;
  _Bool D.23743;
  long int D.23744;
  long int D.23745;
  _Bool D.23750;
  long int D.23751;
  long int D.23752;
  gint64 D.23755;

  location.73 = (unsigned int) location;
  D.23735 = location.73 & 7;
  D.23736 = D.23735 != 0;
  D.23737 = (long int) D.23736;
  D.23738 = __builtin_expect (D.23737, 0);
  if (D.23738 != 0) goto <D.23739>; else goto <D.23740>;
  <D.23739>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23741>; else goto <D.23742>;
      <D.23741>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23742>:
      D.23743 = ret != 0;
      D.23744 = (long int) D.23743;
      D.23745 = __builtin_expect (D.23744, 0);
      if (D.23745 != 0) goto <D.23746>; else goto <D.23747>;
      <D.23746>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1965, "ret == 0");
      <D.23747>:
    }
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.23748>; else goto <D.23749>;
      <D.23748>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23749>:
      D.23750 = ret != 0;
      D.23751 = (long int) D.23750;
      D.23752 = __builtin_expect (D.23751, 0);
      if (D.23752 != 0) goto <D.23753>; else goto <D.23754>;
      <D.23753>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1967, "ret == 0");
      <D.23754>:
    }
    D.23755 = ret;
    return D.23755;
  }
  <D.23740>:
  D.23755 = InterlockedRead64 (location);
  return D.23755;
}


InterlockedRead64 (volatile gint64 * src)
{
  gint64 D.23757;

  D.23757 = InterlockedCompareExchange64 (src, 0, 0);
  return D.23757;
}


ves_icall_System_Threading_Thread_MemoryBarrier ()
{
  mono_memory_barrier ();
}


ves_icall_System_Threading_Thread_ClrState (struct MonoInternalThread * this, guint32 state)
{
  unsigned int D.23759;
  void * background_change_event.74;

  mono_thread_clr_state (this, state);
  D.23759 = state & 4;
  if (D.23759 != 0) goto <D.23760>; else goto <D.23761>;
  <D.23760>:
  background_change_event.74 = background_change_event;
  SetEvent (background_change_event.74);
  <D.23761>:
}


ves_icall_System_Threading_Thread_SetState (struct MonoInternalThread * this, guint32 state)
{
  unsigned int D.23763;
  void * background_change_event.75;

  mono_thread_set_state (this, state);
  D.23763 = state & 4;
  if (D.23763 != 0) goto <D.23764>; else goto <D.23765>;
  <D.23764>:
  background_change_event.75 = background_change_event;
  SetEvent (background_change_event.75);
  <D.23765>:
}


ves_icall_System_Threading_Thread_GetState (struct MonoInternalThread * this)
{
  guint32 D.23767;
  guint32 state;

  lock_thread (this);
  state = this->state;
  unlock_thread (this);
  D.23767 = state;
  return D.23767;
}


ves_icall_System_Threading_Thread_Interrupt_internal (struct MonoInternalThread * this)
{
  int iftmp.76;
  unsigned int D.23773;
  unsigned int D.23774;
  struct MonoInternalThread * current;
  gboolean throw;

  lock_thread (this);
  current = mono_thread_internal_current ();
  this->thread_interrupt_requested = 1;
  if (current != this) goto <D.23772>; else goto <D.23770>;
  <D.23772>:
  D.23773 = this->state;
  D.23774 = D.23773 & 32;
  if (D.23774 != 0) goto <D.23775>; else goto <D.23770>;
  <D.23775>:
  iftmp.76 = 1;
  goto <D.23771>;
  <D.23770>:
  iftmp.76 = 0;
  <D.23771>:
  throw = iftmp.76;
  unlock_thread (this);
  if (throw != 0) goto <D.23776>; else goto <D.23777>;
  <D.23776>:
  abort_thread_internal (this, 1, 0);
  <D.23777>:
}


abort_thread_internal (struct MonoInternalThread * thread, gboolean can_raise_exception, gboolean install_async_abort)
{
  int D.23778;
  struct MonoInternalThread * D.23781;
  void * D.23786;
  long long unsigned int D.23787;
  long unsigned int D.23788;
  struct MonoRuntimeExceptionHandlingCallbacks * D.23791;
  gboolean (*<T30db>) (struct MonoThreadUnwindState *) D.23792;
  struct MonoThreadUnwindState * D.23793;
  int D.23794;
  unsigned int D.23797;
  gint32 * D.23798;
  int D.23799;
  int iftmp.77;
  struct MonoMethod * D.23806;
  int D.23807;
  int D.23809;
  void * D.23810;
  _Bool D.23811;
  _Bool D.23812;
  _Bool D.23813;
  struct MonoJitInfo * ji;
  struct MonoThreadInfo * info;
  gboolean protected_wrapper;
  gboolean running_managed;

  info = 0B;
  D.23778 = mono_thread_info_new_interrupt_enabled ();
  if (D.23778 == 0) goto <D.23779>; else goto <D.23780>;
  <D.23779>:
  signal_thread_state_change (thread);
  return;
  <D.23780>:
  D.23781 = mono_thread_internal_current ();
  if (D.23781 == thread) goto <D.23782>; else goto <D.23783>;
  <D.23782>:
  {
    struct MonoException * exc;

    exc = mono_thread_request_interruption (can_raise_exception);
    if (exc != 0B) goto <D.23784>; else goto <D.23785>;
    <D.23784>:
    mono_raise_exception (exc);
    <D.23785>:
    D.23786 = thread->handle;
    wapi_interrupt_thread (D.23786);
    return;
  }
  <D.23783>:
  D.23787 = thread->tid;
  D.23788 = (long unsigned int) D.23787;
  info = mono_thread_info_safe_suspend_sync (D.23788, 1);
  if (info == 0B) goto <D.23789>; else goto <D.23790>;
  <D.23789>:
  return;
  <D.23790>:
  D.23791 = mono_get_eh_callbacks ();
  D.23792 = D.23791->mono_install_handler_block_guard;
  D.23793 = &info->suspend_state;
  D.23794 = D.23792 (D.23793);
  if (D.23794 != 0) goto <D.23795>; else goto <D.23796>;
  <D.23795>:
  D.23797 = info->node.key;
  mono_thread_info_resume (D.23797);
  return;
  <D.23796>:
  D.23798 = &thread->interruption_requested;
  D.23799 = InterlockedCompareExchange (D.23798, 1, 0);
  if (D.23799 == 1) goto <D.23800>; else goto <D.23801>;
  <D.23800>:
  D.23797 = info->node.key;
  mono_thread_info_resume (D.23797);
  return;
  <D.23801>:
  InterlockedIncrement (&thread_interruption_requested);
  ji = mono_thread_info_get_last_managed (info);
  if (ji != 0B) goto <D.23805>; else goto <D.23803>;
  <D.23805>:
  D.23806 = mono_jit_info_get_method (ji);
  D.23807 = mono_threads_is_critical_method (D.23806);
  if (D.23807 != 0) goto <D.23808>; else goto <D.23803>;
  <D.23808>:
  iftmp.77 = 1;
  goto <D.23804>;
  <D.23803>:
  iftmp.77 = 0;
  <D.23804>:
  protected_wrapper = iftmp.77;
  D.23809 = info->suspend_state.ctx.pc;
  D.23810 = (void *) D.23809;
  running_managed = mono_jit_info_match (ji, D.23810);
  D.23811 = protected_wrapper == 0;
  D.23812 = running_managed != 0;
  D.23813 = D.23811 & D.23812;
  if (D.23813 != 0) goto <D.23814>; else goto <D.23815>;
  <D.23814>:
  if (install_async_abort != 0) goto <D.23816>; else goto <D.23817>;
  <D.23816>:
  mono_thread_info_setup_async_call (info, self_interrupt_thread, 0B);
  <D.23817>:
  D.23797 = info->node.key;
  mono_thread_info_resume (D.23797);
  goto <D.23818>;
  <D.23815>:
  {
    void * interrupt_handle;

    D.23786 = thread->handle;
    interrupt_handle = wapi_prepare_interrupt_thread (D.23786);
    D.23797 = info->node.key;
    mono_thread_info_resume (D.23797);
    wapi_finish_interrupt_thread (interrupt_handle);
  }
  <D.23818>:
}


self_interrupt_thread (void * _unused)
{
  struct MonoInternalThread * D.23820;
  struct MonoContext * D.23823;
  struct MonoThreadInfo * info;
  struct MonoException * exc;

  info = mono_thread_info_current ();
  D.23820 = mono_thread_internal_current ();
  exc = mono_thread_execute_interruption (D.23820);
  if (exc != 0B) goto <D.23821>; else goto <D.23822>;
  <D.23821>:
  D.23823 = &info->suspend_state.ctx;
  mono_raise_exception_with_context (exc, D.23823);
  <D.23822>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "threads.c", 4585);
}


signal_thread_state_change (struct MonoInternalThread * thread)
{
  struct MonoInternalThread * D.23824;
  int D.23829;
  void * D.23830;

  D.23824 = mono_thread_internal_current ();
  if (D.23824 == thread) goto <D.23825>; else goto <D.23826>;
  <D.23825>:
  {
    struct MonoException * exc;

    exc = mono_thread_request_interruption (0);
    if (exc != 0B) goto <D.23827>; else goto <D.23828>;
    <D.23827>:
    mono_raise_exception (exc);
    <D.23828>:
  }
  <D.23826>:
  D.23829 = mono_thread_get_abort_signal ();
  mono_thread_kill (thread, D.23829);
  D.23830 = thread->handle;
  wapi_interrupt_thread (D.23830);
}


mono_thread_info_get_last_managed (struct MonoThreadInfo * info)
{
  struct MonoJitInfo * D.23833;
  struct MonoRuntimeExceptionHandlingCallbacks * D.23834;
  void (*<T30cb>) (gboolean (*MonoInternalStackWalk) (struct MonoStackFrameInfo *, struct MonoContext *, void *), struct MonoThreadUnwindState *, MonoUnwindOptions, void *) D.23835;
  struct MonoThreadUnwindState * D.23836;
  struct MonoJitInfo * ji;

  try
    {
      ji = 0B;
      if (info == 0B) goto <D.23831>; else goto <D.23832>;
      <D.23831>:
      D.23833 = 0B;
      return D.23833;
      <D.23832>:
      D.23834 = mono_get_eh_callbacks ();
      D.23835 = D.23834->mono_walk_stack_with_state;
      D.23836 = &info->suspend_state;
      D.23835 (last_managed, D.23836, 0, &ji);
      D.23833 = ji;
      return D.23833;
    }
  finally
    {
      ji = {CLOBBER};
    }
}


last_managed (struct MonoStackFrameInfo * frame, struct MonoContext * ctx, void * data)
{
  struct MonoJitInfo * D.23839;
  gboolean D.23840;
  struct MonoJitInfo * * dest;

  dest = data;
  D.23839 = frame->ji;
  *dest = D.23839;
  D.23840 = 1;
  return D.23840;
}


mono_threads_is_critical_method (struct MonoMethod * method)
{
  <unnamed-unsigned:5> D.23842;
  int D.23843;
  gboolean D.23844;

  D.23842 = method->wrapper_type;
  D.23843 = (int) D.23842;
  switch (D.23843) <default: <D.23845>, case 4: <D.21722>, case 10: <D.21723>, case 11: <D.21724>>
  <D.21722>:
  <D.21723>:
  <D.21724>:
  D.23844 = 1;
  return D.23844;
  <D.23845>:
  D.23844 = 0;
  return D.23844;
}


mono_jit_info_match (struct MonoJitInfo * ji, void * ip)
{
  gboolean D.23849;
  int iftmp.78;
  void * D.23853;
  int D.23855;
  sizetype D.23856;
  char * D.23857;

  if (ji == 0B) goto <D.23847>; else goto <D.23848>;
  <D.23847>:
  D.23849 = 0;
  return D.23849;
  <D.23848>:
  D.23853 = ji->code_start;
  if (D.23853 <= ip) goto <D.23854>; else goto <D.23851>;
  <D.23854>:
  D.23853 = ji->code_start;
  D.23855 = ji->code_size;
  D.23856 = (sizetype) D.23855;
  D.23857 = D.23853 + D.23856;
  if (D.23857 > ip) goto <D.23858>; else goto <D.23851>;
  <D.23858>:
  iftmp.78 = 1;
  goto <D.23852>;
  <D.23851>:
  iftmp.78 = 0;
  <D.23852>:
  D.23849 = iftmp.78;
  return D.23849;
}


mono_thread_current_check_pending_interrupt ()
{
  unsigned char D.23860;
  struct MonoException * D.23865;
  struct MonoInternalThread * thread;
  gboolean throw;

  thread = mono_thread_internal_current ();
  throw = 0;
  lock_thread (thread);
  D.23860 = thread->thread_interrupt_requested;
  if (D.23860 != 0) goto <D.23861>; else goto <D.23862>;
  <D.23861>:
  throw = 1;
  thread->thread_interrupt_requested = 0;
  <D.23862>:
  unlock_thread (thread);
  if (throw != 0) goto <D.23863>; else goto <D.23864>;
  <D.23863>:
  D.23865 = mono_get_exception_thread_interrupted ();
  mono_raise_exception (D.23865);
  <D.23864>:
}


mono_thread_get_abort_signal ()
{
  int abort_signum.79;
  int D.23869;
  int D.23870;
  void (*<T18a3>) (int) D.23871;
  void (*<T18e5>) (int, struct siginfo_t *, void *) D.23874;
  int D.23877;
  static int abort_signum = -1;
  int i;

  abort_signum.79 = abort_signum;
  if (abort_signum.79 != -1) goto <D.23867>; else goto <D.23868>;
  <D.23867>:
  D.23869 = abort_signum;
  return D.23869;
  <D.23868>:
  D.23870 = __libc_current_sigrtmin ();
  i = D.23870 + 1;
  goto <D.21679>;
  <D.21678>:
  {
    struct sigaction sinfo;

    try
      {
        sigaction (i, 0B, &sinfo);
        D.23871 = sinfo.__sigaction_handler.sa_handler;
        if (D.23871 == 0B) goto <D.23872>; else goto <D.23873>;
        <D.23872>:
        D.23874 = sinfo.__sigaction_handler.sa_sigaction;
        if (D.23874 == 0B) goto <D.23875>; else goto <D.23876>;
        <D.23875>:
        abort_signum = i;
        D.23869 = i;
        return D.23869;
        <D.23876>:
        <D.23873>:
      }
    finally
      {
        sinfo = {CLOBBER};
      }
  }
  i = i + 1;
  <D.21679>:
  D.23877 = __libc_current_sigrtmax ();
  if (D.23877 > i) goto <D.21678>; else goto <D.21680>;
  <D.21680>:
  D.23869 = __libc_current_sigrtmin ();
  return D.23869;
}


ves_icall_System_Threading_Thread_Abort (struct MonoInternalThread * thread, struct MonoObject * state)
{
  unsigned int D.23881;
  unsigned int D.23882;
  unsigned int D.23885;
  unsigned int D.23886;
  unsigned int D.23889;
  unsigned int D.23890;
  int D.23891;
  unsigned int D.23894;
  unsigned int D.23897;
  int D.23898;
  _Bool D.23899;
  long int D.23900;
  long int D.23901;
  int shutting_down.80;

  lock_thread (thread);
  D.23881 = BIT_FIELD_REF <*thread, 32, 224>;
  D.23882 = D.23881 & 145;
  if (D.23882 != 0) goto <D.23883>; else goto <D.23884>;
  <D.23883>:
  unlock_thread (thread);
  return;
  <D.23884>:
  D.23885 = thread->state;
  D.23886 = D.23885 & 8;
  if (D.23886 != 0) goto <D.23887>; else goto <D.23888>;
  <D.23887>:
  D.23885 = thread->state;
  D.23889 = D.23885 | 256;
  thread->state = D.23889;
  unlock_thread (thread);
  return;
  <D.23888>:
  D.23885 = thread->state;
  D.23890 = D.23885 | 128;
  thread->state = D.23890;
  D.23891 = thread->abort_state_handle;
  if (D.23891 != 0) goto <D.23892>; else goto <D.23893>;
  <D.23892>:
  D.23891 = thread->abort_state_handle;
  D.23894 = (unsigned int) D.23891;
  mono_gchandle_free (D.23894);
  <D.23893>:
  if (state != 0B) goto <D.23895>; else goto <D.23896>;
  <D.23895>:
  D.23897 = mono_gchandle_new (state, 0);
  D.23898 = (int) D.23897;
  thread->abort_state_handle = D.23898;
  D.23891 = thread->abort_state_handle;
  D.23899 = D.23891 == 0;
  D.23900 = (long int) D.23899;
  D.23901 = __builtin_expect (D.23900, 0);
  if (D.23901 != 0) goto <D.23902>; else goto <D.23903>;
  <D.23902>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2156, "thread->abort_state_handle");
  <D.23903>:
  goto <D.23904>;
  <D.23896>:
  thread->abort_state_handle = 0;
  <D.23904>:
  thread->abort_exc = 0B;
  unlock_thread (thread);
  shutting_down.80 = shutting_down;
  if (shutting_down.80 == 0) goto <D.23906>; else goto <D.23907>;
  <D.23906>:
  mono_thread_resume (thread);
  <D.23907>:
  abort_thread_internal (thread, 1, 1);
}


mono_thread_resume (struct MonoInternalThread * thread)
{
  unsigned int D.23909;
  unsigned int D.23910;
  unsigned int D.23913;
  gboolean D.23914;
  unsigned int D.23915;
  unsigned int D.23916;

  lock_thread (thread);
  D.23909 = thread->state;
  D.23910 = D.23909 & 2;
  if (D.23910 != 0) goto <D.23911>; else goto <D.23912>;
  <D.23911>:
  D.23909 = thread->state;
  D.23913 = D.23909 & 4294967293;
  thread->state = D.23913;
  unlock_thread (thread);
  D.23914 = 1;
  return D.23914;
  <D.23912>:
  D.23915 = BIT_FIELD_REF <*thread, 32, 224>;
  D.23916 = D.23915 & 344;
  if (D.23916 != 64) goto <D.23917>; else goto <D.23918>;
  <D.23917>:
  unlock_thread (thread);
  D.23914 = 0;
  return D.23914;
  <D.23918>:
  D.23914 = resume_thread_internal (thread);
  return D.23914;
}


resume_thread_internal (struct MonoInternalThread * thread)
{
  int D.23920;
  void * D.23923;
  void * D.23924;
  gboolean D.23927;
  void * D.23928;
  long long unsigned int D.23929;
  long unsigned int D.23930;
  int D.23931;
  unsigned int D.23934;
  unsigned int D.23935;

  D.23920 = mono_thread_info_new_interrupt_enabled ();
  if (D.23920 == 0) goto <D.23921>; else goto <D.23922>;
  <D.23921>:
  D.23923 = CreateEvent (0B, 1, 0, 0B);
  thread->resume_event = D.23923;
  D.23924 = thread->resume_event;
  if (D.23924 == 0B) goto <D.23925>; else goto <D.23926>;
  <D.23925>:
  unlock_thread (thread);
  D.23927 = 0;
  return D.23927;
  <D.23926>:
  D.23928 = thread->suspend_event;
  SetEvent (D.23928);
  unlock_thread (thread);
  D.23924 = thread->resume_event;
  WaitForSingleObject (D.23924, 4294967295);
  D.23924 = thread->resume_event;
  CloseHandle (D.23924);
  thread->resume_event = 0B;
  D.23927 = 1;
  return D.23927;
  <D.23922>:
  unlock_thread (thread);
  D.23929 = thread->tid;
  D.23930 = (long unsigned int) D.23929;
  D.23931 = mono_thread_info_resume (D.23930);
  if (D.23931 == 0) goto <D.23932>; else goto <D.23933>;
  <D.23932>:
  D.23927 = 0;
  return D.23927;
  <D.23933>:
  lock_thread (thread);
  D.23934 = thread->state;
  D.23935 = D.23934 & 4294967231;
  thread->state = D.23935;
  unlock_thread (thread);
  D.23927 = 1;
  return D.23927;
}


ves_icall_System_Threading_Thread_ResetAbort ()
{
  unsigned int D.23937;
  int D.23938;
  unsigned int D.23939;
  struct MonoException * D.23942;
  int D.23943;
  unsigned int D.23946;
  struct MonoInternalThread * thread;
  gboolean was_aborting;

  thread = mono_thread_internal_current ();
  lock_thread (thread);
  D.23937 = thread->state;
  D.23938 = (int) D.23937;
  was_aborting = D.23938 & 128;
  D.23937 = thread->state;
  D.23939 = D.23937 & 4294967167;
  thread->state = D.23939;
  unlock_thread (thread);
  if (was_aborting == 0) goto <D.23940>; else goto <D.23941>;
  <D.23940>:
  {
    const char * msg;

    msg = "Unable to reset abort because no abort was requested";
    D.23942 = mono_get_exception_thread_state (msg);
    mono_raise_exception (D.23942);
  }
  <D.23941>:
  thread->abort_exc = 0B;
  D.23943 = thread->abort_state_handle;
  if (D.23943 != 0) goto <D.23944>; else goto <D.23945>;
  <D.23944>:
  D.23943 = thread->abort_state_handle;
  D.23946 = (unsigned int) D.23943;
  mono_gchandle_free (D.23946);
  thread->abort_state_handle = 0;
  <D.23945>:
}


mono_thread_internal_reset_abort (struct MonoInternalThread * thread)
{
  unsigned int D.23947;
  unsigned int D.23948;
  struct MonoException * D.23949;
  int D.23952;
  unsigned int D.23955;

  lock_thread (thread);
  D.23947 = thread->state;
  D.23948 = D.23947 & 4294967167;
  thread->state = D.23948;
  D.23949 = thread->abort_exc;
  if (D.23949 != 0B) goto <D.23950>; else goto <D.23951>;
  <D.23950>:
  thread->abort_exc = 0B;
  D.23952 = thread->abort_state_handle;
  if (D.23952 != 0) goto <D.23953>; else goto <D.23954>;
  <D.23953>:
  D.23952 = thread->abort_state_handle;
  D.23955 = (unsigned int) D.23952;
  mono_gchandle_free (D.23955);
  thread->abort_state_handle = 0;
  <D.23954>:
  <D.23951>:
  unlock_thread (thread);
}


ves_icall_System_Threading_Thread_GetAbortExceptionState (struct MonoThread * this)
{
  int D.23956;
  struct MonoObject * D.23959;
  unsigned int D.23960;
  _Bool D.23961;
  long int D.23962;
  long int D.23963;
  struct MonoVTable * D.23966;
  struct MonoDomain * D.23967;
  struct MonoObject * exc.81;
  struct MonoObject * * D.23975;
  struct MonoInternalThread * thread;
  struct MonoObject * state;
  struct MonoObject * deserialized;
  struct MonoObject * exc;
  struct MonoDomain * domain;

  try
    {
      thread = this->internal_thread;
      deserialized = 0B;
      D.23956 = thread->abort_state_handle;
      if (D.23956 == 0) goto <D.23957>; else goto <D.23958>;
      <D.23957>:
      D.23959 = 0B;
      return D.23959;
      <D.23958>:
      D.23956 = thread->abort_state_handle;
      D.23960 = (unsigned int) D.23956;
      state = mono_gchandle_get_target (D.23960);
      D.23961 = state == 0B;
      D.23962 = (long int) D.23961;
      D.23963 = __builtin_expect (D.23962, 0);
      if (D.23963 != 0) goto <D.23964>; else goto <D.23965>;
      <D.23964>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2237, "state");
      <D.23965>:
      domain = mono_domain_get ();
      D.23966 = state->vtable;
      D.23967 = D.23966->domain;
      if (D.23967 == domain) goto <D.23968>; else goto <D.23969>;
      <D.23968>:
      D.23959 = state;
      return D.23959;
      <D.23969>:
      deserialized = mono_object_xdomain_representation (state, domain, &exc);
      if (deserialized == 0B) goto <D.23970>; else goto <D.23971>;
      <D.23970>:
      {
        struct MonoException * invalid_op_exc;

        invalid_op_exc = mono_get_exception_invalid_operation ("Thread.ExceptionState cannot access an ExceptionState from a different AppDomain");
        exc.81 = exc;
        if (exc.81 != 0B) goto <D.23973>; else goto <D.23974>;
        <D.23973>:
        D.23975 = &invalid_op_exc->inner_ex;
        exc.81 = exc;
        mono_gc_wbarrier_set_field (invalid_op_exc, D.23975, exc.81);
        <D.23974>:
        mono_raise_exception (invalid_op_exc);
      }
      <D.23971>:
      D.23959 = deserialized;
      return D.23959;
    }
  finally
    {
      exc = {CLOBBER};
    }
}


ves_icall_System_Threading_Thread_Suspend (struct MonoInternalThread * thread)
{
  int D.23978;
  struct MonoException * D.23981;

  D.23978 = mono_thread_suspend (thread);
  if (D.23978 == 0) goto <D.23979>; else goto <D.23980>;
  <D.23979>:
  D.23981 = mono_get_exception_thread_state ("Thread has not been started, or is dead.");
  mono_raise_exception (D.23981);
  <D.23980>:
}


mono_thread_suspend (struct MonoInternalThread * thread)
{
  unsigned int D.23982;
  unsigned int D.23983;
  gboolean D.23986;
  unsigned int D.23987;
  unsigned int D.23990;
  unsigned int D.23991;

  lock_thread (thread);
  D.23982 = BIT_FIELD_REF <*thread, 32, 224>;
  D.23983 = D.23982 & 280;
  if (D.23983 != 0) goto <D.23984>; else goto <D.23985>;
  <D.23984>:
  unlock_thread (thread);
  D.23986 = 0;
  return D.23986;
  <D.23985>:
  D.23982 = BIT_FIELD_REF <*thread, 32, 224>;
  D.23987 = D.23982 & 67;
  if (D.23987 != 0) goto <D.23988>; else goto <D.23989>;
  <D.23988>:
  unlock_thread (thread);
  D.23986 = 1;
  return D.23986;
  <D.23989>:
  D.23990 = thread->state;
  D.23991 = D.23990 | 2;
  thread->state = D.23991;
  unlock_thread (thread);
  suspend_thread_internal (thread, 0);
  D.23986 = 1;
  return D.23986;
}


suspend_thread_internal (struct MonoInternalThread * thread, gboolean interrupt)
{
  int D.23993;
  struct MonoInternalThread * D.23996;
  long long unsigned int D.24000;
  long unsigned int D.24001;
  int iftmp.82;
  struct MonoMethod * D.24008;
  int D.24009;
  int D.24011;
  void * D.24012;
  _Bool D.24013;
  _Bool D.24014;
  _Bool D.24015;
  gint32 * D.24019;
  int D.24020;
  void * D.24025;
  unsigned int D.24026;

  D.23993 = mono_thread_info_new_interrupt_enabled ();
  if (D.23993 == 0) goto <D.23994>; else goto <D.23995>;
  <D.23994>:
  signal_thread_state_change (thread);
  return;
  <D.23995>:
  lock_thread (thread);
  D.23996 = mono_thread_internal_current ();
  if (D.23996 == thread) goto <D.23997>; else goto <D.23998>;
  <D.23997>:
  transition_to_suspended (thread);
  mono_thread_info_self_suspend ();
  goto <D.23999>;
  <D.23998>:
  {
    struct MonoThreadInfo * info;
    struct MonoJitInfo * ji;
    gboolean protected_wrapper;
    gboolean running_managed;

    D.24000 = thread->tid;
    D.24001 = (long unsigned int) D.24000;
    info = mono_thread_info_safe_suspend_sync (D.24001, interrupt);
    if (info == 0B) goto <D.24002>; else goto <D.24003>;
    <D.24002>:
    unlock_thread (thread);
    return;
    <D.24003>:
    ji = mono_thread_info_get_last_managed (info);
    if (ji != 0B) goto <D.24007>; else goto <D.24005>;
    <D.24007>:
    D.24008 = mono_jit_info_get_method (ji);
    D.24009 = mono_threads_is_critical_method (D.24008);
    if (D.24009 != 0) goto <D.24010>; else goto <D.24005>;
    <D.24010>:
    iftmp.82 = 1;
    goto <D.24006>;
    <D.24005>:
    iftmp.82 = 0;
    <D.24006>:
    protected_wrapper = iftmp.82;
    D.24011 = info->suspend_state.ctx.pc;
    D.24012 = (void *) D.24011;
    running_managed = mono_jit_info_match (ji, D.24012);
    D.24013 = running_managed != 0;
    D.24014 = protected_wrapper == 0;
    D.24015 = D.24013 & D.24014;
    if (D.24015 != 0) goto <D.24016>; else goto <D.24017>;
    <D.24016>:
    transition_to_suspended (thread);
    goto <D.24018>;
    <D.24017>:
    {
      void * interrupt_handle;

      D.24019 = &thread->interruption_requested;
      D.24020 = InterlockedCompareExchange (D.24019, 1, 0);
      if (D.24020 == 0) goto <D.24021>; else goto <D.24022>;
      <D.24021>:
      InterlockedIncrement (&thread_interruption_requested);
      <D.24022>:
      if (interrupt != 0) goto <D.24023>; else goto <D.24024>;
      <D.24023>:
      D.24025 = thread->handle;
      interrupt_handle = wapi_prepare_interrupt_thread (D.24025);
      <D.24024>:
      D.24026 = info->node.key;
      mono_thread_info_resume (D.24026);
      if (interrupt != 0) goto <D.24027>; else goto <D.24028>;
      <D.24027>:
      wapi_finish_interrupt_thread (interrupt_handle);
      <D.24028>:
      unlock_thread (thread);
    }
    <D.24018>:
  }
  <D.23999>:
}


ves_icall_System_Threading_Thread_Resume (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.24032;
  int D.24034;
  struct MonoException * D.24035;

  D.24032 = thread->internal_thread;
  if (D.24032 == 0B) goto <D.24030>; else goto <D.24033>;
  <D.24033>:
  D.24032 = thread->internal_thread;
  D.24034 = mono_thread_resume (D.24032);
  if (D.24034 == 0) goto <D.24030>; else goto <D.24031>;
  <D.24030>:
  D.24035 = mono_get_exception_thread_state ("Thread has not been started, or is dead.");
  mono_raise_exception (D.24035);
  <D.24031>:
}


mono_thread_internal_stop (struct MonoInternalThread * thread)
{
  unsigned int D.24036;
  unsigned int D.24037;
  unsigned int D.24040;
  unsigned int D.24041;
  unsigned int D.24042;

  lock_thread (thread);
  D.24036 = BIT_FIELD_REF <*thread, 32, 224>;
  D.24037 = D.24036 & 17;
  if (D.24037 != 0) goto <D.24038>; else goto <D.24039>;
  <D.24038>:
  unlock_thread (thread);
  return;
  <D.24039>:
  mono_thread_resume (thread);
  D.24040 = thread->state;
  D.24041 = D.24040 | 1;
  thread->state = D.24041;
  D.24040 = thread->state;
  D.24042 = D.24040 & 4294967167;
  thread->state = D.24042;
  unlock_thread (thread);
  abort_thread_internal (thread, 1, 1);
}


mono_thread_stop (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.24044;

  D.24044 = thread->internal_thread;
  mono_thread_internal_stop (D.24044);
}


ves_icall_System_Threading_Thread_VolatileRead1 (void * ptr)
{
  gint8 D.24045;
  gint8 tmp;

  {
    gint8 __tmp;

    __tmp = MEM[(volatile gint8 *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24045 = tmp;
  return D.24045;
}


ves_icall_System_Threading_Thread_VolatileRead2 (void * ptr)
{
  gint16 D.24047;
  gint16 tmp;

  {
    gint16 __tmp;

    __tmp = MEM[(volatile gint16 *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24047 = tmp;
  return D.24047;
}


ves_icall_System_Threading_Thread_VolatileRead4 (void * ptr)
{
  gint32 D.24049;
  gint32 tmp;

  {
    gint32 __tmp;

    __tmp = MEM[(volatile gint32 *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24049 = tmp;
  return D.24049;
}


ves_icall_System_Threading_Thread_VolatileRead8 (void * ptr)
{
  gint64 D.24051;
  gint64 tmp;

  {
    gint64 __tmp;

    __tmp = MEM[(volatile gint64 *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24051 = tmp;
  return D.24051;
}


ves_icall_System_Threading_Thread_VolatileReadIntPtr (void * ptr)
{
  void * D.24053;
  volatile void * tmp;

  {
    volatile void * __tmp;

    __tmp = MEM[(volatile void * *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24053 = tmp;
  return D.24053;
}


ves_icall_System_Threading_Thread_VolatileReadObject (void * ptr)
{
  void * D.24055;
  volatile struct MonoObject * tmp;

  {
    volatile struct MonoObject * __tmp;

    __tmp = MEM[(volatile struct MonoObject * *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24055 = tmp;
  return D.24055;
}


ves_icall_System_Threading_Thread_VolatileReadDouble (void * ptr)
{
  double D.24057;
  double tmp;

  {
    double __tmp;

    __tmp = MEM[(volatile double *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24057 = tmp;
  return D.24057;
}


ves_icall_System_Threading_Thread_VolatileReadFloat (void * ptr)
{
  float D.24059;
  float tmp;

  {
    float __tmp;

    __tmp = MEM[(volatile float *)ptr];
    mono_memory_barrier ();
    tmp = __tmp;
  }
  D.24059 = tmp;
  return D.24059;
}


ves_icall_System_Threading_Volatile_Read1 (void * ptr)
{
  gint8 D.24061;

  D.24061 = InterlockedRead8 (ptr);
  return D.24061;
}


InterlockedRead8 (volatile gint8 * src)
{
  gint8 D.24063;
  unsigned char D.24064;

  D.24064 = __sync_fetch_and_add_1 (src, 0);
  D.24063 = (gint8) D.24064;
  return D.24063;
}


ves_icall_System_Threading_Volatile_Read2 (void * ptr)
{
  gint16 D.24066;

  D.24066 = InterlockedRead16 (ptr);
  return D.24066;
}


InterlockedRead16 (volatile gint16 * src)
{
  gint16 D.24068;
  short unsigned int D.24069;

  D.24069 = __sync_fetch_and_add_2 (src, 0);
  D.24068 = (gint16) D.24069;
  return D.24068;
}


ves_icall_System_Threading_Volatile_Read4 (void * ptr)
{
  gint32 D.24071;

  D.24071 = InterlockedRead (ptr);
  return D.24071;
}


InterlockedRead (volatile gint32 * src)
{
  gint32 D.24073;
  unsigned int D.24074;

  D.24074 = __sync_fetch_and_add_4 (src, 0);
  D.24073 = (gint32) D.24074;
  return D.24073;
}


ves_icall_System_Threading_Volatile_Read8 (void * ptr)
{
  unsigned int ptr.83;
  unsigned int D.24077;
  _Bool D.24078;
  long int D.24079;
  long int D.24080;
  _Bool D.24085;
  long int D.24086;
  long int D.24087;
  _Bool D.24092;
  long int D.24093;
  long int D.24094;
  gint64 D.24097;

  ptr.83 = (unsigned int) ptr;
  D.24077 = ptr.83 & 7;
  D.24078 = D.24077 != 0;
  D.24079 = (long int) D.24078;
  D.24080 = __builtin_expect (D.24079, 0);
  if (D.24080 != 0) goto <D.24081>; else goto <D.24082>;
  <D.24081>:
  {
    gint64 val;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.24083>; else goto <D.24084>;
      <D.24083>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.24084>:
      D.24085 = ret != 0;
      D.24086 = (long int) D.24085;
      D.24087 = __builtin_expect (D.24086, 0);
      if (D.24087 != 0) goto <D.24088>; else goto <D.24089>;
      <D.24088>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2469, "ret == 0");
      <D.24089>:
    }
    val = MEM[(gint64 *)ptr];
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.24090>; else goto <D.24091>;
      <D.24090>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.24091>:
      D.24092 = ret != 0;
      D.24093 = (long int) D.24092;
      D.24094 = __builtin_expect (D.24093, 0);
      if (D.24094 != 0) goto <D.24095>; else goto <D.24096>;
      <D.24095>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2471, "ret == 0");
      <D.24096>:
    }
    D.24097 = val;
    return D.24097;
  }
  <D.24082>:
  D.24097 = InterlockedRead64 (ptr);
  return D.24097;
}


ves_icall_System_Threading_Volatile_ReadIntPtr (void * ptr)
{
  void * D.24099;

  D.24099 = InterlockedReadPointer (ptr);
  return D.24099;
}


InterlockedReadPointer (void * volatile * src)
{
  void * D.24101;

  D.24101 = InterlockedCompareExchangePointer (src, 0B, 0B);
  return D.24101;
}


ves_icall_System_Threading_Volatile_ReadDouble (void * ptr)
{
  unsigned int ptr.84;
  unsigned int D.24104;
  _Bool D.24105;
  long int D.24106;
  long int D.24107;
  _Bool D.24112;
  long int D.24113;
  long int D.24114;
  _Bool D.24119;
  long int D.24120;
  long int D.24121;
  double D.24124;
  long long int D.24125;
  union LongDoubleUnion u;

  try
    {
      ptr.84 = (unsigned int) ptr;
      D.24104 = ptr.84 & 7;
      D.24105 = D.24104 != 0;
      D.24106 = (long int) D.24105;
      D.24107 = __builtin_expect (D.24106, 0);
      if (D.24107 != 0) goto <D.24108>; else goto <D.24109>;
      <D.24108>:
      {
        double val;

        {
          int ret;

          ret = pthread_mutex_lock (&interlocked_mutex.mutex);
          if (ret != 0) goto <D.24110>; else goto <D.24111>;
          <D.24110>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.24111>:
          D.24112 = ret != 0;
          D.24113 = (long int) D.24112;
          D.24114 = __builtin_expect (D.24113, 0);
          if (D.24114 != 0) goto <D.24115>; else goto <D.24116>;
          <D.24115>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2492, "ret == 0");
          <D.24116>:
        }
        val = MEM[(double *)ptr];
        {
          int ret;

          ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
          if (ret != 0) goto <D.24117>; else goto <D.24118>;
          <D.24117>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.24118>:
          D.24119 = ret != 0;
          D.24120 = (long int) D.24119;
          D.24121 = __builtin_expect (D.24120, 0);
          if (D.24121 != 0) goto <D.24122>; else goto <D.24123>;
          <D.24122>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2494, "ret == 0");
          <D.24123>:
        }
        D.24124 = val;
        return D.24124;
      }
      <D.24109>:
      D.24125 = InterlockedRead64 (ptr);
      u.ival = D.24125;
      D.24124 = u.fval;
      return D.24124;
    }
  finally
    {
      u = {CLOBBER};
    }
}


ves_icall_System_Threading_Volatile_ReadFloat (void * ptr)
{
  int D.24128;
  float D.24129;
  union IntFloatUnion u;

  try
    {
      D.24128 = InterlockedRead (ptr);
      u.ival = D.24128;
      D.24129 = u.fval;
      return D.24129;
    }
  finally
    {
      u = {CLOBBER};
    }
}


ves_icall_System_Threading_Volatile_Read_T (void * ptr)
{
  struct MonoObject * D.24132;

  D.24132 = InterlockedReadPointer (ptr);
  return D.24132;
}


ves_icall_System_Threading_Thread_VolatileWrite1 (void * ptr, gint8 value)
{
  mono_memory_barrier ();
  MEM[(volatile gint8 *)ptr] = value;
}


ves_icall_System_Threading_Thread_VolatileWrite2 (void * ptr, gint16 value)
{
  mono_memory_barrier ();
  MEM[(volatile gint16 *)ptr] = value;
}


ves_icall_System_Threading_Thread_VolatileWrite4 (void * ptr, gint32 value)
{
  mono_memory_barrier ();
  MEM[(volatile gint32 *)ptr] = value;
}


ves_icall_System_Threading_Thread_VolatileWrite8 (void * ptr, gint64 value)
{
  mono_memory_barrier ();
  MEM[(volatile gint64 *)ptr] = value;
}


ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void * ptr, void * value)
{
  mono_memory_barrier ();
  MEM[(volatile void * *)ptr] = value;
}


ves_icall_System_Threading_Thread_VolatileWriteObject (void * ptr, struct MonoObject * value)
{
  mono_gc_wbarrier_generic_store_atomic (ptr, value);
}


ves_icall_System_Threading_Thread_VolatileWriteDouble (void * ptr, double value)
{
  mono_memory_barrier ();
  MEM[(volatile double *)ptr] = value;
}


ves_icall_System_Threading_Thread_VolatileWriteFloat (void * ptr, float value)
{
  mono_memory_barrier ();
  MEM[(volatile float *)ptr] = value;
}


ves_icall_System_Threading_Volatile_Write1 (void * ptr, gint8 value)
{
  InterlockedWrite8 (ptr, value);
}


InterlockedWrite8 (volatile gint8 * dst, gint8 val)
{
  unsigned char old_val.85;
  unsigned char val.86;
  unsigned char D.24136;
  signed char D.24137;
  gint8 old_val;

  <D.21005>:
  old_val = *dst;
  old_val.85 = (unsigned char) old_val;
  val.86 = (unsigned char) val;
  D.24136 = __sync_val_compare_and_swap_1 (dst, old_val.85, val.86);
  D.24137 = (signed char) D.24136;
  if (D.24137 != old_val) goto <D.21005>; else goto <D.21006>;
  <D.21006>:
}


ves_icall_System_Threading_Volatile_Write2 (void * ptr, gint16 value)
{
  InterlockedWrite16 (ptr, value);
}


InterlockedWrite16 (volatile gint16 * dst, gint16 val)
{
  short unsigned int old_val.87;
  short unsigned int val.88;
  short unsigned int D.24140;
  short int D.24141;
  gint16 old_val;

  <D.21012>:
  old_val = *dst;
  old_val.87 = (short unsigned int) old_val;
  val.88 = (short unsigned int) val;
  D.24140 = __sync_val_compare_and_swap_2 (dst, old_val.87, val.88);
  D.24141 = (short int) D.24140;
  if (D.24141 != old_val) goto <D.21012>; else goto <D.21013>;
  <D.21013>:
}


ves_icall_System_Threading_Volatile_Write4 (void * ptr, gint32 value)
{
  InterlockedWrite (ptr, value);
}


InterlockedWrite (volatile gint32 * dst, gint32 val)
{
  unsigned int old_val.89;
  unsigned int val.90;
  unsigned int D.24144;
  int D.24145;
  gint32 old_val;

  <D.21019>:
  old_val = *dst;
  old_val.89 = (unsigned int) old_val;
  val.90 = (unsigned int) val;
  D.24144 = __sync_val_compare_and_swap_4 (dst, old_val.89, val.90);
  D.24145 = (int) D.24144;
  if (D.24145 != old_val) goto <D.21019>; else goto <D.21020>;
  <D.21020>:
}


ves_icall_System_Threading_Volatile_Write8 (void * ptr, gint64 value)
{
  unsigned int ptr.91;
  unsigned int D.24147;
  _Bool D.24148;
  long int D.24149;
  long int D.24150;
  _Bool D.24155;
  long int D.24156;
  long int D.24157;
  _Bool D.24162;
  long int D.24163;
  long int D.24164;

  ptr.91 = (unsigned int) ptr;
  D.24147 = ptr.91 & 7;
  D.24148 = D.24147 != 0;
  D.24149 = (long int) D.24148;
  D.24150 = __builtin_expect (D.24149, 0);
  if (D.24150 != 0) goto <D.24151>; else goto <D.24152>;
  <D.24151>:
  {
    int ret;

    ret = pthread_mutex_lock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.24153>; else goto <D.24154>;
    <D.24153>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.24154>:
    D.24155 = ret != 0;
    D.24156 = (long int) D.24155;
    D.24157 = __builtin_expect (D.24156, 0);
    if (D.24157 != 0) goto <D.24158>; else goto <D.24159>;
    <D.24158>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2591, "ret == 0");
    <D.24159>:
  }
  MEM[(gint64 *)ptr] = value;
  {
    int ret;

    ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.24160>; else goto <D.24161>;
    <D.24160>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24161>:
    D.24162 = ret != 0;
    D.24163 = (long int) D.24162;
    D.24164 = __builtin_expect (D.24163, 0);
    if (D.24164 != 0) goto <D.24165>; else goto <D.24166>;
    <D.24165>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2593, "ret == 0");
    <D.24166>:
  }
  return;
  <D.24152>:
  InterlockedWrite64 (ptr, value);
}


InterlockedWrite64 (volatile gint64 * dst, gint64 val)
{
  InterlockedExchange64 (dst, val);
}


ves_icall_System_Threading_Volatile_WriteIntPtr (void * ptr, void * value)
{
  InterlockedWritePointer (ptr, value);
}


InterlockedWritePointer (void * volatile * dst, void * val)
{
  InterlockedExchangePointer (dst, val);
}


ves_icall_System_Threading_Volatile_WriteDouble (void * ptr, double value)
{
  unsigned int ptr.92;
  unsigned int D.24169;
  _Bool D.24170;
  long int D.24171;
  long int D.24172;
  _Bool D.24177;
  long int D.24178;
  long int D.24179;
  _Bool D.24184;
  long int D.24185;
  long int D.24186;
  long long int D.24189;
  union LongDoubleUnion u;

  try
    {
      ptr.92 = (unsigned int) ptr;
      D.24169 = ptr.92 & 7;
      D.24170 = D.24169 != 0;
      D.24171 = (long int) D.24170;
      D.24172 = __builtin_expect (D.24171, 0);
      if (D.24172 != 0) goto <D.24173>; else goto <D.24174>;
      <D.24173>:
      {
        int ret;

        ret = pthread_mutex_lock (&interlocked_mutex.mutex);
        if (ret != 0) goto <D.24175>; else goto <D.24176>;
        <D.24175>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24176>:
        D.24177 = ret != 0;
        D.24178 = (long int) D.24177;
        D.24179 = __builtin_expect (D.24178, 0);
        if (D.24179 != 0) goto <D.24180>; else goto <D.24181>;
        <D.24180>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2614, "ret == 0");
        <D.24181>:
      }
      MEM[(double *)ptr] = value;
      {
        int ret;

        ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
        if (ret != 0) goto <D.24182>; else goto <D.24183>;
        <D.24182>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24183>:
        D.24184 = ret != 0;
        D.24185 = (long int) D.24184;
        D.24186 = __builtin_expect (D.24185, 0);
        if (D.24186 != 0) goto <D.24187>; else goto <D.24188>;
        <D.24187>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2616, "ret == 0");
        <D.24188>:
      }
      return;
      <D.24174>:
      u.fval = value;
      D.24189 = u.ival;
      InterlockedWrite64 (ptr, D.24189);
    }
  finally
    {
      u = {CLOBBER};
    }
}


ves_icall_System_Threading_Volatile_WriteFloat (void * ptr, float value)
{
  int D.24193;
  union IntFloatUnion u;

  try
    {
      u.fval = value;
      D.24193 = u.ival;
      InterlockedWrite (ptr, D.24193);
    }
  finally
    {
      u = {CLOBBER};
    }
}


ves_icall_System_Threading_Volatile_Write_T (void * ptr, struct MonoObject * value)
{
  mono_gc_wbarrier_generic_store_atomic (ptr, value);
}


mono_thread_init_tls ()
{
  mono_native_tls_alloc (&current_object_key, 0B);
}


mono_native_tls_alloc (pthread_key_t * key, void * destructor)
{
  int D.24194;
  void (*<Tc1>) (void *) destructor.93;
  int D.24196;
  _Bool D.24197;

  destructor.93 = (void (*<Tc1>) (void *)) destructor;
  D.24196 = pthread_key_create (key, destructor.93);
  D.24197 = D.24196 == 0;
  D.24194 = (int) D.24197;
  return D.24194;
}


mono_thread_init (void (*MonoThreadStartCB) (intptr_t, void *, void *) start_cb, void (*MonoThreadAttachCB) (intptr_t, void *) attach_cb)
{
  void * background_change_event.94;
  void * background_change_event.95;
  _Bool D.24201;
  long int D.24202;
  long int D.24203;

  InitializeCriticalSection (&threads_mutex);
  InitializeCriticalSection (&interlocked_mutex);
  InitializeCriticalSection (&contexts_mutex);
  background_change_event.94 = CreateEvent (0B, 1, 0, 0B);
  background_change_event = background_change_event.94;
  background_change_event.95 = background_change_event;
  D.24201 = background_change_event.95 == 0B;
  D.24202 = (long int) D.24201;
  D.24203 = __builtin_expect (D.24202, 0);
  if (D.24203 != 0) goto <D.24204>; else goto <D.24205>;
  <D.24204>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2657, "background_change_event != NULL");
  <D.24205>:
  mono_init_static_data_info (&thread_static_info);
  mono_init_static_data_info (&context_static_info);
  mono_thread_start_cb = start_cb;
  mono_thread_attach_cb = attach_cb;
  GetCurrentProcess ();
}


mono_init_static_data_info (struct StaticDataInfo * static_data)
{
  static_data->idx = 0;
  static_data->offset = 0;
  static_data->freelist = 0B;
}


mono_thread_cleanup ()
{
  int D.24206;
  unsigned int D.24207;
  unsigned int current_object_key.96;

  D.24206 = mono_environment_exitcode_get ();
  D.24207 = (unsigned int) D.24206;
  _wapi_thread_signal_self (D.24207);
  current_object_key.96 = current_object_key;
  mono_native_tls_free (current_object_key.96);
}


mono_native_tls_free (pthread_key_t key)
{
  pthread_key_delete (key);
}


mono_threads_install_cleanup (void (*MonoThreadCleanupFunc) (struct MonoInternalThread *) func)
{
  mono_thread_cleanup_fn = func;
}


mono_thread_set_manage_callback (struct MonoThread * thread, mono_bool (*MonoThreadManageCallback) (struct MonoThread *) func)
{
  struct _MonoInternalThread * D.24209;

  D.24209 = thread->internal_thread;
  D.24209->manage_callback = func;
}


mono_threads_install_notify_pending_exc (void (*MonoThreadNotifyPendingExcFunc) (void) func)
{
  mono_thread_notify_pending_exc_fn = func;
}


mono_threads_set_shutting_down ()
{
  _Bool D.24212;
  long int D.24213;
  long int D.24214;
  int shutting_down.97;
  _Bool D.24222;
  long int D.24223;
  long int D.24224;
  unsigned int D.24227;
  unsigned int D.24228;
  unsigned int D.24232;
  unsigned int D.24233;
  void * background_change_event.98;
  _Bool D.24237;
  long int D.24238;
  long int D.24239;
  struct MonoInternalThread * current_thread;

  current_thread = mono_thread_internal_current ();
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24210>; else goto <D.24211>;
    <D.24210>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.24211>:
    D.24212 = ret != 0;
    D.24213 = (long int) D.24212;
    D.24214 = __builtin_expect (D.24213, 0);
    if (D.24214 != 0) goto <D.24215>; else goto <D.24216>;
    <D.24215>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2934, "ret == 0");
    <D.24216>:
  }
  shutting_down.97 = shutting_down;
  if (shutting_down.97 != 0) goto <D.24218>; else goto <D.24219>;
  <D.24218>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24220>; else goto <D.24221>;
    <D.24220>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24221>:
    D.24222 = ret != 0;
    D.24223 = (long int) D.24222;
    D.24224 = __builtin_expect (D.24223, 0);
    if (D.24224 != 0) goto <D.24225>; else goto <D.24226>;
    <D.24225>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2937, "ret == 0");
    <D.24226>:
  }
  lock_thread (current_thread);
  D.24227 = BIT_FIELD_REF <*current_thread, 32, 224>;
  D.24228 = D.24227 & 131;
  if (D.24228 != 0) goto <D.24229>; else goto <D.24230>;
  <D.24229>:
  unlock_thread (current_thread);
  mono_thread_execute_interruption (current_thread);
  goto <D.24231>;
  <D.24230>:
  D.24232 = current_thread->state;
  D.24233 = D.24232 | 16;
  current_thread->state = D.24233;
  unlock_thread (current_thread);
  <D.24231>:
  mono_domain_unset ();
  ExitThread (0);
  <D.24219>:
  shutting_down = 1;
  background_change_event.98 = background_change_event;
  SetEvent (background_change_event.98);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24235>; else goto <D.24236>;
    <D.24235>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24236>:
    D.24237 = ret != 0;
    D.24238 = (long int) D.24237;
    D.24239 = __builtin_expect (D.24238, 0);
    if (D.24239 != 0) goto <D.24240>; else goto <D.24241>;
    <D.24240>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2967, "ret == 0");
    <D.24241>:
  }
}


mono_thread_manage ()
{
  _Bool D.24244;
  long int D.24245;
  long int D.24246;
  struct MonoGHashTable * threads.99;
  _Bool D.24254;
  long int D.24255;
  long int D.24256;
  _Bool D.24261;
  long int D.24262;
  long int D.24263;
  _Bool D.24268;
  long int D.24269;
  long int D.24270;
  int shutting_down.100;
  _Bool D.24278;
  long int D.24279;
  long int D.24280;
  void * background_change_event.101;
  struct MonoInternalThread *[64] * D.24284;
  _Bool D.24287;
  long int D.24288;
  long int D.24289;
  unsigned int D.24292;
  int D.24295;
  struct MonoInternalThread * D.24298;
  struct MonoInternalThread * D.24299;
  _Bool D.24302;
  long int D.24303;
  long int D.24304;
  _Bool D.24309;
  long int D.24310;
  long int D.24311;
  struct wait_data wait_data;
  struct wait_data * wait;

  try
    {
      wait = &wait_data;
      memset (wait, 0, 516);
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24242>; else goto <D.24243>;
        <D.24242>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24243>:
        D.24244 = ret != 0;
        D.24245 = (long int) D.24244;
        D.24246 = __builtin_expect (D.24245, 0);
        if (D.24246 != 0) goto <D.24247>; else goto <D.24248>;
        <D.24247>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2980, "ret == 0");
        <D.24248>:
      }
      threads.99 = threads;
      if (threads.99 == 0B) goto <D.24250>; else goto <D.24251>;
      <D.24250>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24252>; else goto <D.24253>;
        <D.24252>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24253>:
        D.24254 = ret != 0;
        D.24255 = (long int) D.24254;
        D.24256 = __builtin_expect (D.24255, 0);
        if (D.24256 != 0) goto <D.24257>; else goto <D.24258>;
        <D.24257>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2983, "ret == 0");
        <D.24258>:
      }
      return;
      <D.24251>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24259>; else goto <D.24260>;
        <D.24259>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24260>:
        D.24261 = ret != 0;
        D.24262 = (long int) D.24261;
        D.24263 = __builtin_expect (D.24262, 0);
        if (D.24263 != 0) goto <D.24264>; else goto <D.24265>;
        <D.24264>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2986, "ret == 0");
        <D.24265>:
      }
      <D.21979>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24266>; else goto <D.24267>;
        <D.24266>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24267>:
        D.24268 = ret != 0;
        D.24269 = (long int) D.24268;
        D.24270 = __builtin_expect (D.24269, 0);
        if (D.24270 != 0) goto <D.24271>; else goto <D.24272>;
        <D.24271>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2989, "ret == 0");
        <D.24272>:
      }
      shutting_down.100 = shutting_down;
      if (shutting_down.100 != 0) goto <D.24274>; else goto <D.24275>;
      <D.24274>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24276>; else goto <D.24277>;
        <D.24276>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24277>:
        D.24278 = ret != 0;
        D.24279 = (long int) D.24278;
        D.24280 = __builtin_expect (D.24279, 0);
        if (D.24280 != 0) goto <D.24281>; else goto <D.24282>;
        <D.24281>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2992, "ret == 0");
        <D.24282>:
      }
      goto <D.21977>;
      <D.24275>:
      background_change_event.101 = background_change_event;
      ResetEvent (background_change_event.101);
      wait->num = 0;
      D.24284 = &wait->threads;
      memset (D.24284, 0, 256);
      threads.99 = threads;
      mono_g_hash_table_foreach (threads.99, build_wait_tids, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24285>; else goto <D.24286>;
        <D.24285>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24286>:
        D.24287 = ret != 0;
        D.24288 = (long int) D.24287;
        D.24289 = __builtin_expect (D.24288, 0);
        if (D.24289 != 0) goto <D.24290>; else goto <D.24291>;
        <D.24290>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3003, "ret == 0");
        <D.24291>:
      }
      D.24292 = wait->num;
      if (D.24292 != 0) goto <D.24293>; else goto <D.24294>;
      <D.24293>:
      wait_for_tids_or_state_change (wait, 4294967295);
      <D.24294>:
      D.24292 = wait->num;
      if (D.24292 != 0) goto <D.21979>; else goto <D.21977>;
      <D.21977>:
      D.24295 = mono_runtime_try_shutdown ();
      if (D.24295 == 0) goto <D.24296>; else goto <D.24297>;
      <D.24296>:
      D.24298 = mono_thread_internal_current ();
      mono_thread_suspend (D.24298);
      D.24299 = mono_thread_internal_current ();
      mono_thread_execute_interruption (D.24299);
      <D.24297>:
      <D.21982>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24300>; else goto <D.24301>;
        <D.24300>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24301>:
        D.24302 = ret != 0;
        D.24303 = (long int) D.24302;
        D.24304 = __builtin_expect (D.24303, 0);
        if (D.24304 != 0) goto <D.24305>; else goto <D.24306>;
        <D.24305>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3023, "ret == 0");
        <D.24306>:
      }
      wait->num = 0;
      D.24284 = &wait->threads;
      memset (D.24284, 0, 256);
      threads.99 = threads;
      mono_g_hash_table_foreach_remove (threads.99, remove_and_abort_threads, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24307>; else goto <D.24308>;
        <D.24307>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24308>:
        D.24309 = ret != 0;
        D.24310 = (long int) D.24309;
        D.24311 = __builtin_expect (D.24310, 0);
        if (D.24311 != 0) goto <D.24312>; else goto <D.24313>;
        <D.24312>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3030, "ret == 0");
        <D.24313>:
      }
      D.24292 = wait->num;
      if (D.24292 != 0) goto <D.24314>; else goto <D.24315>;
      <D.24314>:
      wait_for_tids (wait, 4294967295);
      <D.24315>:
      D.24292 = wait->num;
      if (D.24292 != 0) goto <D.21982>; else goto <D.21983>;
      <D.21983>:
      sched_yield ();
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


remove_and_abort_threads (void * key, void * value, void * user)
{
  unsigned int D.24319;
  gboolean D.24322;
  long long unsigned int D.24323;
  long long unsigned int D.24324;
  unsigned int D.24327;
  unsigned int D.24328;
  unsigned int D.24331;
  unsigned int D.24332;
  unsigned int D.24335;
  void * D.24338;
  unsigned int D.24339;
  int iftmp.102;
  int D.24344;
  struct wait_data * wait;
  gsize self;
  struct MonoInternalThread * thread;
  void * handle;

  wait = user;
  self = GetCurrentThreadId ();
  thread = value;
  D.24319 = wait->num;
  if (D.24319 > 63) goto <D.24320>; else goto <D.24321>;
  <D.24320>:
  D.24322 = 0;
  return D.24322;
  <D.24321>:
  D.24323 = thread->tid;
  D.24324 = (long long unsigned int) self;
  if (D.24323 != D.24324) goto <D.24325>; else goto <D.24326>;
  <D.24325>:
  D.24327 = thread->state;
  D.24328 = D.24327 & 4;
  if (D.24328 != 0) goto <D.24329>; else goto <D.24330>;
  <D.24329>:
  D.24331 = thread->flags;
  D.24332 = D.24331 & 1;
  if (D.24332 == 0) goto <D.24333>; else goto <D.24334>;
  <D.24333>:
  D.24323 = thread->tid;
  D.24335 = (unsigned int) D.24323;
  handle = OpenThread (2032639, 1, D.24335);
  if (handle == 0B) goto <D.24336>; else goto <D.24337>;
  <D.24336>:
  D.24322 = 0;
  return D.24322;
  <D.24337>:
  D.24319 = wait->num;
  D.24338 = thread->handle;
  wait->handles[D.24319] = D.24338;
  D.24319 = wait->num;
  wait->threads[D.24319] = thread;
  D.24319 = wait->num;
  D.24339 = D.24319 + 1;
  wait->num = D.24339;
  mono_thread_internal_stop (thread);
  D.24322 = 1;
  return D.24322;
  <D.24334>:
  <D.24330>:
  <D.24326>:
  D.24323 = thread->tid;
  D.24324 = (long long unsigned int) self;
  if (D.24323 != D.24324) goto <D.24343>; else goto <D.24341>;
  <D.24343>:
  D.24344 = mono_gc_is_finalizer_internal_thread (thread);
  if (D.24344 == 0) goto <D.24345>; else goto <D.24341>;
  <D.24345>:
  iftmp.102 = 1;
  goto <D.24342>;
  <D.24341>:
  iftmp.102 = 0;
  <D.24342>:
  D.24322 = iftmp.102;
  return D.24322;
}


build_wait_tids (void * key, void * value, void * user)
{
  unsigned int D.24347;
  unsigned int D.24350;
  unsigned int D.24351;
  int D.24354;
  struct MonoInternalThread * D.24357;
  struct MonoThread * D.24360;
  struct MonoThread * D.24363;
  struct _MonoInternalThread * D.24364;
  unsigned int D.24367;
  unsigned int D.24368;
  long long unsigned int D.24371;
  unsigned int D.24372;
  mono_bool (*<T267a>) (struct MonoThread *) D.24377;
  struct MonoThread * D.24379;
  int D.24380;
  unsigned int D.24381;
  struct wait_data * wait;

  wait = user;
  D.24347 = wait->num;
  if (D.24347 <= 63) goto <D.24348>; else goto <D.24349>;
  <D.24348>:
  {
    void * handle;
    struct MonoInternalThread * thread;

    thread = value;
    D.24350 = thread->state;
    D.24351 = D.24350 & 4;
    if (D.24351 != 0) goto <D.24352>; else goto <D.24353>;
    <D.24352>:
    return;
    <D.24353>:
    D.24354 = mono_gc_is_finalizer_internal_thread (thread);
    if (D.24354 != 0) goto <D.24355>; else goto <D.24356>;
    <D.24355>:
    return;
    <D.24356>:
    D.24357 = mono_thread_internal_current ();
    if (D.24357 == thread) goto <D.24358>; else goto <D.24359>;
    <D.24358>:
    return;
    <D.24359>:
    D.24360 = mono_thread_get_main ();
    if (D.24360 != 0B) goto <D.24361>; else goto <D.24362>;
    <D.24361>:
    D.24363 = mono_thread_get_main ();
    D.24364 = D.24363->internal_thread;
    if (D.24364 == thread) goto <D.24365>; else goto <D.24366>;
    <D.24365>:
    return;
    <D.24366>:
    <D.24362>:
    D.24367 = thread->flags;
    D.24368 = D.24367 & 1;
    if (D.24368 != 0) goto <D.24369>; else goto <D.24370>;
    <D.24369>:
    return;
    <D.24370>:
    D.24371 = thread->tid;
    D.24372 = (unsigned int) D.24371;
    handle = OpenThread (2032639, 1, D.24372);
    if (handle == 0B) goto <D.24373>; else goto <D.24374>;
    <D.24373>:
    return;
    <D.24374>:
    D.24377 = thread->manage_callback;
    if (D.24377 == 0B) goto <D.24375>; else goto <D.24378>;
    <D.24378>:
    D.24377 = thread->manage_callback;
    D.24379 = thread->root_domain_thread;
    D.24380 = D.24377 (D.24379);
    if (D.24380 == 1) goto <D.24375>; else goto <D.24376>;
    <D.24375>:
    D.24347 = wait->num;
    wait->handles[D.24347] = handle;
    D.24347 = wait->num;
    wait->threads[D.24347] = thread;
    D.24347 = wait->num;
    D.24381 = D.24347 + 1;
    wait->num = D.24381;
    <D.24376>:
  }
  goto <D.24382>;
  <D.24349>:
  <D.24382>:
}


wait_for_tids_or_state_change (struct wait_data * wait, guint32 timeout)
{
  void * background_change_event.103;
  void *[64] * D.24387;
  void * D.24390;
  unsigned int D.24391;
  struct MonoInternalThread * D.24396;
  long long unsigned int D.24397;
  _Bool D.24400;
  long int D.24401;
  long int D.24402;
  struct MonoGHashTable * threads.104;
  const void * tid.105;
  void * D.24407;
  _Bool D.24412;
  long int D.24413;
  long int D.24414;
  _Bool D.24420;
  long int D.24421;
  long int D.24422;
  guint32 i;
  guint32 ret;
  guint32 count;

  count = wait->num;
  if (count <= 63) goto <D.24384>; else goto <D.24385>;
  <D.24384>:
  background_change_event.103 = background_change_event;
  wait->handles[count] = background_change_event.103;
  count = count + 1;
  <D.24385>:
  D.24387 = &wait->handles;
  ret = WaitForMultipleObjectsEx (count, D.24387, 0, timeout, 1);
  if (ret == 4294967295) goto <D.24388>; else goto <D.24389>;
  <D.24388>:
  return;
  <D.24389>:
  i = 0;
  goto <D.21937>;
  <D.21936>:
  D.24390 = wait->handles[i];
  CloseHandle (D.24390);
  i = i + 1;
  <D.21937>:
  D.24391 = wait->num;
  if (D.24391 > i) goto <D.21936>; else goto <D.21938>;
  <D.21938>:
  if (ret == 258) goto <D.24392>; else goto <D.24393>;
  <D.24392>:
  return;
  <D.24393>:
  D.24391 = wait->num;
  if (D.24391 > ret) goto <D.24394>; else goto <D.24395>;
  <D.24394>:
  {
    gsize tid;

    D.24396 = wait->threads[ret];
    D.24397 = D.24396->tid;
    tid = (gsize) D.24397;
    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24398>; else goto <D.24399>;
      <D.24398>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.24399>:
      D.24400 = ret != 0;
      D.24401 = (long int) D.24400;
      D.24402 = __builtin_expect (D.24401, 0);
      if (D.24402 != 0) goto <D.24403>; else goto <D.24404>;
      <D.24403>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2819, "ret == 0");
      <D.24404>:
    }
    threads.104 = threads;
    tid.105 = (const void *) tid;
    D.24407 = mono_g_hash_table_lookup (threads.104, tid.105);
    if (D.24407 != 0B) goto <D.24408>; else goto <D.24409>;
    <D.24408>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24410>; else goto <D.24411>;
      <D.24410>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.24411>:
      D.24412 = ret != 0;
      D.24413 = (long int) D.24412;
      D.24414 = __builtin_expect (D.24413, 0);
      if (D.24414 != 0) goto <D.24415>; else goto <D.24416>;
      <D.24415>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2822, "ret == 0");
      <D.24416>:
    }
    D.24396 = wait->threads[ret];
    thread_cleanup (D.24396);
    goto <D.24417>;
    <D.24409>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24418>; else goto <D.24419>;
      <D.24418>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.24419>:
      D.24420 = ret != 0;
      D.24421 = (long int) D.24420;
      D.24422 = __builtin_expect (D.24421, 0);
      if (D.24422 != 0) goto <D.24423>; else goto <D.24424>;
      <D.24423>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2826, "ret == 0");
      <D.24424>:
    }
    <D.24417>:
  }
  <D.24395>:
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.24428;
  int D.24433;
  void * D.24435;
  unsigned int D.24436;

  D.24428 = __builtin_constant_p (__len);
  if (D.24428 != 0) goto <D.24429>; else goto <D.24430>;
  <D.24429>:
  if (__len == 0) goto <D.24431>; else goto <D.24432>;
  <D.24431>:
  D.24433 = __builtin_constant_p (__ch);
  if (D.24433 == 0) goto <D.24426>; else goto <D.24434>;
  <D.24434>:
  if (__ch != 0) goto <D.24426>; else goto <D.24427>;
  <D.24426>:
  __warn_memset_zero_len ();
  D.24435 = __dest;
  return D.24435;
  <D.24427>:
  <D.24432>:
  <D.24430>:
  D.24436 = __builtin_object_size (__dest, 0);
  D.24435 = __builtin___memset_chk (__dest, __ch, __len, D.24436);
  return D.24435;
}


wait_for_tids (struct wait_data * wait, guint32 timeout)
{
  unsigned int D.24438;
  void *[64] * D.24439;
  void * D.24442;
  struct MonoInternalThread * D.24445;
  long long unsigned int D.24446;
  _Bool D.24449;
  long int D.24450;
  long int D.24451;
  struct MonoGHashTable * threads.106;
  const void * tid.107;
  void * D.24456;
  _Bool D.24461;
  long int D.24462;
  long int D.24463;
  _Bool D.24469;
  long int D.24470;
  long int D.24471;
  guint32 i;
  guint32 ret;

  D.24438 = wait->num;
  D.24439 = &wait->handles;
  ret = WaitForMultipleObjectsEx (D.24438, D.24439, 1, timeout, 1);
  if (ret == 4294967295) goto <D.24440>; else goto <D.24441>;
  <D.24440>:
  return;
  <D.24441>:
  i = 0;
  goto <D.21920>;
  <D.21919>:
  D.24442 = wait->handles[i];
  CloseHandle (D.24442);
  i = i + 1;
  <D.21920>:
  D.24438 = wait->num;
  if (D.24438 > i) goto <D.21919>; else goto <D.21921>;
  <D.21921>:
  if (ret == 258) goto <D.24443>; else goto <D.24444>;
  <D.24443>:
  return;
  <D.24444>:
  i = 0;
  goto <D.21927>;
  <D.21926>:
  {
    gsize tid;

    D.24445 = wait->threads[i];
    D.24446 = D.24445->tid;
    tid = (gsize) D.24446;
    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24447>; else goto <D.24448>;
      <D.24447>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.24448>:
      D.24449 = ret != 0;
      D.24450 = (long int) D.24449;
      D.24451 = __builtin_expect (D.24450, 0);
      if (D.24451 != 0) goto <D.24452>; else goto <D.24453>;
      <D.24452>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2766, "ret == 0");
      <D.24453>:
    }
    threads.106 = threads;
    tid.107 = (const void *) tid;
    D.24456 = mono_g_hash_table_lookup (threads.106, tid.107);
    if (D.24456 != 0B) goto <D.24457>; else goto <D.24458>;
    <D.24457>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24459>; else goto <D.24460>;
      <D.24459>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.24460>:
      D.24461 = ret != 0;
      D.24462 = (long int) D.24461;
      D.24463 = __builtin_expect (D.24462, 0);
      if (D.24463 != 0) goto <D.24464>; else goto <D.24465>;
      <D.24464>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2779, "ret == 0");
      <D.24465>:
    }
    D.24445 = wait->threads[i];
    thread_cleanup (D.24445);
    goto <D.24466>;
    <D.24458>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24467>; else goto <D.24468>;
      <D.24467>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.24468>:
      D.24469 = ret != 0;
      D.24470 = (long int) D.24469;
      D.24471 = __builtin_expect (D.24470, 0);
      if (D.24471 != 0) goto <D.24472>; else goto <D.24473>;
      <D.24472>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2783, "ret == 0");
      <D.24473>:
    }
    <D.24466>:
  }
  i = i + 1;
  <D.21927>:
  D.24438 = wait->num;
  if (D.24438 > i) goto <D.21926>; else goto <D.21928>;
  <D.21928>:
}


mono_thread_abort_all_other_threads ()
{
  _Bool D.24477;
  long int D.24478;
  long int D.24479;
  struct MonoGHashTable * threads.108;
  void * self.109;
  _Bool D.24486;
  long int D.24487;
  long int D.24488;
  gsize self;

  self = GetCurrentThreadId ();
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24475>; else goto <D.24476>;
    <D.24475>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.24476>:
    D.24477 = ret != 0;
    D.24478 = (long int) D.24477;
    D.24479 = __builtin_expect (D.24478, 0);
    if (D.24479 != 0) goto <D.24480>; else goto <D.24481>;
    <D.24480>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3062, "ret == 0");
    <D.24481>:
  }
  threads.108 = threads;
  self.109 = (void *) self;
  mono_g_hash_table_foreach (threads.108, terminate_thread, self.109);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24484>; else goto <D.24485>;
    <D.24484>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24485>:
    D.24486 = ret != 0;
    D.24487 = (long int) D.24486;
    D.24488 = __builtin_expect (D.24487, 0);
    if (D.24488 != 0) goto <D.24489>; else goto <D.24490>;
    <D.24489>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3069, "ret == 0");
    <D.24490>:
  }
}


terminate_thread (void * key, void * value, void * user)
{
  long long unsigned int D.24491;
  unsigned int user.110;
  long long unsigned int D.24493;
  struct MonoInternalThread * thread;

  thread = value;
  D.24491 = thread->tid;
  user.110 = (unsigned int) user;
  D.24493 = (long long unsigned int) user.110;
  if (D.24491 != D.24493) goto <D.24494>; else goto <D.24495>;
  <D.24494>:
  <D.24495>:
}


mono_thread_suspend_all_other_threads ()
{
  int shutting_down.111;
  _Bool D.24497;
  long int D.24498;
  long int D.24499;
  struct MonoInternalThread *[64] * D.24502;
  _Bool D.24505;
  long int D.24506;
  long int D.24507;
  struct MonoGHashTable * threads.112;
  _Bool D.24513;
  long int D.24514;
  long int D.24515;
  unsigned int D.24518;
  unsigned int D.24519;
  long long unsigned int D.24522;
  long long unsigned int D.24523;
  int D.24525;
  unsigned int D.24527;
  unsigned int D.24528;
  void * D.24529;
  void * D.24532;
  unsigned int D.24535;
  unsigned int D.24536;
  void * D.24539;
  unsigned int D.24540;
  unsigned int D.24541;
  unsigned int eventidx.113;
  unsigned int D.24545;
  void * * D.24546;
  unsigned int D.24547;
  unsigned int D.24550;
  unsigned int D.24551;
  int D.24552;
  unsigned int i.114;
  int D.24561;
  unsigned int D.24566;
  unsigned int D.24567;
  void * D.24570;
  _Bool D.24575;
  long int D.24576;
  long int D.24577;
  struct MonoGHashTable * threads_starting_up.115;
  unsigned int D.24583;
  _Bool D.24584;
  _Bool D.24588;
  long int D.24589;
  long int D.24590;
  struct wait_data wait_data;
  struct wait_data * wait;
  int i;
  gsize self;
  void * * events;
  guint32 eventidx;
  gboolean starting;
  gboolean finished;

  try
    {
      wait = &wait_data;
      self = GetCurrentThreadId ();
      eventidx = 0;
      memset (wait, 0, 516);
      shutting_down.111 = shutting_down;
      D.24497 = shutting_down.111 == 0;
      D.24498 = (long int) D.24497;
      D.24499 = __builtin_expect (D.24498, 0);
      if (D.24499 != 0) goto <D.24500>; else goto <D.24501>;
      <D.24500>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3128, "shutting_down");
      <D.24501>:
      finished = 0;
      goto <D.22031>;
      <D.22030>:
      wait->num = 0;
      D.24502 = &wait->threads;
      memset (D.24502, 0, 256);
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24503>; else goto <D.24504>;
        <D.24503>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24504>:
        D.24505 = ret != 0;
        D.24506 = (long int) D.24505;
        D.24507 = __builtin_expect (D.24506, 0);
        if (D.24507 != 0) goto <D.24508>; else goto <D.24509>;
        <D.24508>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3144, "ret == 0");
        <D.24509>:
      }
      threads.112 = threads;
      mono_g_hash_table_foreach (threads.112, collect_threads_for_suspend, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24511>; else goto <D.24512>;
        <D.24511>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24512>:
        D.24513 = ret != 0;
        D.24514 = (long int) D.24513;
        D.24515 = __builtin_expect (D.24514, 0);
        if (D.24515 != 0) goto <D.24516>; else goto <D.24517>;
        <D.24516>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3146, "ret == 0");
        <D.24517>:
      }
      D.24518 = wait->num;
      D.24519 = D.24518 * 4;
      events = monoeg_malloc0 (D.24519);
      eventidx = 0;
      i = 0;
      goto <D.22021>;
      <D.22020>:
      {
        struct MonoInternalThread * thread;
        gboolean signal_suspend;

        thread = wait->threads[i];
        signal_suspend = 0;
        D.24522 = thread->tid;
        D.24523 = (long long unsigned int) self;
        if (D.24522 == D.24523) goto <D.24520>; else goto <D.24524>;
        <D.24524>:
        D.24525 = mono_gc_is_finalizer_internal_thread (thread);
        if (D.24525 != 0) goto <D.24520>; else goto <D.24526>;
        <D.24526>:
        D.24527 = thread->flags;
        D.24528 = D.24527 & 1;
        if (D.24528 != 0) goto <D.24520>; else goto <D.24521>;
        <D.24520>:
        wait->threads[i] = 0B;
        // predicted unlikely by continue predictor.
        goto <D.22019>;
        <D.24521>:
        lock_thread (thread);
        D.24529 = thread->suspended_event;
        if (D.24529 == 0B) goto <D.24530>; else goto <D.24531>;
        <D.24530>:
        D.24532 = CreateEvent (0B, 1, 0, 0B);
        thread->suspended_event = D.24532;
        D.24529 = thread->suspended_event;
        if (D.24529 == 0B) goto <D.24533>; else goto <D.24534>;
        <D.24533>:
        unlock_thread (thread);
        // predicted unlikely by continue predictor.
        goto <D.22019>;
        <D.24534>:
        <D.24531>:
        D.24535 = BIT_FIELD_REF <*thread, 32, 224>;
        D.24536 = D.24535 & 81;
        if (D.24536 != 0) goto <D.24537>; else goto <D.24538>;
        <D.24537>:
        unlock_thread (thread);
        D.24539 = wait->handles[i];
        CloseHandle (D.24539);
        wait->threads[i] = 0B;
        // predicted unlikely by continue predictor.
        goto <D.22019>;
        <D.24538>:
        D.24540 = thread->state;
        D.24541 = D.24540 & 2;
        if (D.24541 == 0) goto <D.24542>; else goto <D.24543>;
        <D.24542>:
        signal_suspend = 1;
        <D.24543>:
        eventidx.113 = eventidx;
        eventidx = eventidx.113 + 1;
        D.24545 = eventidx.113 * 4;
        D.24546 = events + D.24545;
        D.24529 = thread->suspended_event;
        *D.24546 = D.24529;
        D.24540 = thread->state;
        D.24547 = D.24540 & 128;
        if (D.24547 != 0) goto <D.24548>; else goto <D.24549>;
        <D.24548>:
        D.24540 = thread->state;
        D.24550 = D.24540 & 4294967167;
        thread->state = D.24550;
        <D.24549>:
        D.24540 = thread->state;
        D.24551 = D.24540 | 2;
        thread->state = D.24551;
        unlock_thread (thread);
        D.24552 = mono_thread_info_new_interrupt_enabled ();
        if (D.24552 != 0) goto <D.24553>; else goto <D.24554>;
        <D.24553>:
        suspend_thread_internal (thread, 1);
        goto <D.24555>;
        <D.24554>:
        if (signal_suspend != 0) goto <D.24556>; else goto <D.24557>;
        <D.24556>:
        signal_thread_state_change (thread);
        <D.24557>:
        <D.24555>:
      }
      <D.22019>:
      i = i + 1;
      <D.22021>:
      i.114 = (unsigned int) i;
      D.24518 = wait->num;
      if (i.114 < D.24518) goto <D.22020>; else goto <D.22022>;
      <D.22022>:
      if (eventidx != 0) goto <D.24559>; else goto <D.24560>;
      <D.24559>:
      D.24561 = mono_thread_info_new_interrupt_enabled ();
      if (D.24561 == 0) goto <D.24562>; else goto <D.24563>;
      <D.24562>:
      WaitForMultipleObjectsEx (eventidx, events, 1, 100, 0);
      i = 0;
      goto <D.22026>;
      <D.22025>:
      {
        struct MonoInternalThread * thread;

        thread = wait->threads[i];
        if (thread == 0B) goto <D.24564>; else goto <D.24565>;
        <D.24564>:
        // predicted unlikely by continue predictor.
        goto <D.22024>;
        <D.24565>:
        lock_thread (thread);
        D.24566 = thread->state;
        D.24567 = D.24566 & 64;
        if (D.24567 != 0) goto <D.24568>; else goto <D.24569>;
        <D.24568>:
        D.24570 = thread->suspended_event;
        CloseHandle (D.24570);
        thread->suspended_event = 0B;
        <D.24569>:
        unlock_thread (thread);
      }
      <D.22024>:
      i = i + 1;
      <D.22026>:
      i.114 = (unsigned int) i;
      D.24518 = wait->num;
      if (i.114 < D.24518) goto <D.22025>; else goto <D.22027>;
      <D.22027>:
      <D.24563>:
      <D.24560>:
      if (eventidx == 0) goto <D.24571>; else goto <D.24572>;
      <D.24571>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24573>; else goto <D.24574>;
        <D.24573>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24574>:
        D.24575 = ret != 0;
        D.24576 = (long int) D.24575;
        D.24577 = __builtin_expect (D.24576, 0);
        if (D.24577 != 0) goto <D.24578>; else goto <D.24579>;
        <D.24578>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3227, "ret == 0");
        <D.24579>:
      }
      threads_starting_up.115 = threads_starting_up;
      if (threads_starting_up.115 != 0B) goto <D.24581>; else goto <D.24582>;
      <D.24581>:
      threads_starting_up.115 = threads_starting_up;
      D.24583 = mono_g_hash_table_size (threads_starting_up.115);
      D.24584 = D.24583 != 0;
      starting = (gboolean) D.24584;
      goto <D.24585>;
      <D.24582>:
      starting = 0;
      <D.24585>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24586>; else goto <D.24587>;
        <D.24586>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24587>:
        D.24588 = ret != 0;
        D.24589 = (long int) D.24588;
        D.24590 = __builtin_expect (D.24589, 0);
        if (D.24590 != 0) goto <D.24591>; else goto <D.24592>;
        <D.24591>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3232, "ret == 0");
        <D.24592>:
      }
      if (starting != 0) goto <D.24593>; else goto <D.24594>;
      <D.24593>:
      Sleep (100);
      goto <D.24595>;
      <D.24594>:
      finished = 1;
      <D.24595>:
      <D.24572>:
      monoeg_g_free (events);
      <D.22031>:
      if (finished == 0) goto <D.22030>; else goto <D.22032>;
      <D.22032>:
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


collect_threads_for_suspend (void * key, void * value, void * user_data)
{
  unsigned int D.24596;
  unsigned int D.24597;
  unsigned int D.24600;
  long long unsigned int D.24603;
  unsigned int D.24604;
  unsigned int D.24607;
  struct MonoInternalThread * thread;
  struct wait_data * wait;
  void * handle;

  thread = value;
  wait = user_data;
  D.24596 = BIT_FIELD_REF <*thread, 32, 224>;
  D.24597 = D.24596 & 80;
  if (D.24597 != 0) goto <D.24598>; else goto <D.24599>;
  <D.24598>:
  return;
  <D.24599>:
  D.24600 = wait->num;
  if (D.24600 <= 63) goto <D.24601>; else goto <D.24602>;
  <D.24601>:
  D.24603 = thread->tid;
  D.24604 = (unsigned int) D.24603;
  handle = OpenThread (2032639, 1, D.24604);
  if (handle == 0B) goto <D.24605>; else goto <D.24606>;
  <D.24605>:
  return;
  <D.24606>:
  D.24600 = wait->num;
  wait->handles[D.24600] = handle;
  D.24600 = wait->num;
  wait->threads[D.24600] = thread;
  D.24600 = wait->num;
  D.24607 = D.24600 + 1;
  wait->num = D.24607;
  <D.24602>:
}


mono_threads_perform_thread_dump ()
{
  int thread_dump_requested.116;
  _Bool D.24614;
  long int D.24615;
  long int D.24616;
  struct MonoGHashTable * threads.117;
  _Bool D.24622;
  long int D.24623;
  long int D.24624;

  thread_dump_requested.116 = thread_dump_requested;
  if (thread_dump_requested.116 == 0) goto <D.24610>; else goto <D.24611>;
  <D.24610>:
  return;
  <D.24611>:
  printf ("Full thread dump:\n");
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24612>; else goto <D.24613>;
    <D.24612>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.24613>:
    D.24614 = ret != 0;
    D.24615 = (long int) D.24614;
    D.24616 = __builtin_expect (D.24615, 0);
    if (D.24616 != 0) goto <D.24617>; else goto <D.24618>;
    <D.24617>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3357, "ret == 0");
    <D.24618>:
  }
  threads.117 = threads;
  mono_g_hash_table_foreach (threads.117, dump_thread, 0B);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24620>; else goto <D.24621>;
    <D.24620>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24621>:
    D.24622 = ret != 0;
    D.24623 = (long int) D.24622;
    D.24624 = __builtin_expect (D.24623, 0);
    if (D.24624 != 0) goto <D.24625>; else goto <D.24626>;
    <D.24625>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3359, "ret == 0");
    <D.24626>:
  }
  thread_dump_requested = 0;
}


dump_thread (void * key, void * value, void * user)
{
  struct MonoInternalThread * D.24628;
  long long unsigned int D.24631;
  long unsigned int D.24632;
  struct MonoInternalThread * thread;
  struct MonoThreadInfo * info;

  thread = value;
  D.24628 = mono_thread_internal_current ();
  if (D.24628 == thread) goto <D.24629>; else goto <D.24630>;
  <D.24629>:
  return;
  <D.24630>:
  D.24631 = thread->tid;
  D.24632 = (long unsigned int) D.24631;
  info = mono_thread_info_safe_suspend_sync (D.24632, 0);
  if (info == 0B) goto <D.24633>; else goto <D.24634>;
  <D.24633>:
  return;
  <D.24634>:
  print_thread_dump (thread, info);
}


print_thread_dump (struct MonoInternalThread * thread, struct MonoThreadInfo * info)
{
  gunichar2 * D.24636;
  unsigned int D.24639;
  long int D.24640;
  struct GError * error.118;
  _Bool D.24642;
  long int D.24643;
  long int D.24644;
  unsigned char D.24648;
  struct MonoRuntimeExceptionHandlingCallbacks * D.24652;
  void (*<T30cb>) (gboolean (*MonoInternalStackWalk) (struct MonoStackFrameInfo *, struct MonoContext *, void *), struct MonoThreadUnwindState *, MonoUnwindOptions, void *) D.24653;
  struct MonoThreadUnwindState * D.24654;
  unsigned int D.24655;
  struct _IO_FILE * stdout.119;
  char * D.24657;
  struct GString * text;
  char * name;
  struct GError * error;

  try
    {
      text = monoeg_g_string_new (0B);
      error = 0B;
      D.24636 = thread->name;
      if (D.24636 != 0B) goto <D.24637>; else goto <D.24638>;
      <D.24637>:
      D.24636 = thread->name;
      D.24639 = thread->name_len;
      D.24640 = (long int) D.24639;
      name = monoeg_g_utf16_to_utf8 (D.24636, D.24640, 0B, 0B, &error);
      error.118 = error;
      D.24642 = error.118 != 0B;
      D.24643 = (long int) D.24642;
      D.24644 = __builtin_expect (D.24643, 0);
      if (D.24644 != 0) goto <D.24645>; else goto <D.24646>;
      <D.24645>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3290, "!error");
      <D.24646>:
      monoeg_g_string_append_printf (text, "\n\"%s\"", name);
      monoeg_g_free (name);
      goto <D.24647>;
      <D.24638>:
      D.24648 = thread->threadpool_thread;
      if (D.24648 != 0) goto <D.24649>; else goto <D.24650>;
      <D.24649>:
      monoeg_g_string_append (text, "\n\"<threadpool thread>\"");
      goto <D.24651>;
      <D.24650>:
      monoeg_g_string_append (text, "\n\"<unnamed thread>\"");
      <D.24651>:
      <D.24647>:
      D.24652 = mono_get_eh_callbacks ();
      D.24653 = D.24652->mono_walk_stack_with_state;
      D.24654 = &info->suspend_state;
      D.24653 (print_stack_frame_to_string, D.24654, 0, text);
      D.24655 = info->node.key;
      mono_thread_info_resume (D.24655);
      stdout.119 = stdout;
      D.24657 = text->str;
      fprintf (stdout.119, "%s", D.24657);
      monoeg_g_string_free (text, 1);
      stdout.119 = stdout;
      fflush (stdout.119);
    }
  finally
    {
      error = {CLOBBER};
    }
}


print_stack_frame_to_string (struct MonoStackFrameInfo * frame, struct MonoContext * ctx, void * data)
{
  struct MonoJitInfo * D.24658;
  int D.24663;
  unsigned int D.24664;
  struct MonoDomain * D.24665;
  gboolean D.24667;
  struct GString * p;
  struct MonoMethod * method;

  p = data;
  method = 0B;
  D.24658 = frame->ji;
  if (D.24658 != 0B) goto <D.24659>; else goto <D.24660>;
  <D.24659>:
  D.24658 = frame->ji;
  method = mono_jit_info_get_method (D.24658);
  <D.24660>:
  if (method != 0B) goto <D.24661>; else goto <D.24662>;
  <D.24661>:
  {
    gchar * location;

    D.24663 = frame->native_offset;
    D.24664 = (unsigned int) D.24663;
    D.24665 = frame->domain;
    location = mono_debug_print_stack_frame (method, D.24664, D.24665);
    monoeg_g_string_append_printf (p, "  %s\n", location);
    monoeg_g_free (location);
  }
  goto <D.24666>;
  <D.24662>:
  D.24663 = frame->native_offset;
  monoeg_g_string_append_printf (p, "  at <unknown> <0x%05x>\n", D.24663);
  <D.24666>:
  D.24667 = 0;
  return D.24667;
}


fprintf (struct FILE * restrict __stream, const char * restrict __fmt)
{
  int D.24669;

  D.24669 = __fprintf_chk (__stream, 1, __fmt, __builtin_va_arg_pack ());
  return D.24669;
}


printf (const char * restrict __fmt)
{
  int D.24671;

  D.24671 = __printf_chk (1, __fmt, __builtin_va_arg_pack ());
  return D.24671;
}


mono_threads_request_thread_dump ()
{
  int D.24673;
  _Bool D.24678;
  long int D.24679;
  long int D.24680;
  struct MonoGHashTable * threads.120;
  _Bool D.24686;
  long int D.24687;
  long int D.24688;
  int D.24691;
  struct MonoInternalThread * D.24694;
  unsigned char D.24697;
  void * D.24700;
  unsigned int i.121;
  unsigned int D.24702;
  struct wait_data wait_data;
  struct wait_data * wait;
  int i;

  try
    {
      wait = &wait_data;
      D.24673 = mono_thread_info_new_interrupt_enabled ();
      if (D.24673 != 0) goto <D.24674>; else goto <D.24675>;
      <D.24674>:
      thread_dump_requested = 1;
      mono_gc_finalize_notify ();
      return;
      <D.24675>:
      memset (wait, 0, 516);
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24676>; else goto <D.24677>;
        <D.24676>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24677>:
        D.24678 = ret != 0;
        D.24679 = (long int) D.24678;
        D.24680 = __builtin_expect (D.24679, 0);
        if (D.24680 != 0) goto <D.24681>; else goto <D.24682>;
        <D.24681>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3390, "ret == 0");
        <D.24682>:
      }
      threads.120 = threads;
      mono_g_hash_table_foreach (threads.120, collect_threads, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24684>; else goto <D.24685>;
        <D.24684>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24685>:
        D.24686 = ret != 0;
        D.24687 = (long int) D.24686;
        D.24688 = __builtin_expect (D.24687, 0);
        if (D.24688 != 0) goto <D.24689>; else goto <D.24690>;
        <D.24689>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3392, "ret == 0");
        <D.24690>:
      }
      i = 0;
      goto <D.22079>;
      <D.22078>:
      {
        struct MonoInternalThread * thread;

        thread = wait->threads[i];
        D.24691 = mono_gc_is_finalizer_internal_thread (thread);
        if (D.24691 == 0) goto <D.24692>; else goto <D.24693>;
        <D.24692>:
        D.24694 = mono_thread_internal_current ();
        if (D.24694 != thread) goto <D.24695>; else goto <D.24696>;
        <D.24695>:
        D.24697 = thread->thread_dump_requested;
        if (D.24697 == 0) goto <D.24698>; else goto <D.24699>;
        <D.24698>:
        thread->thread_dump_requested = 1;
        signal_thread_state_change (thread);
        <D.24699>:
        <D.24696>:
        <D.24693>:
        D.24700 = wait->handles[i];
        CloseHandle (D.24700);
      }
      i = i + 1;
      <D.22079>:
      i.121 = (unsigned int) i;
      D.24702 = wait->num;
      if (i.121 < D.24702) goto <D.22078>; else goto <D.22080>;
      <D.22080>:
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


collect_threads (void * key, void * value, void * user_data)
{
  unsigned int D.24706;
  long long unsigned int D.24709;
  unsigned int D.24710;
  unsigned int D.24713;
  struct MonoInternalThread * thread;
  struct wait_data * wait;
  void * handle;

  thread = value;
  wait = user_data;
  D.24706 = wait->num;
  if (D.24706 <= 63) goto <D.24707>; else goto <D.24708>;
  <D.24707>:
  D.24709 = thread->tid;
  D.24710 = (unsigned int) D.24709;
  handle = OpenThread (2032639, 1, D.24710);
  if (handle == 0B) goto <D.24711>; else goto <D.24712>;
  <D.24711>:
  return;
  <D.24712>:
  D.24706 = wait->num;
  wait->handles[D.24706] = handle;
  D.24706 = wait->num;
  wait->threads[D.24706] = thread;
  D.24706 = wait->num;
  D.24713 = D.24706 + 1;
  wait->num = D.24713;
  <D.24708>:
}


mono_thread_push_appdomain_ref (struct MonoDomain * domain)
{
  volatile int * D.24717;
  int D.24718;
  void * D.24720;
  struct RefStack * D.24723;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.24715>; else goto <D.24716>;
  <D.24715>:
  <D.22114>:
  D.24717 = &thread->lock_thread_id;
  D.24718 = InterlockedCompareExchange (D.24717, 1, 0);
  if (D.24718 == 0) goto <D.22113>; else goto <D.24719>;
  <D.24719>:
  goto <D.22114>;
  <D.22113>:
  D.24720 = thread->appdomain_refs;
  if (D.24720 == 0B) goto <D.24721>; else goto <D.24722>;
  <D.24721>:
  D.24723 = ref_stack_new (16);
  thread->appdomain_refs = D.24723;
  <D.24722>:
  D.24720 = thread->appdomain_refs;
  ref_stack_push (D.24720, domain);
  thread->lock_thread_id = 0;
  <D.24716>:
}


ref_stack_new (gint initial_size)
{
  int D.24724;
  unsigned int initial_size.122;
  unsigned int D.24726;
  void * D.24727;
  struct RefStack * D.24728;
  struct RefStack * rs;

  D.24724 = MAX_EXPR <initial_size, 16>;
  initial_size = D.24724 + 1;
  rs = monoeg_malloc0 (12);
  initial_size.122 = (unsigned int) initial_size;
  D.24726 = initial_size.122 * 4;
  D.24727 = monoeg_malloc0 (D.24726);
  rs->refs = D.24727;
  rs->allocated = initial_size;
  D.24728 = rs;
  return D.24728;
}


ref_stack_push (struct RefStack * rs, void * ptr)
{
  _Bool D.24730;
  long int D.24731;
  long int D.24732;
  int D.24735;
  int D.24736;
  void * * D.24739;
  unsigned int D.24740;
  unsigned int D.24741;
  unsigned int D.24742;
  void * D.24743;
  int D.24744;
  unsigned int D.24745;
  void * * D.24746;
  int D.24747;
  int D.24748;
  unsigned int D.24749;
  unsigned int D.24750;
  void * * D.24751;

  D.24730 = rs == 0B;
  D.24731 = (long int) D.24730;
  D.24732 = __builtin_expect (D.24731, 0);
  if (D.24732 != 0) goto <D.24733>; else goto <D.24734>;
  <D.24733>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3443, "rs != NULL");
  <D.24734>:
  D.24735 = rs->bottom;
  D.24736 = rs->allocated;
  if (D.24735 >= D.24736) goto <D.24737>; else goto <D.24738>;
  <D.24737>:
  D.24739 = rs->refs;
  D.24736 = rs->allocated;
  D.24740 = (unsigned int) D.24736;
  D.24741 = D.24740 * 8;
  D.24742 = D.24741 + 1;
  D.24743 = monoeg_realloc (D.24739, D.24742);
  rs->refs = D.24743;
  D.24736 = rs->allocated;
  D.24744 = D.24736 << 1;
  rs->allocated = D.24744;
  D.24739 = rs->refs;
  D.24736 = rs->allocated;
  D.24740 = (unsigned int) D.24736;
  D.24745 = D.24740 * 4;
  D.24746 = D.24739 + D.24745;
  *D.24746 = 0B;
  <D.24738>:
  D.24739 = rs->refs;
  D.24735 = rs->bottom;
  D.24747 = D.24735;
  D.24748 = D.24747 + 1;
  rs->bottom = D.24748;
  D.24749 = (unsigned int) D.24747;
  D.24750 = D.24749 * 4;
  D.24751 = D.24739 + D.24750;
  *D.24751 = ptr;
}


mono_thread_pop_appdomain_ref ()
{
  volatile int * D.24754;
  int D.24755;
  void * D.24757;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.24752>; else goto <D.24753>;
  <D.24752>:
  <D.22120>:
  D.24754 = &thread->lock_thread_id;
  D.24755 = InterlockedCompareExchange (D.24754, 1, 0);
  if (D.24755 == 0) goto <D.22119>; else goto <D.24756>;
  <D.24756>:
  goto <D.22120>;
  <D.22119>:
  D.24757 = thread->appdomain_refs;
  ref_stack_pop (D.24757);
  thread->lock_thread_id = 0;
  <D.24753>:
}


ref_stack_pop (struct RefStack * rs)
{
  int D.24761;
  int D.24762;
  void * * D.24763;
  unsigned int D.24764;
  unsigned int D.24765;
  void * * D.24766;

  if (rs == 0B) goto <D.24758>; else goto <D.24760>;
  <D.24760>:
  D.24761 = rs->bottom;
  if (D.24761 == 0) goto <D.24758>; else goto <D.24759>;
  <D.24758>:
  return;
  <D.24759>:
  D.24761 = rs->bottom;
  D.24762 = D.24761 + -1;
  rs->bottom = D.24762;
  D.24763 = rs->refs;
  D.24761 = rs->bottom;
  D.24764 = (unsigned int) D.24761;
  D.24765 = D.24764 * 4;
  D.24766 = D.24763 + D.24765;
  *D.24766 = 0B;
}


mono_thread_internal_has_appdomain_ref (struct MonoInternalThread * thread, struct MonoDomain * domain)
{
  volatile int * D.24768;
  int D.24769;
  void * D.24771;
  gboolean D.24772;
  gboolean res;

  <D.22127>:
  D.24768 = &thread->lock_thread_id;
  D.24769 = InterlockedCompareExchange (D.24768, 1, 0);
  if (D.24769 == 0) goto <D.22126>; else goto <D.24770>;
  <D.24770>:
  goto <D.22127>;
  <D.22126>:
  D.24771 = thread->appdomain_refs;
  res = ref_stack_find (D.24771, domain);
  thread->lock_thread_id = 0;
  D.24772 = res;
  return D.24772;
}


ref_stack_find (struct RefStack * rs, void * ptr)
{
  gboolean D.24776;
  void * D.24777;
  void * * refs;

  if (rs == 0B) goto <D.24774>; else goto <D.24775>;
  <D.24774>:
  D.24776 = 0;
  return D.24776;
  <D.24775>:
  refs = rs->refs;
  goto <D.22107>;
  <D.22106>:
  D.24777 = *refs;
  if (D.24777 == ptr) goto <D.24778>; else goto <D.24779>;
  <D.24778>:
  D.24776 = 1;
  return D.24776;
  <D.24779>:
  refs = refs + 4;
  <D.22107>:
  if (refs != 0B) goto <D.24780>; else goto <D.22108>;
  <D.24780>:
  D.24777 = *refs;
  if (D.24777 != 0B) goto <D.22106>; else goto <D.22108>;
  <D.22108>:
  D.24776 = 0;
  return D.24776;
}


mono_thread_has_appdomain_ref (struct MonoThread * thread, struct MonoDomain * domain)
{
  gboolean D.24782;
  struct _MonoInternalThread * D.24783;

  D.24783 = thread->internal_thread;
  D.24782 = mono_thread_internal_has_appdomain_ref (D.24783, domain);
  return D.24782;
}


mono_threads_abort_appdomain_threads (struct MonoDomain * domain, int timeout)
{
  _Bool D.24787;
  long int D.24788;
  long int D.24789;
  struct MonoGHashTable * threads.123;
  _Bool D.24795;
  long int D.24796;
  long int D.24797;
  unsigned int D.24800;
  struct MonoInternalThread * D.24803;
  unsigned int i.124;
  unsigned int D.24805;
  unsigned int D.24806;
  unsigned int timeout.125;
  unsigned int D.24808;
  _Bool D.24809;
  _Bool D.24810;
  _Bool D.24811;
  gboolean D.24814;
  struct abort_appdomain_data user_data;
  guint32 start_time;
  int orig_timeout;
  int i;

  try
    {
      orig_timeout = timeout;
      start_time = mono_msec_ticks ();
      <D.22158>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24785>; else goto <D.24786>;
        <D.24785>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.24786>:
        D.24787 = ret != 0;
        D.24788 = (long int) D.24787;
        D.24789 = __builtin_expect (D.24788, 0);
        if (D.24789 != 0) goto <D.24790>; else goto <D.24791>;
        <D.24790>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3580, "ret == 0");
        <D.24791>:
      }
      user_data.domain = domain;
      user_data.wait.num = 0;
      threads.123 = threads;
      mono_g_hash_table_foreach (threads.123, collect_appdomain_thread, &user_data);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.24793>; else goto <D.24794>;
        <D.24793>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.24794>:
        D.24795 = ret != 0;
        D.24796 = (long int) D.24795;
        D.24797 = __builtin_expect (D.24796, 0);
        if (D.24797 != 0) goto <D.24798>; else goto <D.24799>;
        <D.24798>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3586, "ret == 0");
        <D.24799>:
      }
      D.24800 = user_data.wait.num;
      if (D.24800 != 0) goto <D.24801>; else goto <D.24802>;
      <D.24801>:
      i = 0;
      goto <D.22156>;
      <D.22155>:
      D.24803 = user_data.wait.threads[i];
      ves_icall_System_Threading_Thread_Abort (D.24803, 0B);
      i = i + 1;
      <D.22156>:
      i.124 = (unsigned int) i;
      D.24800 = user_data.wait.num;
      if (i.124 < D.24800) goto <D.22155>; else goto <D.22157>;
      <D.22157>:
      wait_for_tids (&user_data.wait, 100);
      <D.24802>:
      D.24805 = mono_msec_ticks ();
      D.24806 = D.24805 - start_time;
      timeout.125 = (unsigned int) timeout;
      D.24808 = timeout.125 - D.24806;
      timeout = (int) D.24808;
      start_time = mono_msec_ticks ();
      D.24809 = orig_timeout != -1;
      D.24810 = timeout < 0;
      D.24811 = D.24809 & D.24810;
      if (D.24811 != 0) goto <D.24812>; else goto <D.24813>;
      <D.24812>:
      D.24814 = 0;
      return D.24814;
      <D.24813>:
      D.24800 = user_data.wait.num;
      if (D.24800 != 0) goto <D.22158>; else goto <D.22159>;
      <D.22159>:
      D.24814 = 1;
      return D.24814;
    }
  finally
    {
      user_data = {CLOBBER};
    }
}


collect_appdomain_thread (void * key, void * value, void * user_data)
{
  int D.24817;
  unsigned int D.24820;
  long long unsigned int D.24823;
  unsigned int D.24824;
  unsigned int D.24827;
  struct MonoInternalThread * thread;
  struct abort_appdomain_data * data;
  struct MonoDomain * domain;

  thread = value;
  data = user_data;
  domain = data->domain;
  D.24817 = mono_thread_internal_has_appdomain_ref (thread, domain);
  if (D.24817 != 0) goto <D.24818>; else goto <D.24819>;
  <D.24818>:
  D.24820 = data->wait.num;
  if (D.24820 <= 63) goto <D.24821>; else goto <D.24822>;
  <D.24821>:
  {
    void * handle;

    D.24823 = thread->tid;
    D.24824 = (unsigned int) D.24823;
    handle = OpenThread (2032639, 1, D.24824);
    if (handle == 0B) goto <D.24825>; else goto <D.24826>;
    <D.24825>:
    return;
    <D.24826>:
    D.24820 = data->wait.num;
    data->wait.handles[D.24820] = handle;
    D.24820 = data->wait.num;
    data->wait.threads[D.24820] = thread;
    D.24820 = data->wait.num;
    D.24827 = D.24820 + 1;
    data->wait.num = D.24827;
  }
  goto <D.24828>;
  <D.24822>:
  <D.24828>:
  <D.24819>:
}


mono_threads_clear_cached_culture (struct MonoDomain * domain)
{
  _Bool D.24832;
  long int D.24833;
  long int D.24834;
  struct MonoGHashTable * threads.126;
  _Bool D.24840;
  long int D.24841;
  long int D.24842;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24830>; else goto <D.24831>;
    <D.24830>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.24831>:
    D.24832 = ret != 0;
    D.24833 = (long int) D.24832;
    D.24834 = __builtin_expect (D.24833, 0);
    if (D.24834 != 0) goto <D.24835>; else goto <D.24836>;
    <D.24835>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3642, "ret == 0");
    <D.24836>:
  }
  threads.126 = threads;
  mono_g_hash_table_foreach (threads.126, clear_cached_culture, domain);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.24838>; else goto <D.24839>;
    <D.24838>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24839>:
    D.24840 = ret != 0;
    D.24841 = (long int) D.24840;
    D.24842 = __builtin_expect (D.24841, 0);
    if (D.24842 != 0) goto <D.24843>; else goto <D.24844>;
    <D.24843>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3644, "ret == 0");
    <D.24844>:
  }
}


clear_cached_culture (void * key, void * value, void * user_data)
{
  struct MonoArray * D.24845;
  unsigned int i.127;
  char * D.24849;
  struct MonoVTable * D.24852;
  struct MonoDomain * D.24853;
  struct MonoInternalThread * thread;
  struct MonoDomain * domain;
  int i;

  thread = value;
  domain = user_data;
  D.24845 = thread->cached_culture_info;
  if (D.24845 != 0B) goto <D.24846>; else goto <D.24847>;
  <D.24846>:
  i = 0;
  goto <D.22171>;
  <D.22170>:
  {
    struct MonoObject * obj;

    D.24845 = thread->cached_culture_info;
    i.127 = (unsigned int) i;
    D.24849 = mono_array_addr_with_size (D.24845, 4, i.127);
    obj = MEM[(struct MonoObject * *)D.24849];
    if (obj != 0B) goto <D.24850>; else goto <D.24851>;
    <D.24850>:
    D.24852 = obj->vtable;
    D.24853 = D.24852->domain;
    if (D.24853 == domain) goto <D.24854>; else goto <D.24855>;
    <D.24854>:
    {
      struct MonoObject * * __p;

      D.24845 = thread->cached_culture_info;
      i.127 = (unsigned int) i;
      __p = mono_array_addr_with_size (D.24845, 4, i.127);
      *__p = 0B;
    }
    <D.24855>:
    <D.24851>:
  }
  i = i + 1;
  <D.22171>:
  if (i <= 7) goto <D.22170>; else goto <D.22172>;
  <D.22172>:
  <D.24847>:
}


mono_thread_get_undeniable_exception ()
{
  struct MonoException * D.24858;
  int D.24861;
  struct MonoException * D.24864;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.24856>; else goto <D.24857>;
  <D.24856>:
  D.24858 = thread->abort_exc;
  if (D.24858 != 0B) goto <D.24859>; else goto <D.24860>;
  <D.24859>:
  D.24861 = is_running_protected_wrapper ();
  if (D.24861 == 0) goto <D.24862>; else goto <D.24863>;
  <D.24862>:
  D.24858 = thread->abort_exc;
  D.24858->trace_ips = 0B;
  D.24858 = thread->abort_exc;
  D.24858->stack_trace = 0B;
  D.24864 = thread->abort_exc;
  return D.24864;
  <D.24863>:
  <D.24860>:
  <D.24857>:
  D.24864 = 0B;
  return D.24864;
}


is_running_protected_wrapper ()
{
  gboolean D.24866;
  gboolean found;

  try
    {
      found = 0;
      mono_stack_walk (find_wrapper, &found);
      D.24866 = found;
      return D.24866;
    }
  finally
    {
      found = {CLOBBER};
    }
}


find_wrapper (struct MonoMethod * m, gint no, gint ilo, gboolean managed, void * data)
{
  gboolean D.24871;
  int D.24872;

  if (managed != 0) goto <D.24869>; else goto <D.24870>;
  <D.24869>:
  D.24871 = 1;
  return D.24871;
  <D.24870>:
  D.24872 = mono_threads_is_critical_method (m);
  if (D.24872 != 0) goto <D.24873>; else goto <D.24874>;
  <D.24873>:
  MEM[(gboolean *)data] = 1;
  D.24871 = 1;
  return D.24871;
  <D.24874>:
  D.24871 = 0;
  return D.24871;
}


mono_alloc_special_static_data (guint32 static_type, guint32 size, guint32 align, uintptr_t * bitmap, int numbits)
{
  _Bool D.24880;
  long int D.24881;
  long int D.24882;
  struct MonoGHashTable * threads.128;
  void * offset.129;
  _Bool D.24894;
  long int D.24895;
  long int D.24896;
  _Bool D.24900;
  long int D.24901;
  long int D.24902;
  _Bool D.24907;
  long int D.24908;
  long int D.24909;
  _Bool D.24914;
  long int D.24915;
  long int D.24916;
  uint32_t D.24919;
  guint32 offset;

  if (static_type == 1) goto <D.24876>; else goto <D.24877>;
  <D.24876>:
  {
    struct MonoThreadDomainTls * item;

    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24878>; else goto <D.24879>;
      <D.24878>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.24879>:
      D.24880 = ret != 0;
      D.24881 = (long int) D.24880;
      D.24882 = __builtin_expect (D.24881, 0);
      if (D.24882 != 0) goto <D.24883>; else goto <D.24884>;
      <D.24883>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3902, "ret == 0");
      <D.24884>:
    }
    item = search_tls_slot_in_freelist (&thread_static_info, size, align);
    if (item != 0B) goto <D.24885>; else goto <D.24886>;
    <D.24885>:
    offset = item->offset;
    monoeg_g_free (item);
    goto <D.24887>;
    <D.24886>:
    offset = mono_alloc_static_data_slot (&thread_static_info, size, align);
    <D.24887>:
    update_tls_reference_bitmap (offset, bitmap, numbits);
    threads.128 = threads;
    if (threads.128 != 0B) goto <D.24889>; else goto <D.24890>;
    <D.24889>:
    threads.128 = threads;
    offset.129 = (void *) offset;
    mono_g_hash_table_foreach (threads.128, alloc_thread_static_data_helper, offset.129);
    <D.24890>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.24892>; else goto <D.24893>;
      <D.24892>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.24893>:
      D.24894 = ret != 0;
      D.24895 = (long int) D.24894;
      D.24896 = __builtin_expect (D.24895, 0);
      if (D.24896 != 0) goto <D.24897>; else goto <D.24898>;
      <D.24897>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3915, "ret == 0");
      <D.24898>:
    }
  }
  goto <D.24899>;
  <D.24877>:
  D.24900 = static_type != 2;
  D.24901 = (long int) D.24900;
  D.24902 = __builtin_expect (D.24901, 0);
  if (D.24902 != 0) goto <D.24903>; else goto <D.24904>;
  <D.24903>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3917, "static_type == SPECIAL_STATIC_CONTEXT");
  <D.24904>:
  {
    int ret;

    ret = pthread_mutex_lock (&contexts_mutex.mutex);
    if (ret != 0) goto <D.24905>; else goto <D.24906>;
    <D.24905>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.24906>:
    D.24907 = ret != 0;
    D.24908 = (long int) D.24907;
    D.24909 = __builtin_expect (D.24908, 0);
    if (D.24909 != 0) goto <D.24910>; else goto <D.24911>;
    <D.24910>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3918, "ret == 0");
    <D.24911>:
  }
  offset = mono_alloc_static_data_slot (&context_static_info, size, align);
  {
    int ret;

    ret = pthread_mutex_unlock (&contexts_mutex.mutex);
    if (ret != 0) goto <D.24912>; else goto <D.24913>;
    <D.24912>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.24913>:
    D.24914 = ret != 0;
    D.24915 = (long int) D.24914;
    D.24916 = __builtin_expect (D.24915, 0);
    if (D.24916 != 0) goto <D.24917>; else goto <D.24918>;
    <D.24917>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3920, "ret == 0");
    <D.24918>:
  }
  offset = offset | 2147483648;
  <D.24899>:
  D.24919 = offset;
  return D.24919;
}


alloc_thread_static_data_helper (void * key, void * value, void * user)
{
  void * * * D.24921;
  struct MonoInternalThread * thread;
  guint32 offset;

  thread = value;
  offset = (guint32) user;
  D.24921 = &thread->static_data;
  mono_alloc_static_data (D.24921, offset, 1);
}


search_tls_slot_in_freelist (struct StaticDataInfo * static_data, guint32 size, guint32 align)
{
  unsigned int D.24922;
  struct MonoThreadDomainTls * D.24927;
  struct MonoThreadDomainTls * D.24929;
  struct MonoThreadDomainTls * prev;
  struct MonoThreadDomainTls * tmp;

  prev = 0B;
  tmp = static_data->freelist;
  goto <D.22258>;
  <D.22257>:
  D.24922 = tmp->size;
  if (D.24922 == size) goto <D.24923>; else goto <D.24924>;
  <D.24923>:
  if (prev != 0B) goto <D.24925>; else goto <D.24926>;
  <D.24925>:
  D.24927 = tmp->next;
  prev->next = D.24927;
  goto <D.24928>;
  <D.24926>:
  D.24927 = tmp->next;
  static_data->freelist = D.24927;
  <D.24928>:
  D.24929 = tmp;
  return D.24929;
  <D.24924>:
  tmp = tmp->next;
  <D.22258>:
  if (tmp != 0B) goto <D.22257>; else goto <D.22259>;
  <D.22259>:
  D.24929 = 0B;
  return D.24929;
}


update_tls_reference_bitmap (guint32 offset, uintptr_t * bitmap, int numbits)
{
  unsigned int D.24931;
  unsigned int D.24932;
  uintptr_t * D.24933;
  int D.24936;
  unsigned int D.24937;
  unsigned int D.24938;
  unsigned int D.24939;
  unsigned int D.24940;
  void * D.24941;
  unsigned int i.130;
  unsigned int D.24943;
  unsigned int D.24944;
  uintptr_t * D.24945;
  unsigned int D.24946;
  int D.24947;
  long int D.24948;
  long unsigned int D.24949;
  long unsigned int D.24950;
  unsigned int i.131;
  unsigned int D.24954;
  unsigned int D.24955;
  unsigned int D.24956;
  uintptr_t * D.24957;
  unsigned int D.24958;
  int D.24959;
  int D.24960;
  long int D.24961;
  long unsigned int D.24962;
  long unsigned int D.24963;
  int i;
  int idx;
  uintptr_t * rb;

  D.24931 = offset >> 24;
  D.24932 = D.24931 + 4294967295;
  idx = (int) D.24932;
  D.24933 = static_reference_bitmaps[idx];
  if (D.24933 == 0B) goto <D.24934>; else goto <D.24935>;
  <D.24934>:
  D.24936 = static_data_size[idx];
  D.24937 = (unsigned int) D.24936;
  D.24938 = D.24937 / 128;
  D.24939 = D.24938 + 1;
  D.24940 = D.24939 * 4;
  D.24941 = monoeg_malloc0 (D.24940);
  static_reference_bitmaps[idx] = D.24941;
  <D.24935>:
  rb = static_reference_bitmaps[idx];
  offset = offset & 16777215;
  offset = offset / 4;
  i = 0;
  goto <D.22269>;
  <D.22268>:
  i.130 = (unsigned int) i;
  D.24943 = i.130 / 4;
  D.24944 = D.24943 * 4;
  D.24945 = bitmap + D.24944;
  D.24946 = *D.24945;
  D.24947 = i & 31;
  D.24948 = 1 << D.24947;
  D.24949 = (long unsigned int) D.24948;
  D.24950 = D.24946 & D.24949;
  if (D.24950 != 0) goto <D.24951>; else goto <D.24952>;
  <D.24951>:
  i.131 = (unsigned int) i;
  D.24954 = offset + i.131;
  D.24955 = D.24954 / 32;
  D.24956 = D.24955 * 4;
  D.24957 = rb + D.24956;
  D.24956 = D.24955 * 4;
  D.24957 = rb + D.24956;
  D.24958 = *D.24957;
  i.131 = (unsigned int) i;
  D.24954 = offset + i.131;
  D.24959 = (int) D.24954;
  D.24960 = D.24959 & 31;
  D.24961 = 1 << D.24960;
  D.24962 = (long unsigned int) D.24961;
  D.24963 = D.24958 | D.24962;
  *D.24957 = D.24963;
  <D.24952>:
  i = i + 1;
  <D.22269>:
  if (i < numbits) goto <D.22268>; else goto <D.22270>;
  <D.22270>:
}


mono_alloc_static_data_slot (struct StaticDataInfo * static_data, guint32 size, guint32 align)
{
  int D.24964;
  int D.24967;
  unsigned int D.24970;
  unsigned int D.24971;
  unsigned int D.24972;
  int D.24973;
  unsigned int D.24974;
  unsigned int D.24975;
  int D.24976;
  unsigned int D.24977;
  int D.24978;
  unsigned int D.24979;
  int D.24982;
  _Bool D.24983;
  long int D.24984;
  long int D.24985;
  _Bool D.24988;
  long int D.24989;
  long int D.24990;
  int D.24993;
  int D.24994;
  int D.24995;
  guint32 D.24996;
  guint32 offset;

  D.24964 = static_data->idx;
  if (D.24964 == 0) goto <D.24965>; else goto <D.24966>;
  <D.24965>:
  D.24967 = static_data->offset;
  if (D.24967 == 0) goto <D.24968>; else goto <D.24969>;
  <D.24968>:
  static_data->offset = 32;
  <D.24969>:
  <D.24966>:
  D.24967 = static_data->offset;
  D.24970 = (unsigned int) D.24967;
  D.24971 = D.24970 + align;
  D.24972 = D.24971 + 4294967295;
  D.24973 = (int) D.24972;
  static_data->offset = D.24973;
  D.24967 = static_data->offset;
  D.24970 = (unsigned int) D.24967;
  D.24974 = -align;
  D.24975 = D.24970 & D.24974;
  D.24976 = (int) D.24975;
  static_data->offset = D.24976;
  D.24967 = static_data->offset;
  D.24970 = (unsigned int) D.24967;
  D.24977 = D.24970 + size;
  D.24964 = static_data->idx;
  D.24978 = static_data_size[D.24964];
  D.24979 = (unsigned int) D.24978;
  if (D.24977 >= D.24979) goto <D.24980>; else goto <D.24981>;
  <D.24980>:
  D.24964 = static_data->idx;
  D.24982 = D.24964 + 1;
  static_data->idx = D.24982;
  D.24964 = static_data->idx;
  D.24978 = static_data_size[D.24964];
  D.24979 = (unsigned int) D.24978;
  D.24983 = D.24979 < size;
  D.24984 = (long int) D.24983;
  D.24985 = __builtin_expect (D.24984, 0);
  if (D.24985 != 0) goto <D.24986>; else goto <D.24987>;
  <D.24986>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3801, "size <= static_data_size [static_data->idx]");
  <D.24987>:
  D.24964 = static_data->idx;
  D.24988 = D.24964 > 7;
  D.24989 = (long int) D.24988;
  D.24990 = __builtin_expect (D.24989, 0);
  if (D.24990 != 0) goto <D.24991>; else goto <D.24992>;
  <D.24991>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3802, "static_data->idx < NUM_STATIC_DATA_IDX");
  <D.24992>:
  static_data->offset = 0;
  <D.24981>:
  D.24967 = static_data->offset;
  D.24964 = static_data->idx;
  D.24982 = D.24964 + 1;
  D.24993 = D.24982 << 24;
  D.24994 = D.24967 | D.24993;
  offset = (guint32) D.24994;
  D.24967 = static_data->offset;
  D.24970 = (unsigned int) D.24967;
  D.24977 = D.24970 + size;
  D.24995 = (int) D.24977;
  static_data->offset = D.24995;
  D.24996 = offset;
  return D.24996;
}


mono_get_special_static_data_for_thread (struct MonoInternalThread * thread, guint32 offset)
{
  unsigned int D.24998;
  unsigned int D.24999;
  void * D.25002;
  void * * D.25005;
  unsigned int idx.132;
  unsigned int D.25008;
  void * * D.25009;
  void * D.25010;
  _Bool D.25013;
  long int D.25014;
  long int D.25015;
  void * * * D.25018;
  _Bool D.25021;
  long int D.25022;
  long int D.25023;
  sizetype D.25026;
  guint32 static_type;
  int idx;

  static_type = offset & 2147483648;
  offset = offset & 2147483647;
  D.24998 = offset >> 24;
  D.24999 = D.24998 + 4294967295;
  idx = (int) D.24999;
  if (static_type == 0) goto <D.25000>; else goto <D.25001>;
  <D.25000>:
  D.25002 = get_thread_static_data (thread, offset);
  return D.25002;
  <D.25001>:
  {
    struct MonoAppContext * context;

    context = mono_context_get ();
    D.25005 = context->static_data;
    if (D.25005 == 0B) goto <D.25003>; else goto <D.25006>;
    <D.25006>:
    D.25005 = context->static_data;
    idx.132 = (unsigned int) idx;
    D.25008 = idx.132 * 4;
    D.25009 = D.25005 + D.25008;
    D.25010 = *D.25009;
    if (D.25010 == 0B) goto <D.25003>; else goto <D.25004>;
    <D.25003>:
    {
      int ret;

      ret = pthread_mutex_lock (&contexts_mutex.mutex);
      if (ret != 0) goto <D.25011>; else goto <D.25012>;
      <D.25011>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.25012>:
      D.25013 = ret != 0;
      D.25014 = (long int) D.25013;
      D.25015 = __builtin_expect (D.25014, 0);
      if (D.25015 != 0) goto <D.25016>; else goto <D.25017>;
      <D.25016>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3945, "ret == 0");
      <D.25017>:
    }
    D.25018 = &context->static_data;
    mono_alloc_static_data (D.25018, offset, 0);
    {
      int ret;

      ret = pthread_mutex_unlock (&contexts_mutex.mutex);
      if (ret != 0) goto <D.25019>; else goto <D.25020>;
      <D.25019>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.25020>:
      D.25021 = ret != 0;
      D.25022 = (long int) D.25021;
      D.25023 = __builtin_expect (D.25022, 0);
      if (D.25023 != 0) goto <D.25024>; else goto <D.25025>;
      <D.25024>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3947, "ret == 0");
      <D.25025>:
    }
    <D.25004>:
    D.25005 = context->static_data;
    idx.132 = (unsigned int) idx;
    D.25008 = idx.132 * 4;
    D.25009 = D.25005 + D.25008;
    D.25010 = *D.25009;
    D.25026 = offset & 16777215;
    D.25002 = D.25010 + D.25026;
    return D.25002;
  }
}


mono_get_special_static_data (guint32 offset)
{
  void * D.25028;
  struct MonoInternalThread * D.25029;

  D.25029 = mono_thread_internal_current ();
  D.25028 = mono_get_special_static_data_for_thread (D.25029, offset);
  return D.25028;
}


mono_alloc_special_static_data_free (struct GHashTable * special_static_fields)
{
  _Bool D.25033;
  long int D.25034;
  long int D.25035;
  _Bool D.25040;
  long int D.25041;
  long int D.25042;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.25031>; else goto <D.25032>;
    <D.25031>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.25032>:
    D.25033 = ret != 0;
    D.25034 = (long int) D.25033;
    D.25035 = __builtin_expect (D.25034, 0);
    if (D.25035 != 0) goto <D.25036>; else goto <D.25037>;
    <D.25036>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4020, "ret == 0");
    <D.25037>:
  }
  monoeg_g_hash_table_foreach (special_static_fields, do_free_special, 0B);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.25038>; else goto <D.25039>;
    <D.25038>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.25039>:
    D.25040 = ret != 0;
    D.25041 = (long int) D.25040;
    D.25042 = __builtin_expect (D.25041, 0);
    if (D.25042 != 0) goto <D.25043>; else goto <D.25044>;
    <D.25043>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4022, "ret == 0");
    <D.25044>:
  }
}


do_free_special (void * key, void * value, void * data)
{
  struct MonoType * D.25045;
  int D.25046;
  struct MonoClassField * field;
  guint32 offset;
  gint32 align;
  guint32 size;

  try
    {
      field = key;
      offset = (guint32) value;
      D.25045 = field->type;
      D.25046 = mono_type_size (D.25045, &align);
      size = (guint32) D.25046;
      do_free_special_slot (offset, size);
    }
  finally
    {
      align = {CLOBBER};
    }
}


do_free_special_slot (guint32 offset, guint32 size)
{
  unsigned int D.25049;
  unsigned int D.25050;
  unsigned int D.25051;
  struct MonoGHashTable * threads.133;
  int D.25055;
  struct MonoThreadDomainTls * D.25058;
  guint32 static_type;

  static_type = offset & 2147483648;
  if (static_type == 0) goto <D.25047>; else goto <D.25048>;
  <D.25047>:
  {
    struct TlsOffsetSize data;
    struct MonoThreadDomainTls * item;

    try
      {
        item = monoeg_malloc0 (12);
        D.25049 = offset & 2147483647;
        data.offset = D.25049;
        data.size = size;
        D.25050 = data.offset;
        D.25051 = data.size;
        clear_reference_bitmap (D.25050, D.25051);
        threads.133 = threads;
        if (threads.133 != 0B) goto <D.25053>; else goto <D.25054>;
        <D.25053>:
        threads.133 = threads;
        mono_g_hash_table_foreach (threads.133, free_thread_static_data_helper, &data);
        <D.25054>:
        item->offset = offset;
        item->size = size;
        D.25055 = mono_runtime_is_shutting_down ();
        if (D.25055 == 0) goto <D.25056>; else goto <D.25057>;
        <D.25056>:
        D.25058 = thread_static_info.freelist;
        item->next = D.25058;
        thread_static_info.freelist = item;
        goto <D.25059>;
        <D.25057>:
        monoeg_g_free (item);
        <D.25059>:
      }
    finally
      {
        data = {CLOBBER};
      }
  }
  goto <D.25060>;
  <D.25048>:
  <D.25060>:
}


free_thread_static_data_helper (void * key, void * value, void * user)
{
  unsigned int D.25061;
  unsigned int D.25062;
  unsigned int D.25063;
  void * * D.25066;
  unsigned int idx.134;
  unsigned int D.25069;
  void * * D.25070;
  void * D.25071;
  sizetype D.25072;
  unsigned int D.25073;
  struct MonoInternalThread * thread;
  struct TlsOffsetSize * data;
  int idx;
  char * ptr;

  thread = value;
  data = user;
  D.25061 = data->offset;
  D.25062 = D.25061 >> 24;
  D.25063 = D.25062 + 4294967295;
  idx = (int) D.25063;
  D.25066 = thread->static_data;
  if (D.25066 == 0B) goto <D.25064>; else goto <D.25067>;
  <D.25067>:
  D.25066 = thread->static_data;
  idx.134 = (unsigned int) idx;
  D.25069 = idx.134 * 4;
  D.25070 = D.25066 + D.25069;
  D.25071 = *D.25070;
  if (D.25071 == 0B) goto <D.25064>; else goto <D.25065>;
  <D.25064>:
  return;
  <D.25065>:
  D.25066 = thread->static_data;
  idx.134 = (unsigned int) idx;
  D.25069 = idx.134 * 4;
  D.25070 = D.25066 + D.25069;
  D.25071 = *D.25070;
  D.25061 = data->offset;
  D.25072 = D.25061 & 16777215;
  ptr = D.25071 + D.25072;
  D.25073 = data->size;
  mono_gc_bzero_atomic (ptr, D.25073);
}


clear_reference_bitmap (guint32 offset, guint32 size)
{
  unsigned int D.25075;
  unsigned int D.25076;
  unsigned int D.25077;
  unsigned int D.25078;
  uintptr_t * D.25079;
  unsigned int D.25080;
  int offset.135;
  int D.25082;
  long int D.25083;
  long int D.25084;
  long unsigned int D.25085;
  long unsigned int D.25086;
  int idx;
  uintptr_t * rb;

  D.25075 = offset >> 24;
  D.25076 = D.25075 + 4294967295;
  idx = (int) D.25076;
  rb = static_reference_bitmaps[idx];
  offset = offset & 16777215;
  offset = offset / 4;
  size = size / 4;
  size = size + offset;
  goto <D.22278>;
  <D.22277>:
  D.25077 = offset / 32;
  D.25078 = D.25077 * 4;
  D.25079 = rb + D.25078;
  D.25078 = D.25077 * 4;
  D.25079 = rb + D.25078;
  D.25080 = *D.25079;
  offset.135 = (int) offset;
  D.25082 = offset.135 & 31;
  D.25083 = 1 << D.25082;
  D.25084 = ~D.25083;
  D.25085 = (long unsigned int) D.25084;
  D.25086 = D.25080 & D.25085;
  *D.25079 = D.25086;
  offset = offset + 1;
  <D.22278>:
  if (offset < size) goto <D.22277>; else goto <D.22279>;
  <D.22279>:
}


mono_special_static_data_free_slot (guint32 offset, guint32 size)
{
  _Bool D.25089;
  long int D.25090;
  long int D.25091;
  _Bool D.25096;
  long int D.25097;
  long int D.25098;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.25087>; else goto <D.25088>;
    <D.25087>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.25088>:
    D.25089 = ret != 0;
    D.25090 = (long int) D.25089;
    D.25091 = __builtin_expect (D.25090, 0);
    if (D.25091 != 0) goto <D.25092>; else goto <D.25093>;
    <D.25092>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4028, "ret == 0");
    <D.25093>:
  }
  do_free_special_slot (offset, size);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.25094>; else goto <D.25095>;
    <D.25094>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.25095>:
    D.25096 = ret != 0;
    D.25097 = (long int) D.25096;
    D.25098 = __builtin_expect (D.25097, 0);
    if (D.25098 != 0) goto <D.25099>; else goto <D.25100>;
    <D.25099>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4030, "ret == 0");
    <D.25100>:
  }
}


mono_thread_alloc_tls (struct MonoReflectionType * type)
{
  struct MonoType * D.25101;
  int D.25102;
  int align.136;
  unsigned int align.137;
  int max_set.138;
  int D.25106;
  union mono_mutex_t * D.25109;
  _Bool D.25112;
  long int D.25113;
  long int D.25114;
  struct MonoTlsDataRecord * D.25117;
  _Bool D.25120;
  long int D.25121;
  long int D.25122;
  uint32_t D.25125;
  struct MonoDomain * domain;
  struct MonoClass * klass;
  struct MonoTlsDataRecord * tlsrec;
  int max_set;
  gsize * bitmap;
  gsize default_bitmap[4];
  uint32_t tls_offset;
  guint32 size;
  gint32 align;

  try
    {
      domain = mono_domain_get ();
      max_set = 0;
      default_bitmap = {};
      D.25101 = type->type;
      klass = mono_class_from_mono_type (D.25101);
      bitmap = mono_class_compute_bitmap (klass, &default_bitmap, 128, -2, &max_set, 0);
      D.25101 = type->type;
      D.25102 = mono_type_size (D.25101, &align);
      size = (guint32) D.25102;
      align.136 = align;
      align.137 = (unsigned int) align.136;
      max_set.138 = max_set;
      D.25106 = max_set.138 + 1;
      tls_offset = mono_alloc_special_static_data (1, size, align.137, bitmap, D.25106);
      if (&default_bitmap != bitmap) goto <D.25107>; else goto <D.25108>;
      <D.25107>:
      monoeg_g_free (bitmap);
      <D.25108>:
      tlsrec = monoeg_malloc0 (12);
      tlsrec->tls_offset = tls_offset;
      tlsrec->size = size;
      {
        int ret;

        D.25109 = &domain->lock.mutex;
        ret = pthread_mutex_lock (D.25109);
        if (ret != 0) goto <D.25110>; else goto <D.25111>;
        <D.25110>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.25111>:
        D.25112 = ret != 0;
        D.25113 = (long int) D.25112;
        D.25114 = __builtin_expect (D.25113, 0);
        if (D.25114 != 0) goto <D.25115>; else goto <D.25116>;
        <D.25115>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4060, "ret == 0");
        <D.25116>:
      }
      D.25117 = domain->tlsrec_list;
      tlsrec->next = D.25117;
      domain->tlsrec_list = tlsrec;
      {
        int ret;

        D.25109 = &domain->lock.mutex;
        ret = pthread_mutex_unlock (D.25109);
        if (ret != 0) goto <D.25118>; else goto <D.25119>;
        <D.25118>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.25119>:
        D.25120 = ret != 0;
        D.25121 = (long int) D.25120;
        D.25122 = __builtin_expect (D.25121, 0);
        if (D.25122 != 0) goto <D.25123>; else goto <D.25124>;
        <D.25123>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4063, "ret == 0");
        <D.25124>:
      }
      D.25125 = tls_offset;
      return D.25125;
    }
  finally
    {
      max_set = {CLOBBER};
      default_bitmap = {CLOBBER};
      align = {CLOBBER};
    }
}


mono_thread_destroy_tls (uint32_t tls_offset)
{
  union mono_mutex_t * D.25128;
  _Bool D.25131;
  long int D.25132;
  long int D.25133;
  unsigned int D.25136;
  struct MonoTlsDataRecord * D.25141;
  _Bool D.25145;
  long int D.25146;
  long int D.25147;
  struct MonoTlsDataRecord * prev;
  struct MonoTlsDataRecord * cur;
  guint32 size;
  struct MonoDomain * domain;

  prev = 0B;
  size = 0;
  domain = mono_domain_get ();
  {
    int ret;

    D.25128 = &domain->lock.mutex;
    ret = pthread_mutex_lock (D.25128);
    if (ret != 0) goto <D.25129>; else goto <D.25130>;
    <D.25129>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.25130>:
    D.25131 = ret != 0;
    D.25132 = (long int) D.25131;
    D.25133 = __builtin_expect (D.25132, 0);
    if (D.25133 != 0) goto <D.25134>; else goto <D.25135>;
    <D.25134>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4074, "ret == 0");
    <D.25135>:
  }
  cur = domain->tlsrec_list;
  goto <D.22369>;
  <D.22368>:
  D.25136 = cur->tls_offset;
  if (D.25136 == tls_offset) goto <D.25137>; else goto <D.25138>;
  <D.25137>:
  if (prev != 0B) goto <D.25139>; else goto <D.25140>;
  <D.25139>:
  D.25141 = cur->next;
  prev->next = D.25141;
  goto <D.25142>;
  <D.25140>:
  D.25141 = cur->next;
  domain->tlsrec_list = D.25141;
  <D.25142>:
  size = cur->size;
  monoeg_g_free (cur);
  goto <D.22367>;
  <D.25138>:
  prev = cur;
  cur = cur->next;
  <D.22369>:
  if (cur != 0B) goto <D.22368>; else goto <D.22367>;
  <D.22367>:
  {
    int ret;

    D.25128 = &domain->lock.mutex;
    ret = pthread_mutex_unlock (D.25128);
    if (ret != 0) goto <D.25143>; else goto <D.25144>;
    <D.25143>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.25144>:
    D.25145 = ret != 0;
    D.25146 = (long int) D.25145;
    D.25147 = __builtin_expect (D.25146, 0);
    if (D.25147 != 0) goto <D.25148>; else goto <D.25149>;
    <D.25148>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4089, "ret == 0");
    <D.25149>:
  }
  if (size != 0) goto <D.25150>; else goto <D.25151>;
  <D.25150>:
  mono_special_static_data_free_slot (tls_offset, size);
  <D.25151>:
}


mono_thread_destroy_domain_tls (struct MonoDomain * domain)
{
  struct MonoTlsDataRecord * D.25152;
  unsigned int D.25153;

  goto <D.22375>;
  <D.22374>:
  D.25152 = domain->tlsrec_list;
  D.25153 = D.25152->tls_offset;
  mono_thread_destroy_tls (D.25153);
  <D.22375>:
  D.25152 = domain->tlsrec_list;
  if (D.25152 != 0B) goto <D.22374>; else goto <D.22376>;
  <D.22376>:
}


mono_thread_free_local_slot_values (int slot, MonoBoolean thread_local)
{
  struct MonoClassField * local_slots.139;
  struct MonoClass * D.25159;
  struct MonoClassField * local_slots.140;
  union mono_mutex_t * D.25163;
  _Bool D.25166;
  long int D.25167;
  long int D.25168;
  struct GHashTable * D.25171;
  _Bool D.25176;
  long int D.25177;
  long int D.25178;
  unsigned int addr.141;
  unsigned int D.25184;
  unsigned int D.25185;
  unsigned int D.25186;
  unsigned int D.25187;
  int D.25188;
  _Bool D.25191;
  long int D.25192;
  long int D.25193;
  struct MonoGHashTable * threads.142;
  _Bool D.25199;
  long int D.25200;
  long int D.25201;
  struct MonoDomain * domain;
  struct LocalSlotID sid;

  try
    {
      sid.slot = slot;
      if (thread_local != 0) goto <D.25154>; else goto <D.25155>;
      <D.25154>:
      {
        void * addr;

        addr = 0B;
        local_slots.139 = local_slots;
        if (local_slots.139 == 0B) goto <D.25157>; else goto <D.25158>;
        <D.25157>:
        D.25159 = mono_defaults.thread_class;
        local_slots.140 = mono_class_get_field_from_name (D.25159, "local_slots");
        local_slots = local_slots.140;
        local_slots.139 = local_slots;
        if (local_slots.139 == 0B) goto <D.25161>; else goto <D.25162>;
        <D.25161>:
        monoeg_g_log (0B, 16, "local_slots field not found in Thread class");
        return;
        <D.25162>:
        <D.25158>:
        domain = mono_domain_get ();
        {
          int ret;

          D.25163 = &domain->lock.mutex;
          ret = pthread_mutex_lock (D.25163);
          if (ret != 0) goto <D.25164>; else goto <D.25165>;
          <D.25164>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.25165>:
          D.25166 = ret != 0;
          D.25167 = (long int) D.25166;
          D.25168 = __builtin_expect (D.25167, 0);
          if (D.25168 != 0) goto <D.25169>; else goto <D.25170>;
          <D.25169>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4150, "ret == 0");
          <D.25170>:
        }
        D.25171 = domain->special_static_fields;
        if (D.25171 != 0B) goto <D.25172>; else goto <D.25173>;
        <D.25172>:
        D.25171 = domain->special_static_fields;
        local_slots.139 = local_slots;
        addr = monoeg_g_hash_table_lookup (D.25171, local_slots.139);
        <D.25173>:
        {
          int ret;

          D.25163 = &domain->lock.mutex;
          ret = pthread_mutex_unlock (D.25163);
          if (ret != 0) goto <D.25174>; else goto <D.25175>;
          <D.25174>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.25175>:
          D.25176 = ret != 0;
          D.25177 = (long int) D.25176;
          D.25178 = __builtin_expect (D.25177, 0);
          if (D.25178 != 0) goto <D.25179>; else goto <D.25180>;
          <D.25179>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4153, "ret == 0");
          <D.25180>:
        }
        if (addr == 0B) goto <D.25181>; else goto <D.25182>;
        <D.25181>:
        return;
        <D.25182>:
        addr.141 = (unsigned int) addr;
        sid.offset = addr.141;
        D.25184 = sid.offset;
        D.25185 = D.25184 & 2147483647;
        sid.offset = D.25185;
        D.25184 = sid.offset;
        D.25186 = D.25184 >> 24;
        D.25187 = D.25186 + 4294967295;
        D.25188 = (int) D.25187;
        sid.idx = D.25188;
        {
          int ret;

          ret = pthread_mutex_lock (&threads_mutex.mutex);
          if (ret != 0) goto <D.25189>; else goto <D.25190>;
          <D.25189>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.25190>:
          D.25191 = ret != 0;
          D.25192 = (long int) D.25191;
          D.25193 = __builtin_expect (D.25192, 0);
          if (D.25193 != 0) goto <D.25194>; else goto <D.25195>;
          <D.25194>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4160, "ret == 0");
          <D.25195>:
        }
        threads.142 = threads;
        mono_g_hash_table_foreach (threads.142, clear_local_slot, &sid);
        {
          int ret;

          ret = pthread_mutex_unlock (&threads_mutex.mutex);
          if (ret != 0) goto <D.25197>; else goto <D.25198>;
          <D.25197>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.25198>:
          D.25199 = ret != 0;
          D.25200 = (long int) D.25199;
          D.25201 = __builtin_expect (D.25200, 0);
          if (D.25201 != 0) goto <D.25202>; else goto <D.25203>;
          <D.25202>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4162, "ret == 0");
          <D.25203>:
        }
      }
      goto <D.25204>;
      <D.25155>:
      <D.25204>:
    }
  finally
    {
      sid = {CLOBBER};
    }
}


clear_local_slot (void * key, void * value, void * user_data)
{
  void * * D.25210;
  int D.25212;
  unsigned int D.25213;
  unsigned int D.25214;
  void * * D.25215;
  void * D.25216;
  unsigned int D.25217;
  sizetype D.25218;
  struct MonoArray * * D.25219;
  int D.25223;
  unsigned int D.25224;
  unsigned int D.25225;
  struct LocalSlotID * sid;
  struct MonoInternalThread * thread;
  struct MonoArray * slots_array;

  sid = user_data;
  thread = value;
  D.25210 = thread->static_data;
  if (D.25210 == 0B) goto <D.25208>; else goto <D.25211>;
  <D.25211>:
  D.25210 = thread->static_data;
  D.25212 = sid->idx;
  D.25213 = (unsigned int) D.25212;
  D.25214 = D.25213 * 4;
  D.25215 = D.25210 + D.25214;
  D.25216 = *D.25215;
  if (D.25216 == 0B) goto <D.25208>; else goto <D.25209>;
  <D.25208>:
  return;
  <D.25209>:
  D.25210 = thread->static_data;
  D.25212 = sid->idx;
  D.25213 = (unsigned int) D.25212;
  D.25214 = D.25213 * 4;
  D.25215 = D.25210 + D.25214;
  D.25216 = *D.25215;
  D.25217 = sid->offset;
  D.25218 = D.25217 & 16777215;
  D.25219 = D.25216 + D.25218;
  slots_array = *D.25219;
  if (slots_array == 0B) goto <D.25220>; else goto <D.25222>;
  <D.25222>:
  D.25223 = sid->slot;
  D.25224 = (unsigned int) D.25223;
  D.25225 = mono_array_length (slots_array);
  if (D.25224 >= D.25225) goto <D.25220>; else goto <D.25221>;
  <D.25220>:
  return;
  <D.25221>:
  {
    struct MonoObject * * __p;

    D.25223 = sid->slot;
    D.25224 = (unsigned int) D.25223;
    __p = mono_array_addr_with_size (slots_array, 4, D.25224);
    *__p = 0B;
  }
}


mono_thread_request_interruption (gboolean running_managed)
{
  struct MonoException * D.25229;
  gint32 * D.25230;
  int D.25231;
  int D.25237;
  void (*<Tf21>) (void) mono_thread_notify_pending_exc_fn.143;
  void * D.25243;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.25227>; else goto <D.25228>;
  <D.25227>:
  D.25229 = 0B;
  return D.25229;
  <D.25228>:
  D.25230 = &thread->interruption_requested;
  D.25231 = InterlockedCompareExchange (D.25230, 1, 0);
  if (D.25231 == 1) goto <D.25232>; else goto <D.25233>;
  <D.25232>:
  D.25229 = 0B;
  return D.25229;
  <D.25233>:
  InterlockedIncrement (&thread_interruption_requested);
  if (running_managed == 0) goto <D.25234>; else goto <D.25236>;
  <D.25236>:
  D.25237 = is_running_protected_wrapper ();
  if (D.25237 != 0) goto <D.25234>; else goto <D.25235>;
  <D.25234>:
  mono_thread_notify_pending_exc_fn.143 = mono_thread_notify_pending_exc_fn;
  if (mono_thread_notify_pending_exc_fn.143 != 0B) goto <D.25239>; else goto <D.25240>;
  <D.25239>:
  if (running_managed == 0) goto <D.25241>; else goto <D.25242>;
  <D.25241>:
  mono_thread_notify_pending_exc_fn.143 = mono_thread_notify_pending_exc_fn;
  mono_thread_notify_pending_exc_fn.143 ();
  <D.25242>:
  <D.25240>:
  D.25243 = thread->handle;
  QueueUserAPC (dummy_apc, D.25243, 0B);
  D.25229 = 0B;
  return D.25229;
  <D.25235>:
  D.25229 = mono_thread_execute_interruption (thread);
  return D.25229;
}


dummy_apc (void * param)
{
  guint32 D.25245;

  D.25245 = 0;
  return D.25245;
}


mono_thread_resume_interruption ()
{
  struct MonoException * D.25249;
  unsigned int D.25250;
  unsigned int D.25251;
  _Bool D.25252;
  gint32 * D.25255;
  int D.25256;
  struct MonoInternalThread * thread;
  gboolean still_aborting;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.25247>; else goto <D.25248>;
  <D.25247>:
  D.25249 = 0B;
  return D.25249;
  <D.25248>:
  lock_thread (thread);
  D.25250 = thread->state;
  D.25251 = D.25250 & 128;
  D.25252 = D.25251 != 0;
  still_aborting = (gboolean) D.25252;
  unlock_thread (thread);
  if (still_aborting == 0) goto <D.25253>; else goto <D.25254>;
  <D.25253>:
  D.25249 = 0B;
  return D.25249;
  <D.25254>:
  D.25255 = &thread->interruption_requested;
  D.25256 = InterlockedCompareExchange (D.25255, 1, 0);
  if (D.25256 == 1) goto <D.25257>; else goto <D.25258>;
  <D.25257>:
  D.25249 = 0B;
  return D.25249;
  <D.25258>:
  InterlockedIncrement (&thread_interruption_requested);
  wapi_self_interrupt ();
  D.25249 = mono_thread_execute_interruption (thread);
  return D.25249;
}


mono_thread_interruption_requested ()
{
  int thread_interruption_requested.144;
  gboolean D.25265;

  thread_interruption_requested.144 = thread_interruption_requested;
  if (thread_interruption_requested.144 != 0) goto <D.25261>; else goto <D.25262>;
  <D.25261>:
  {
    struct MonoInternalThread * thread;

    thread = mono_thread_internal_current ();
    if (thread != 0B) goto <D.25263>; else goto <D.25264>;
    <D.25263>:
    D.25265 = thread->interruption_requested;
    return D.25265;
    <D.25264>:
  }
  <D.25262>:
  D.25265 = 0;
  return D.25265;
}


mono_thread_interruption_checkpoint ()
{
  mono_thread_interruption_checkpoint_request (0);
}


mono_thread_interruption_checkpoint_request (gboolean bypass_abort_protection)
{
  int D.25271;
  int D.25275;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.25267>; else goto <D.25268>;
  <D.25267>:
  return;
  <D.25268>:
  D.25271 = thread->interruption_requested;
  if (D.25271 != 0) goto <D.25272>; else goto <D.25273>;
  <D.25272>:
  if (bypass_abort_protection != 0) goto <D.25269>; else goto <D.25274>;
  <D.25274>:
  D.25275 = is_running_protected_wrapper ();
  if (D.25275 == 0) goto <D.25269>; else goto <D.25270>;
  <D.25269>:
  {
    struct MonoException * exc;

    exc = mono_thread_execute_interruption (thread);
    if (exc != 0B) goto <D.25276>; else goto <D.25277>;
    <D.25276>:
    mono_raise_exception (exc);
    <D.25277>:
  }
  <D.25270>:
  <D.25273>:
}


mono_thread_force_interruption_checkpoint ()
{
  mono_thread_interruption_checkpoint_request (1);
}


mono_thread_get_and_clear_pending_exception ()
{
  struct MonoException * D.25281;
  int D.25282;
  int D.25285;
  struct MonoException * D.25288;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.25279>; else goto <D.25280>;
  <D.25279>:
  D.25281 = 0B;
  return D.25281;
  <D.25280>:
  D.25282 = thread->interruption_requested;
  if (D.25282 != 0) goto <D.25283>; else goto <D.25284>;
  <D.25283>:
  D.25285 = is_running_protected_wrapper ();
  if (D.25285 == 0) goto <D.25286>; else goto <D.25287>;
  <D.25286>:
  D.25281 = mono_thread_execute_interruption (thread);
  return D.25281;
  <D.25287>:
  <D.25284>:
  D.25288 = thread->pending_exception;
  if (D.25288 != 0B) goto <D.25289>; else goto <D.25290>;
  <D.25289>:
  {
    struct MonoException * exc;

    exc = thread->pending_exception;
    thread->pending_exception = 0B;
    D.25281 = exc;
    return D.25281;
  }
  <D.25290>:
  D.25281 = 0B;
  return D.25281;
}


mono_set_pending_exception (struct MonoException * exc)
{
  struct MonoException * * D.25294;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.25292>; else goto <D.25293>;
  <D.25292>:
  return;
  <D.25293>:
  D.25294 = &thread->pending_exception;
  mono_gc_wbarrier_set_field (thread, D.25294, exc);
  mono_thread_request_interruption (0);
}


mono_thread_interruption_request_flag ()
{
  gint32 * D.25296;

  D.25296 = &thread_interruption_requested;
  return D.25296;
}


mono_thread_init_apartment_state ()
{

}


mono_thread_cleanup_apartment_state ()
{

}


mono_thread_set_state (struct MonoInternalThread * thread, MonoThreadState state)
{
  unsigned int D.25298;
  unsigned int D.25299;

  lock_thread (thread);
  D.25298 = thread->state;
  D.25299 = D.25298 | state;
  thread->state = D.25299;
  unlock_thread (thread);
}


mono_thread_clr_state (struct MonoInternalThread * thread, MonoThreadState state)
{
  unsigned int D.25300;
  unsigned int D.25301;
  unsigned int D.25302;

  lock_thread (thread);
  D.25300 = thread->state;
  D.25301 = ~state;
  D.25302 = D.25300 & D.25301;
  thread->state = D.25302;
  unlock_thread (thread);
}


mono_thread_test_state (struct MonoInternalThread * thread, MonoThreadState test)
{
  unsigned int D.25303;
  unsigned int D.25304;
  gboolean D.25307;
  gboolean ret;

  ret = 0;
  lock_thread (thread);
  D.25303 = thread->state;
  D.25304 = D.25303 & test;
  if (D.25304 != 0) goto <D.25305>; else goto <D.25306>;
  <D.25305>:
  ret = 1;
  <D.25306>:
  unlock_thread (thread);
  D.25307 = ret;
  return D.25307;
}


mono_thread_get_execution_context ()
{
  struct MonoObject * D.25309;
  struct MonoObject * * D.25310;

  D.25310 = get_execution_context_addr ();
  D.25309 = *D.25310;
  return D.25309;
}


get_execution_context_addr ()
{
  struct MonoClass * D.25314;
  _Bool D.25315;
  long int D.25316;
  long int D.25317;
  struct MonoClass * D.25320;
  struct MonoVTable * D.25321;
  _Bool D.25322;
  long int D.25323;
  long int D.25324;
  union mono_mutex_t * D.25327;
  _Bool D.25330;
  long int D.25331;
  long int D.25332;
  struct GHashTable * D.25335;
  void * D.25336;
  _Bool D.25339;
  long int D.25340;
  long int D.25341;
  _Bool D.25344;
  long int D.25345;
  long int D.25346;
  struct MonoObject * * D.25349;
  struct MonoDomain * domain;
  guint32 offset;

  domain = mono_domain_get ();
  offset = domain->execution_context_field_offset;
  if (offset == 0) goto <D.25312>; else goto <D.25313>;
  <D.25312>:
  {
    struct MonoClassField * field;

    D.25314 = mono_defaults.thread_class;
    field = mono_class_get_field_from_name (D.25314, "_ec");
    D.25315 = field == 0B;
    D.25316 = (long int) D.25315;
    D.25317 = __builtin_expect (D.25316, 0);
    if (D.25317 != 0) goto <D.25318>; else goto <D.25319>;
    <D.25318>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4501, "field");
    <D.25319>:
    D.25320 = mono_defaults.appdomain_class;
    D.25321 = mono_class_try_get_vtable (domain, D.25320);
    D.25322 = D.25321 == 0B;
    D.25323 = (long int) D.25322;
    D.25324 = __builtin_expect (D.25323, 0);
    if (D.25324 != 0) goto <D.25325>; else goto <D.25326>;
    <D.25325>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4503, "mono_class_try_get_vtable (domain, mono_defaults.appdomain_class)");
    <D.25326>:
    {
      int ret;

      D.25327 = &domain->lock.mutex;
      ret = pthread_mutex_lock (D.25327);
      if (ret != 0) goto <D.25328>; else goto <D.25329>;
      <D.25328>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.25329>:
      D.25330 = ret != 0;
      D.25331 = (long int) D.25330;
      D.25332 = __builtin_expect (D.25331, 0);
      if (D.25332 != 0) goto <D.25333>; else goto <D.25334>;
      <D.25333>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4505, "ret == 0");
      <D.25334>:
    }
    D.25335 = domain->special_static_fields;
    D.25336 = monoeg_g_hash_table_lookup (D.25335, field);
    offset = (guint32) D.25336;
    {
      int ret;

      D.25327 = &domain->lock.mutex;
      ret = pthread_mutex_unlock (D.25327);
      if (ret != 0) goto <D.25337>; else goto <D.25338>;
      <D.25337>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.25338>:
      D.25339 = ret != 0;
      D.25340 = (long int) D.25339;
      D.25341 = __builtin_expect (D.25340, 0);
      if (D.25341 != 0) goto <D.25342>; else goto <D.25343>;
      <D.25342>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4507, "ret == 0");
      <D.25343>:
    }
    D.25344 = offset == 0;
    D.25345 = (long int) D.25344;
    D.25346 = __builtin_expect (D.25345, 0);
    if (D.25346 != 0) goto <D.25347>; else goto <D.25348>;
    <D.25347>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4508, "offset");
    <D.25348>:
    domain->execution_context_field_offset = offset;
  }
  <D.25313>:
  D.25349 = mono_get_special_static_data (offset);
  return D.25349;
}


mono_thread_set_execution_context (struct MonoObject * ec)
{
  struct MonoObject * * D.25351;

  D.25351 = get_execution_context_addr ();
  *D.25351 = ec;
}


mono_runtime_set_has_tls_get (gboolean val)
{
  has_tls_get = val;
}


mono_runtime_has_tls_get ()
{
  gboolean D.25352;

  D.25352 = has_tls_get;
  return D.25352;
}


mono_thread_kill (struct MonoInternalThread * thread, int signal)
{
  int D.25354;
  long long unsigned int D.25355;
  long unsigned int D.25356;
  int D.25357;

  D.25355 = thread->tid;
  D.25356 = (long unsigned int) D.25355;
  D.25357 = mono_thread_get_abort_signal ();
  D.25354 = pthread_kill (D.25356, D.25357);
  return D.25354;
}


mono_thread_is_foreign (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.25359;
  mono_bool D.25360;
  int D.25361;
  _Bool D.25362;
  struct MonoThreadInfo * info;

  D.25359 = thread->internal_thread;
  info = D.25359->thread_info;
  D.25361 = info->runtime_thread;
  D.25362 = D.25361 == 0;
  D.25360 = (mono_bool) D.25362;
  return D.25360;
}


