__attribute__((visibility ("hidden")))
mono_thread_get_tls_key ()
{
  pthread_key_t D.20458;

  D.20458 = current_object_key;
  return D.20458;
}


__attribute__((visibility ("hidden")))
mono_thread_get_tls_offset ()
{
  gint32 D.20460;
  int offset;

  {
    guint64 foo;

    __asm__("basr	%%r1,0
	j	0f
	.quad tls_current_object@NTPOFF
0:
	lg	%0,4(%%r1)
	" : "=r" foo :  : "1");
    offset = (int) foo;
  }
  D.20460 = offset;
  return D.20460;
}


mono_thread_new_init (intptr_t tid, void * stack_start, void * func)
{
  void (*<T14f4>) (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.20463>; else goto <D.20464>;
  <D.20463>:
  mono_thread_start_cb.0 = mono_thread_start_cb;
  mono_thread_start_cb.0 (tid, stack_start, func);
  <D.20464>:
}


mono_threads_set_default_stacksize (guint32 stacksize)
{
  default_stacksize = stacksize;
}


mono_threads_get_default_stacksize ()
{
  uint32_t D.20465;

  D.20465 = default_stacksize;
  return D.20465;
}


__attribute__((visibility ("hidden")))
mono_thread_create_internal (struct MonoDomain * domain, void * func, void * arg, gboolean threadpool_thread, gboolean no_detach, guint32 stack_size)
{
  struct _MonoInternalThread * * D.20467;
  guint32 (*<T334c>) (void *) func.1;
  struct MonoInternalThread * D.20471;
  const char * D.20472;
  struct MonoClass * D.20475;
  struct MonoClassField * D.20476;
  unsigned int D.20477;
  unsigned int D.20478;
  long unsigned int D.20479;
  long unsigned int D.20480;
  struct MonoClassField * D.20481;
  int D.20482;
  _Bool D.20483;
  long int D.20484;
  long int D.20485;
  struct MonoThread * thread;
  struct MonoInternalThread * internal;
  struct StartInfo * start_info;
  gboolean res;

  thread = create_thread_object (domain);
  internal = create_internal_thread ();
  D.20467 = &thread->internal_thread;
  mono_gc_wbarrier_set_field (thread, D.20467, internal);
  start_info = monoeg_malloc0 (32);
  func.1 = (guint32 (*<T334c>) (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.20469>; else goto <D.20470>;
  <D.20469>:
  D.20471 = 0B;
  return D.20471;
  <D.20470>:
  D.20472 = mono_check_corlib_version ();
  if (D.20472 == 0B) goto <D.20473>; else goto <D.20474>;
  <D.20473>:
  D.20475 = mono_defaults.internal_thread_class;
  D.20476 = D.20475->fields;
  D.20475 = mono_defaults.internal_thread_class;
  D.20477 = D.20475->field.count;
  D.20478 = D.20477 + 4294967295;
  D.20479 = (long unsigned int) D.20478;
  D.20480 = D.20479 * 32;
  D.20481 = D.20476 + D.20480;
  D.20482 = D.20481->offset;
  D.20483 = D.20482 != 312;
  D.20484 = (long int) D.20483;
  D.20485 = __builtin_expect (D.20484, 0);
  if (D.20485 != 0) goto <D.20486>; else goto <D.20487>;
  <D.20486>:
  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.20487>:
  <D.20474>:
  D.20471 = internal;
  return D.20471;
}


create_thread_object (struct MonoDomain * domain)
{
  struct MonoClass * D.20489;
  struct MonoThread * D.20490;
  struct MonoVTable * vt;

  D.20489 = mono_defaults.thread_class;
  vt = mono_class_vtable (domain, D.20489);
  D.20490 = mono_gc_alloc_mature (vt);
  return D.20490;
}


create_internal_thread ()
{
  struct MonoDomain * D.20492;
  struct MonoClass * D.20493;
  void * D.20494;
  struct CRITICAL_SECTION * D.20495;
  unsigned int D.20496;
  int D.20497;
  int D.20498;
  void * * D.20501;
  struct MonoInternalThread * D.20502;
  struct MonoInternalThread * thread;
  struct MonoVTable * vt;

  D.20492 = mono_get_root_domain ();
  D.20493 = mono_defaults.internal_thread_class;
  vt = mono_class_vtable (D.20492, D.20493);
  thread = mono_gc_alloc_mature (vt);
  D.20494 = monoeg_malloc0 (48);
  thread->synch_cs = D.20494;
  D.20495 = thread->synch_cs;
  InitializeCriticalSection (D.20495);
  thread->apartment_state = 2;
  D.20496 = get_next_managed_thread_id ();
  D.20497 = (int) D.20496;
  thread->managed_id = D.20497;
  D.20498 = mono_gc_is_moving ();
  if (D.20498 != 0) goto <D.20499>; else goto <D.20500>;
  <D.20499>:
  thread->thread_pinning_ref = thread;
  D.20501 = &thread->thread_pinning_ref;
  mono_gc_register_root (D.20501, 8, 0B);
  <D.20500>:
  D.20502 = thread;
  return D.20502;
}


get_next_managed_thread_id ()
{
  guint32 D.20504;
  int D.20505;

  D.20505 = InterlockedIncrement (&managed_thread_id_counter);
  D.20504 = (guint32) D.20505;
  return D.20504;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.20507;
  unsigned int D.20508;

  D.20508 = __sync_add_and_fetch_4 (val, 1);
  D.20507 = (gint32) D.20508;
  return D.20507;
}


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.20512;
  long int D.20513;
  long int D.20514;
  int shutting_down.2;
  _Bool D.20522;
  long int D.20523;
  long int D.20524;
  gboolean D.20527;
  struct MonoGHashTable * thread_start_args.3;
  int D.20531;
  struct MonoGHashTable * D.20534;
  void * D.20535;
  struct MonoGHashTable * threads_starting_up.4;
  int D.20539;
  struct MonoGHashTable * D.20542;
  _Bool D.20545;
  long int D.20546;
  long int D.20547;
  void * D.20550;
  void * D.20551;
  _Bool D.20556;
  long int D.20557;
  long int D.20558;
  _Bool D.20563;
  long int D.20564;
  long int D.20565;
  unsigned int D.20568;
  guint32 iftmp.5;
  int D.20572;
  _Bool D.20582;
  long int D.20583;
  long int D.20584;
  _Bool D.20589;
  long int D.20590;
  long int D.20591;
  struct MonoException * D.20596;
  unsigned int D.20598;
  long unsigned int tid.6;
  unsigned char D.20600;
  int D.20603;
  void * D.20606;
  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.20510>; else goto <D.20511>;
        <D.20510>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20511>:
        D.20512 = ret != 0;
        D.20513 = (long int) D.20512;
        D.20514 = __builtin_expect (D.20513, 0);
        if (D.20514 != 0) goto <D.20515>; else goto <D.20516>;
        <D.20515>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 705, "ret == 0");
        <D.20516>:
      }
      shutting_down.2 = shutting_down;
      if (shutting_down.2 != 0) goto <D.20518>; else goto <D.20519>;
      <D.20518>:
      monoeg_g_free (start_info);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20520>; else goto <D.20521>;
        <D.20520>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20521>:
        D.20522 = ret != 0;
        D.20523 = (long int) D.20522;
        D.20524 = __builtin_expect (D.20523, 0);
        if (D.20524 != 0) goto <D.20525>; else goto <D.20526>;
        <D.20525>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 708, "ret == 0");
        <D.20526>:
      }
      D.20527 = 0;
      return D.20527;
      <D.20519>:
      thread_start_args.3 = thread_start_args;
      if (thread_start_args.3 == 0B) goto <D.20529>; else goto <D.20530>;
      <D.20529>:
      D.20531 = mono_gc_is_moving ();
      if (D.20531 == 0) goto <D.20532>; else goto <D.20533>;
      <D.20532>:
      mono_gc_register_root (&thread_start_args, 8, 0B);
      <D.20533>:
      D.20534 = mono_g_hash_table_new (0B, 0B);
      thread_start_args = D.20534;
      <D.20530>:
      thread_start_args.3 = thread_start_args;
      D.20535 = start_info->start_arg;
      mono_g_hash_table_insert (thread_start_args.3, thread, D.20535);
      threads_starting_up.4 = threads_starting_up;
      if (threads_starting_up.4 == 0B) goto <D.20537>; else goto <D.20538>;
      <D.20537>:
      D.20539 = mono_gc_is_moving ();
      if (D.20539 == 0) goto <D.20540>; else goto <D.20541>;
      <D.20540>:
      mono_gc_register_root (&threads_starting_up, 8, 0B);
      <D.20541>:
      D.20542 = mono_g_hash_table_new_type (0B, 0B, 3);
      threads_starting_up = D.20542;
      <D.20538>:
      threads_starting_up.4 = threads_starting_up;
      mono_g_hash_table_insert (threads_starting_up.4, thread, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20543>; else goto <D.20544>;
        <D.20543>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20544>:
        D.20545 = ret != 0;
        D.20546 = (long int) D.20545;
        D.20547 = __builtin_expect (D.20546, 0);
        if (D.20547 != 0) goto <D.20548>; else goto <D.20549>;
        <D.20548>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 727, "ret == 0");
        <D.20549>:
      }
      D.20550 = CreateSemaphore (0B, 0, 2147483647, 0B);
      internal->start_notify = D.20550;
      D.20551 = internal->start_notify;
      if (D.20551 == 0B) goto <D.20552>; else goto <D.20553>;
      <D.20552>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20554>; else goto <D.20555>;
        <D.20554>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20555>:
        D.20556 = ret != 0;
        D.20557 = (long int) D.20556;
        D.20558 = __builtin_expect (D.20557, 0);
        if (D.20558 != 0) goto <D.20559>; else goto <D.20560>;
        <D.20559>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 731, "ret == 0");
        <D.20560>:
      }
      threads_starting_up.4 = threads_starting_up;
      mono_g_hash_table_remove (threads_starting_up.4, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20561>; else goto <D.20562>;
        <D.20561>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20562>:
        D.20563 = ret != 0;
        D.20564 = (long int) D.20563;
        D.20565 = __builtin_expect (D.20564, 0);
        if (D.20565 != 0) goto <D.20566>; else goto <D.20567>;
        <D.20566>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 733, "ret == 0");
        <D.20567>:
      }
      D.20568 = GetLastError ();
      monoeg_g_log (0B, 16, "%s: CreateSemaphore error 0x%x", &__func__, D.20568);
      monoeg_g_free (start_info);
      D.20527 = 0;
      return D.20527;
      <D.20553>:
      if (stack_size == 0) goto <D.20569>; else goto <D.20570>;
      <D.20569>:
      D.20572 = internal->stack_size;
      if (D.20572 != 0) goto <D.20573>; else goto <D.20574>;
      <D.20573>:
      D.20572 = internal->stack_size;
      iftmp.5 = (guint32) D.20572;
      goto <D.20575>;
      <D.20574>:
      iftmp.5 = default_stacksize;
      <D.20575>:
      stack_size = iftmp.5;
      <D.20570>:
      create_flags = 4;
      if (no_detach != 0) goto <D.20576>; else goto <D.20577>;
      <D.20576>:
      create_flags = create_flags | 268435456;
      <D.20577>:
      thread_handle = mono_threads_create_thread (start_wrapper, start_info, stack_size, create_flags, &tid);
      if (thread_handle == 0B) goto <D.20578>; else goto <D.20579>;
      <D.20578>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20580>; else goto <D.20581>;
        <D.20580>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20581>:
        D.20582 = ret != 0;
        D.20583 = (long int) D.20582;
        D.20584 = __builtin_expect (D.20583, 0);
        if (D.20584 != 0) goto <D.20585>; else goto <D.20586>;
        <D.20585>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 754, "ret == 0");
        <D.20586>:
      }
      threads_starting_up.4 = threads_starting_up;
      mono_g_hash_table_remove (threads_starting_up.4, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20587>; else goto <D.20588>;
        <D.20587>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20588>:
        D.20589 = ret != 0;
        D.20590 = (long int) D.20589;
        D.20591 = __builtin_expect (D.20590, 0);
        if (D.20591 != 0) goto <D.20592>; else goto <D.20593>;
        <D.20592>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 756, "ret == 0");
        <D.20593>:
      }
      monoeg_g_free (start_info);
      if (throw_on_failure != 0) goto <D.20594>; else goto <D.20595>;
      <D.20594>:
      D.20596 = mono_get_exception_execution_engine ("Couldn\'t create thread");
      mono_raise_exception (D.20596);
      goto <D.20597>;
      <D.20595>:
      D.20598 = GetLastError ();
      monoeg_g_log (0B, 16, "%s: CreateThread error 0x%x", &__func__, D.20598);
      <D.20597>:
      D.20527 = 0;
      return D.20527;
      <D.20579>:
      internal->handle = thread_handle;
      tid.6 = tid;
      internal->tid = tid.6;
      D.20600 = (unsigned char) threadpool_thread;
      internal->threadpool_thread = D.20600;
      if (threadpool_thread != 0) goto <D.20601>; else goto <D.20602>;
      <D.20601>:
      mono_thread_set_state (internal, 4);
      <D.20602>:
      D.20603 = handle_store (thread, 0);
      if (D.20603 == 0) goto <D.20604>; else goto <D.20605>;
      <D.20604>:
      D.20527 = 0;
      return D.20527;
      <D.20605>:
      D.20606 = internal->handle;
      ResumeThread (D.20606);
      D.20551 = internal->start_notify;
      if (D.20551 != 0B) goto <D.20607>; else goto <D.20608>;
      <D.20607>:
      D.20551 = internal->start_notify;
      WaitForSingleObjectEx (D.20551, 4294967295, 0);
      D.20551 = internal->start_notify;
      CloseHandle (D.20551);
      internal->start_notify = 0B;
      <D.20608>:
      D.20527 = 1;
      return D.20527;
    }
  finally
    {
      tid = {CLOBBER};
    }
}


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

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


start_wrapper_internal (void * data)
{
  struct MonoThread * D.20613;
  struct MonoVTable * D.20614;
  _Bool D.20615;
  long int D.20616;
  long int D.20617;
  long unsigned int tid.7;
  unsigned int current_object_key.8;
  int D.20622;
  guint32 D.20625;
  long unsigned int tid.9;
  long int tid.10;
  unsigned char D.20628;
  void * D.20631;
  _Bool D.20636;
  long int D.20637;
  long int D.20638;
  struct MonoGHashTable * thread_start_args.11;
  _Bool D.20644;
  long int D.20645;
  long int D.20646;
  struct MonoObject * D.20649;
  _Bool D.20653;
  long int D.20654;
  long int D.20655;
  struct MonoThreadInfo * info;
  struct StartInfo * start_info;
  guint32 (*<T334c>) (void *) start_func;
  void * start_arg;
  gsize tid;
  struct MonoInternalThread * internal;
  struct MonoObject * start_delegate;
  struct MonoDomain * domain;

  try
    {
      start_info = data;
      D.20613 = start_info->obj;
      internal = D.20613->internal_thread;
      start_delegate = start_info->delegate;
      D.20613 = start_info->obj;
      D.20614 = D.20613->obj.vtable;
      domain = D.20614->domain;
      info = mono_thread_info_current ();
      D.20615 = info == 0B;
      D.20616 = (long int) D.20615;
      D.20617 = __builtin_expect (D.20616, 0);
      if (D.20617 != 0) goto <D.20618>; else goto <D.20619>;
      <D.20618>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 570, "info");
      <D.20619>:
      internal->thread_info = info;
      tid.7 = internal->tid;
      tid = tid.7;
      tls_current_object = internal;
      current_object_key.8 = current_object_key;
      mono_native_tls_set_value (current_object_key.8, internal);
      mono_monitor_init_tls ();
      mono_thread_push_appdomain_ref (domain);
      D.20622 = mono_domain_set (domain, 0);
      if (D.20622 == 0) goto <D.20623>; else goto <D.20624>;
      <D.20623>:
      mono_thread_pop_appdomain_ref ();
      D.20625 = 0;
      return D.20625;
      <D.20624>:
      start_func = start_info->func;
      start_arg = start_info->start_arg;
      thread_adjust_static_data (internal);
      D.20613 = start_info->obj;
      init_root_domain_thread (internal, D.20613);
      tid.9 = tid;
      tid.10 = (long int) tid.9;
      mono_thread_new_init (tid.10, &tid, start_func);
      internal->stack_ptr = &tid;
      D.20628 = internal->apartment_state;
      if (D.20628 == 2) goto <D.20629>; else goto <D.20630>;
      <D.20629>:
      internal->apartment_state = 1;
      <D.20630>:
      mono_thread_init_apartment_state ();
      D.20631 = internal->start_notify;
      if (D.20631 != 0B) goto <D.20632>; else goto <D.20633>;
      <D.20632>:
      D.20631 = internal->start_notify;
      ReleaseSemaphore (D.20631, 1, 0B);
      <D.20633>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20634>; else goto <D.20635>;
        <D.20634>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20635>:
        D.20636 = ret != 0;
        D.20637 = (long int) D.20636;
        D.20638 = __builtin_expect (D.20637, 0);
        if (D.20638 != 0) goto <D.20639>; else goto <D.20640>;
        <D.20639>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 623, "ret == 0");
        <D.20640>:
      }
      thread_start_args.11 = thread_start_args;
      D.20613 = start_info->obj;
      mono_g_hash_table_remove (thread_start_args.11, D.20613);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20642>; else goto <D.20643>;
        <D.20642>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20643>:
        D.20644 = ret != 0;
        D.20645 = (long int) D.20644;
        D.20646 = __builtin_expect (D.20645, 0);
        if (D.20646 != 0) goto <D.20647>; else goto <D.20648>;
        <D.20647>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 625, "ret == 0");
        <D.20648>:
      }
      D.20613 = start_info->obj;
      D.20649 = D.20613->ec_to_set;
      mono_thread_set_execution_context (D.20649);
      D.20613 = start_info->obj;
      D.20613->ec_to_set = 0B;
      monoeg_g_free (start_info);
      tid.9 = tid;
      mono_profiler_thread_start (tid.9);
      if (start_func != 0B) goto <D.20650>; else goto <D.20651>;
      <D.20650>:
      start_func (start_arg);
      goto <D.20652>;
      <D.20651>:
      {
        void * args[1];

        try
          {
            D.20653 = start_delegate == 0B;
            D.20654 = (long int) D.20653;
            D.20655 = __builtin_expect (D.20654, 0);
            if (D.20655 != 0) goto <D.20656>; else goto <D.20657>;
            <D.20656>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 646, "start_delegate != NULL");
            <D.20657>:
            args[0] = start_arg;
            mono_runtime_delegate_invoke (start_delegate, &args, 0B);
          }
        finally
          {
            args = {CLOBBER};
          }
      }
      <D.20652>:
      mono_thread_cleanup_apartment_state ();
      thread_cleanup (internal);
      tls_current_object = 0B;
      current_object_key.8 = current_object_key;
      mono_native_tls_set_value (current_object_key.8, 0B);
      D.20625 = 0;
      return D.20625;
    }
  finally
    {
      tid = {CLOBBER};
    }
}


thread_adjust_static_data (struct MonoInternalThread * thread)
{
  _Bool D.20662;
  long int D.20663;
  long int D.20664;
  int D.20669;
  int D.20671;
  int D.20672;
  int D.20673;
  int D.20674;
  void * * * D.20675;
  _Bool D.20678;
  long int D.20679;
  long int D.20680;
  guint32 offset;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20660>; else goto <D.20661>;
    <D.20660>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20661>:
    D.20662 = ret != 0;
    D.20663 = (long int) D.20662;
    D.20664 = __builtin_expect (D.20663, 0);
    if (D.20664 != 0) goto <D.20665>; else goto <D.20666>;
    <D.20665>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3819, "ret == 0");
    <D.20666>:
  }
  D.20669 = thread_static_info.offset;
  if (D.20669 != 0) goto <D.20667>; else goto <D.20670>;
  <D.20670>:
  D.20671 = thread_static_info.idx;
  if (D.20671 > 0) goto <D.20667>; else goto <D.20668>;
  <D.20667>:
  D.20669 = thread_static_info.offset;
  D.20671 = thread_static_info.idx;
  D.20672 = D.20671 + 1;
  D.20673 = D.20672 << 24;
  D.20674 = D.20669 | D.20673;
  offset = (guint32) D.20674;
  D.20675 = &thread->static_data;
  mono_alloc_static_data (D.20675, offset, 1);
  <D.20668>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20676>; else goto <D.20677>;
    <D.20676>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20677>:
    D.20678 = ret != 0;
    D.20679 = (long int) D.20678;
    D.20680 = __builtin_expect (D.20679, 0);
    if (D.20680 != 0) goto <D.20681>; else goto <D.20682>;
    <D.20681>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3825, "ret == 0");
    <D.20682>:
  }
}


mono_alloc_static_data (void * * * static_data_ptr, guint32 offset, gboolean threadlocal)
{
  unsigned int D.20683;
  int D.20686;
  void * tls_desc.12;
  void * tls_desc.13;
  int D.20693;
  long unsigned int D.20694;
  void * iftmp.14;
  long unsigned int D.20699;
  long unsigned int D.20700;
  void * * D.20701;
  void * D.20702;
  int D.20707;
  int D.20710;
  long unsigned int D.20711;
  void * D.20712;
  long unsigned int D.20713;
  void * D.20714;
  unsigned int i.15;
  guint idx;
  int i;
  void * * static_data;

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

    D.20686 = mono_gc_user_markers_supported ();
    if (D.20686 != 0) goto <D.20687>; else goto <D.20688>;
    <D.20687>:
    tls_desc.12 = tls_desc;
    if (tls_desc.12 == 0B) goto <D.20690>; else goto <D.20691>;
    <D.20690>:
    tls_desc.13 = mono_gc_make_root_descr_user (mark_tls_slots);
    tls_desc = tls_desc.13;
    <D.20691>:
    <D.20688>:
    D.20693 = 1024;
    D.20694 = (long unsigned int) D.20693;
    if (threadlocal != 0) goto <D.20696>; else goto <D.20697>;
    <D.20696>:
    iftmp.14 = tls_desc;
    goto <D.20698>;
    <D.20697>:
    iftmp.14 = 0B;
    <D.20698>:
    static_data = mono_gc_alloc_fixed (D.20694, iftmp.14);
    *static_data_ptr = static_data;
    *static_data = static_data;
  }
  <D.20685>:
  i = 1;
  goto <D.20134>;
  <D.20133>:
  D.20699 = (long unsigned int) i;
  D.20700 = D.20699 * 8;
  D.20701 = static_data + D.20700;
  D.20702 = *D.20701;
  if (D.20702 != 0B) goto <D.20703>; else goto <D.20704>;
  <D.20703>:
  // predicted unlikely by continue predictor.
  goto <D.20132>;
  <D.20704>:
  D.20707 = mono_gc_user_markers_supported ();
  if (D.20707 != 0) goto <D.20708>; else goto <D.20705>;
  <D.20708>:
  if (threadlocal != 0) goto <D.20709>; else goto <D.20705>;
  <D.20709>:
  D.20699 = (long unsigned int) i;
  D.20700 = D.20699 * 8;
  D.20701 = static_data + D.20700;
  D.20710 = static_data_size[i];
  D.20711 = (long unsigned int) D.20710;
  D.20712 = monoeg_malloc0 (D.20711);
  *D.20701 = D.20712;
  goto <D.20706>;
  <D.20705>:
  D.20699 = (long unsigned int) i;
  D.20700 = D.20699 * 8;
  D.20701 = static_data + D.20700;
  D.20710 = static_data_size[i];
  D.20713 = (long unsigned int) D.20710;
  D.20714 = mono_gc_alloc_fixed (D.20713, 0B);
  *D.20701 = D.20714;
  <D.20706>:
  <D.20132>:
  i = i + 1;
  <D.20134>:
  i.15 = (unsigned int) i;
  if (i.15 <= idx) goto <D.20133>; else goto <D.20135>;
  <D.20135>:
}


mark_tls_slots (void * addr, void (*MonoGCMarkFunc) (void * *) mark_func)
{
  long unsigned int D.20716;
  long unsigned int D.20717;
  void * * D.20718;
  void * D.20719;
  int D.20722;
  long unsigned int D.20723;
  long unsigned int D.20724;
  unsigned int D.20725;
  unsigned int D.20726;
  uintptr_t * D.20727;
  long unsigned int D.20728;
  long unsigned int D.20729;
  uintptr_t * D.20730;
  long unsigned int D.20731;
  void * D.20734;
  int i;
  void * * static_data;

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

    D.20716 = (long unsigned int) i;
    D.20717 = D.20716 * 8;
    D.20718 = static_data + D.20717;
    D.20719 = *D.20718;
    if (D.20719 == 0B) goto <D.20720>; else goto <D.20721>;
    <D.20720>:
    // predicted unlikely by continue predictor.
    goto <D.20111>;
    <D.20721>:
    D.20722 = static_data_size[i];
    D.20723 = (long unsigned int) D.20722;
    D.20724 = D.20723 / 512;
    D.20725 = (unsigned int) D.20724;
    D.20726 = D.20725 + 1;
    numwords = (int) D.20726;
    D.20716 = (long unsigned int) i;
    D.20717 = D.20716 * 8;
    D.20718 = static_data + D.20717;
    ptr = *D.20718;
    j = 0;
    goto <D.20118>;
    <D.20117>:
    {
      uintptr_t bmap;
      void * * p;

      D.20727 = static_reference_bitmaps[i];
      D.20728 = (long unsigned int) j;
      D.20729 = D.20728 * 8;
      D.20730 = D.20727 + D.20729;
      bmap = *D.20730;
      p = ptr;
      goto <D.20115>;
      <D.20114>:
      D.20731 = bmap & 1;
      if (D.20731 != 0) goto <D.20732>; else goto <D.20733>;
      <D.20732>:
      D.20734 = *p;
      if (D.20734 != 0B) goto <D.20735>; else goto <D.20736>;
      <D.20735>:
      mark_func (p);
      <D.20736>:
      <D.20733>:
      p = p + 8;
      bmap = bmap >> 1;
      <D.20115>:
      if (bmap != 0) goto <D.20114>; else goto <D.20116>;
      <D.20116>:
    }
    j = j + 1;
    ptr = ptr + 512;
    <D.20118>:
    if (j < numwords) goto <D.20117>; else goto <D.20119>;
    <D.20119>:
  }
  <D.20111>:
  i = i + 1;
  <D.20121>:
  if (i <= 7) goto <D.20120>; else goto <D.20122>;
  <D.20122>:
}


init_root_domain_thread (struct MonoInternalThread * thread, struct MonoThread * candidate)
{
  struct MonoVTable * D.20740;
  struct MonoDomain * D.20741;
  struct MonoThread * D.20742;
  _Bool D.20743;
  long int D.20744;
  long int D.20745;
  struct MonoThread * * D.20748;
  struct MonoDomain * domain;

  domain = mono_get_root_domain ();
  if (candidate == 0B) goto <D.20737>; else goto <D.20739>;
  <D.20739>:
  D.20740 = candidate->obj.vtable;
  D.20741 = D.20740->domain;
  if (D.20741 != domain) goto <D.20737>; else goto <D.20738>;
  <D.20737>:
  candidate = new_thread_with_internal (domain, thread);
  <D.20738>:
  set_current_thread_for_domain (domain, thread, candidate);
  D.20742 = thread->root_domain_thread;
  D.20743 = D.20742 != 0B;
  D.20744 = (long int) D.20743;
  D.20745 = __builtin_expect (D.20744, 0);
  if (D.20745 != 0) goto <D.20746>; else goto <D.20747>;
  <D.20746>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 542, "!thread->root_domain_thread");
  <D.20747>:
  D.20748 = &thread->root_domain_thread;
  mono_gc_wbarrier_set_field (thread, D.20748, candidate);
}


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

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


set_current_thread_for_domain (struct MonoDomain * domain, struct MonoInternalThread * thread, struct MonoThread * current)
{
  struct MonoVTable * D.20752;
  struct MonoDomain * D.20753;
  _Bool D.20754;
  long int D.20755;
  long int D.20756;
  struct MonoThread * D.20759;
  _Bool D.20760;
  long int D.20761;
  long int D.20762;
  struct MonoThread * * current_thread_ptr;

  current_thread_ptr = get_current_thread_ptr_for_domain (domain, thread);
  D.20752 = current->obj.vtable;
  D.20753 = D.20752->domain;
  D.20754 = D.20753 != domain;
  D.20755 = (long int) D.20754;
  D.20756 = __builtin_expect (D.20755, 0);
  if (D.20756 != 0) goto <D.20757>; else goto <D.20758>;
  <D.20757>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 491, "current->obj.vtable->domain == domain");
  <D.20758>:
  D.20759 = *current_thread_ptr;
  D.20760 = D.20759 != 0B;
  D.20761 = (long int) D.20760;
  D.20762 = __builtin_expect (D.20761, 0);
  if (D.20762 != 0) goto <D.20763>; else goto <D.20764>;
  <D.20763>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 493, "!*current_thread_ptr");
  <D.20764>:
  *current_thread_ptr = current;
}


get_current_thread_ptr_for_domain (struct MonoDomain * domain, struct MonoInternalThread * thread)
{
  struct MonoClassField * current_thread_field.16;
  struct MonoClass * D.20768;
  struct MonoClassField * current_thread_field.17;
  _Bool D.20770;
  long int D.20771;
  long int D.20772;
  union mono_mutex_t * D.20775;
  _Bool D.20778;
  long int D.20779;
  long int D.20780;
  struct GHashTable * D.20783;
  void * D.20784;
  long int D.20785;
  _Bool D.20788;
  long int D.20789;
  long int D.20790;
  _Bool D.20793;
  long int D.20794;
  long int D.20795;
  struct MonoThread * * D.20798;
  static struct MonoClassField * current_thread_field = 0B;
  guint32 offset;

  current_thread_field.16 = current_thread_field;
  if (current_thread_field.16 == 0B) goto <D.20766>; else goto <D.20767>;
  <D.20766>:
  D.20768 = mono_defaults.thread_class;
  current_thread_field.17 = mono_class_get_field_from_name (D.20768, "current_thread");
  current_thread_field = current_thread_field.17;
  current_thread_field.16 = current_thread_field;
  D.20770 = current_thread_field.16 == 0B;
  D.20771 = (long int) D.20770;
  D.20772 = __builtin_expect (D.20771, 0);
  if (D.20772 != 0) goto <D.20773>; else goto <D.20774>;
  <D.20773>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 474, "current_thread_field");
  <D.20774>:
  <D.20767>:
  D.20768 = mono_defaults.thread_class;
  mono_class_vtable (domain, D.20768);
  {
    int ret;

    D.20775 = &domain->lock.mutex;
    ret = pthread_mutex_lock (D.20775);
    if (ret != 0) goto <D.20776>; else goto <D.20777>;
    <D.20776>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20777>:
    D.20778 = ret != 0;
    D.20779 = (long int) D.20778;
    D.20780 = __builtin_expect (D.20779, 0);
    if (D.20780 != 0) goto <D.20781>; else goto <D.20782>;
    <D.20781>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 478, "ret == 0");
    <D.20782>:
  }
  D.20783 = domain->special_static_fields;
  current_thread_field.16 = current_thread_field;
  D.20784 = monoeg_g_hash_table_lookup (D.20783, current_thread_field.16);
  D.20785 = (long int) D.20784;
  offset = (guint32) D.20785;
  {
    int ret;

    D.20775 = &domain->lock.mutex;
    ret = pthread_mutex_unlock (D.20775);
    if (ret != 0) goto <D.20786>; else goto <D.20787>;
    <D.20786>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20787>:
    D.20788 = ret != 0;
    D.20789 = (long int) D.20788;
    D.20790 = __builtin_expect (D.20789, 0);
    if (D.20790 != 0) goto <D.20791>; else goto <D.20792>;
    <D.20791>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 480, "ret == 0");
    <D.20792>:
  }
  D.20793 = offset == 0;
  D.20794 = (long int) D.20793;
  D.20795 = __builtin_expect (D.20794, 0);
  if (D.20795 != 0) goto <D.20796>; else goto <D.20797>;
  <D.20796>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 481, "offset");
  <D.20797>:
  D.20798 = get_thread_static_data (thread, offset);
  return D.20798;
}


get_thread_static_data (struct MonoInternalThread * thread, guint32 offset)
{
  signed int offset.18;
  _Bool D.20801;
  long int D.20802;
  long int D.20803;
  unsigned int D.20806;
  unsigned int D.20807;
  void * D.20808;
  void * * D.20809;
  long unsigned int D.20810;
  long unsigned int D.20811;
  void * * D.20812;
  void * D.20813;
  sizetype D.20814;
  sizetype D.20815;
  int idx;

  offset.18 = (signed int) offset;
  D.20801 = offset.18 < 0;
  D.20802 = (long int) D.20801;
  D.20803 = __builtin_expect (D.20802, 0);
  if (D.20803 != 0) goto <D.20804>; else goto <D.20805>;
  <D.20804>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 459, "(offset & 0x80000000) == 0");
  <D.20805>:
  offset = offset & 2147483647;
  D.20806 = offset >> 24;
  D.20807 = D.20806 + 4294967295;
  idx = (int) D.20807;
  D.20809 = thread->static_data;
  D.20810 = (long unsigned int) idx;
  D.20811 = D.20810 * 8;
  D.20812 = D.20809 + D.20811;
  D.20813 = *D.20812;
  D.20814 = (sizetype) offset;
  D.20815 = D.20814 & 16777215;
  D.20808 = D.20813 + D.20815;
  return D.20808;
}


thread_cleanup (struct MonoInternalThread * thread)
{
  _Bool D.20817;
  long int D.20818;
  long int D.20819;
  int D.20822;
  unsigned int D.20825;
  struct MonoArray * D.20826;
  long unsigned int D.20829;
  struct CRITICAL_SECTION * D.20830;
  int shutting_down.19;
  _Bool D.20835;
  long int D.20836;
  long int D.20837;
  unsigned int D.20840;
  unsigned int D.20841;
  unsigned int D.20842;
  gint32 * D.20845;
  int D.20846;
  int D.20849;
  struct MonoInternalThread * D.20852;
  void (*<T22db>) (struct MonoInternalThread *) mono_thread_cleanup_fn.20;
  long unsigned int D.20858;
  struct MonoInternalThread * D.20859;
  struct MonoInternalThread * D.20862;
  void * * D.20865;
  void * D.20866;
  int D.20869;
  void * * D.20872;

  D.20817 = thread == 0B;
  D.20818 = (long int) D.20817;
  D.20819 = __builtin_expect (D.20818, 0);
  if (D.20819 != 0) goto <D.20820>; else goto <D.20821>;
  <D.20820>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 368, "thread != NULL");
  <D.20821>:
  D.20822 = thread->abort_state_handle;
  if (D.20822 != 0) goto <D.20823>; else goto <D.20824>;
  <D.20823>:
  D.20822 = thread->abort_state_handle;
  D.20825 = (unsigned int) D.20822;
  mono_gchandle_free (D.20825);
  thread->abort_state_handle = 0;
  <D.20824>:
  thread->abort_exc = 0B;
  thread->current_appcontext = 0B;
  D.20826 = thread->cached_culture_info;
  if (D.20826 != 0B) goto <D.20827>; else goto <D.20828>;
  <D.20827>:
  {
    int i;

    i = 0;
    goto <D.19143>;
    <D.19142>:
    {
      struct MonoObject * * __p;

      D.20826 = thread->cached_culture_info;
      D.20829 = (long unsigned int) i;
      __p = mono_array_addr_with_size (D.20826, 8, D.20829);
      *__p = 0B;
    }
    i = i + 1;
    <D.19143>:
    if (i <= 7) goto <D.19142>; else goto <D.19144>;
    <D.19144>:
  }
  <D.20828>:
  D.20830 = thread->synch_cs;
  if (D.20830 != 0B) goto <D.20831>; else goto <D.20832>;
  <D.20831>:
  lock_thread (thread);
  goto <D.20833>;
  <D.20832>:
  shutting_down.19 = shutting_down;
  D.20835 = shutting_down.19 == 0;
  D.20836 = (long int) D.20835;
  D.20837 = __builtin_expect (D.20836, 0);
  if (D.20837 != 0) goto <D.20838>; else goto <D.20839>;
  <D.20838>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 391, "shutting_down");
  <D.20839>:
  <D.20833>:
  D.20840 = thread->state;
  D.20841 = D.20840 | 16;
  thread->state = D.20841;
  D.20840 = thread->state;
  D.20842 = D.20840 & 4294967291;
  thread->state = D.20842;
  D.20830 = thread->synch_cs;
  if (D.20830 != 0B) goto <D.20843>; else goto <D.20844>;
  <D.20843>:
  unlock_thread (thread);
  <D.20844>:
  D.20845 = &thread->interruption_requested;
  D.20846 = InterlockedExchange (D.20845, 0);
  if (D.20846 != 0) goto <D.20847>; else goto <D.20848>;
  <D.20847>:
  InterlockedDecrement (&thread_interruption_requested);
  <D.20848>:
  D.20849 = handle_remove (thread);
  if (D.20849 == 0) goto <D.20850>; else goto <D.20851>;
  <D.20850>:
  D.20852 = mono_thread_internal_current ();
  if (D.20852 == thread) goto <D.20853>; else goto <D.20854>;
  <D.20853>:
  mono_domain_unset ();
  mono_memory_barrier ();
  <D.20854>:
  mono_thread_cleanup_fn.20 = mono_thread_cleanup_fn;
  if (mono_thread_cleanup_fn.20 != 0B) goto <D.20856>; else goto <D.20857>;
  <D.20856>:
  mono_thread_cleanup_fn.20 = mono_thread_cleanup_fn;
  mono_thread_cleanup_fn.20 (thread);
  <D.20857>:
  return;
  <D.20851>:
  mono_release_type_locks (thread);
  D.20858 = thread->tid;
  mono_profiler_thread_end (D.20858);
  D.20859 = mono_thread_internal_current ();
  if (D.20859 == thread) goto <D.20860>; else goto <D.20861>;
  <D.20860>:
  mono_domain_unset ();
  mono_memory_barrier ();
  <D.20861>:
  D.20862 = mono_thread_internal_current ();
  if (D.20862 == thread) goto <D.20863>; else goto <D.20864>;
  <D.20863>:
  mono_thread_pop_appdomain_ref ();
  <D.20864>:
  thread->cached_culture_info = 0B;
  D.20865 = thread->static_data;
  mono_free_static_data (D.20865, 1);
  thread->static_data = 0B;
  D.20866 = thread->appdomain_refs;
  ref_stack_destroy (D.20866);
  thread->appdomain_refs = 0B;
  mono_thread_cleanup_fn.20 = mono_thread_cleanup_fn;
  if (mono_thread_cleanup_fn.20 != 0B) goto <D.20867>; else goto <D.20868>;
  <D.20867>:
  mono_thread_cleanup_fn.20 = mono_thread_cleanup_fn;
  mono_thread_cleanup_fn.20 (thread);
  <D.20868>:
  D.20869 = mono_gc_is_moving ();
  if (D.20869 != 0) goto <D.20870>; else goto <D.20871>;
  <D.20870>:
  D.20872 = &thread->thread_pinning_ref;
  mono_gc_deregister_root (D.20872);
  thread->thread_pinning_ref = 0B;
  <D.20871>:
}


lock_thread (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.20874;
  _Bool D.20877;
  long int D.20878;
  long int D.20879;
  union mono_mutex_t * D.20882;
  _Bool D.20885;
  long int D.20886;
  long int D.20887;

  D.20874 = thread->synch_cs;
  if (D.20874 == 0B) goto <D.20875>; else goto <D.20876>;
  <D.20875>:
  ensure_synch_cs_set (thread);
  <D.20876>:
  D.20874 = thread->synch_cs;
  D.20877 = D.20874 == 0B;
  D.20878 = (long int) D.20877;
  D.20879 = __builtin_expect (D.20878, 0);
  if (D.20879 != 0) goto <D.20880>; else goto <D.20881>;
  <D.20880>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 351, "thread->synch_cs");
  <D.20881>:
  {
    int ret;

    D.20874 = thread->synch_cs;
    D.20882 = &D.20874->mutex;
    ret = pthread_mutex_lock (D.20882);
    if (ret != 0) goto <D.20883>; else goto <D.20884>;
    <D.20883>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20884>:
    D.20885 = ret != 0;
    D.20886 = (long int) D.20885;
    D.20887 = __builtin_expect (D.20886, 0);
    if (D.20887 != 0) goto <D.20888>; else goto <D.20889>;
    <D.20888>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 352, "ret == 0");
    <D.20889>:
  }
}


ensure_synch_cs_set (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.20890;
  struct CRITICAL_SECTION * * D.20893;
  void * D.20894;
  struct CRITICAL_SECTION * synch_cs;

  D.20890 = thread->synch_cs;
  if (D.20890 != 0B) goto <D.20891>; else goto <D.20892>;
  <D.20891>:
  return;
  <D.20892>:
  synch_cs = monoeg_malloc0 (48);
  InitializeCriticalSection (synch_cs);
  D.20893 = &thread->synch_cs;
  D.20894 = InterlockedCompareExchangePointer (D.20893, synch_cs, 0B);
  if (D.20894 != 0B) goto <D.20895>; else goto <D.20896>;
  <D.20895>:
  DeleteCriticalSection (synch_cs);
  monoeg_g_free (synch_cs);
  <D.20896>:
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.20898;
  long unsigned int comp.21;
  long unsigned int exch.22;
  long unsigned int D.20901;

  comp.21 = (long unsigned int) comp;
  exch.22 = (long unsigned int) exch;
  D.20901 = __sync_val_compare_and_swap_8 (dest, comp.21, exch.22);
  D.20898 = (void *) D.20901;
  return D.20898;
}


unlock_thread (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.20903;
  union mono_mutex_t * D.20904;
  _Bool D.20907;
  long int D.20908;
  long int D.20909;

  {
    int ret;

    D.20903 = thread->synch_cs;
    D.20904 = &D.20903->mutex;
    ret = pthread_mutex_unlock (D.20904);
    if (ret != 0) goto <D.20905>; else goto <D.20906>;
    <D.20905>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20906>:
    D.20907 = ret != 0;
    D.20908 = (long int) D.20907;
    D.20909 = __builtin_expect (D.20908, 0);
    if (D.20909 != 0) goto <D.20910>; else goto <D.20911>;
    <D.20910>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 358, "ret == 0");
    <D.20911>:
  }
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int old_val.23;
  unsigned int new_val.24;
  unsigned int D.20914;
  int D.20915;
  gint32 D.20916;
  gint32 old_val;

  <D.18937>:
  old_val = *val;
  old_val.23 = (unsigned int) old_val;
  new_val.24 = (unsigned int) new_val;
  D.20914 = __sync_val_compare_and_swap_4 (val, old_val.23, new_val.24);
  D.20915 = (int) D.20914;
  if (D.20915 != old_val) goto <D.18937>; else goto <D.18938>;
  <D.18938>:
  D.20916 = old_val;
  return D.20916;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.20918;
  unsigned int D.20919;

  D.20919 = __sync_sub_and_fetch_4 (val, 1);
  D.20918 = (gint32) D.20919;
  return D.20918;
}


handle_remove (struct MonoInternalThread * thread)
{
  _Bool D.20923;
  long int D.20924;
  long int D.20925;
  struct MonoGHashTable * threads.25;
  const void * tid.26;
  void * D.20932;
  _Bool D.20939;
  long int D.20940;
  long int D.20941;
  gboolean D.20944;
  gboolean ret;
  gsize tid;

  tid = thread->tid;
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20921>; else goto <D.20922>;
    <D.20921>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20922>:
    D.20923 = ret != 0;
    D.20924 = (long int) D.20923;
    D.20925 = __builtin_expect (D.20924, 0);
    if (D.20925 != 0) goto <D.20926>; else goto <D.20927>;
    <D.20926>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 289, "ret == 0");
    <D.20927>:
  }
  threads.25 = threads;
  if (threads.25 != 0B) goto <D.20929>; else goto <D.20930>;
  <D.20929>:
  threads.25 = threads;
  tid.26 = (const void *) tid;
  D.20932 = mono_g_hash_table_lookup (threads.25, tid.26);
  if (D.20932 == thread) goto <D.20933>; else goto <D.20934>;
  <D.20933>:
  threads.25 = threads;
  tid.26 = (const void *) tid;
  mono_g_hash_table_remove (threads.25, tid.26);
  ret = 1;
  goto <D.20935>;
  <D.20934>:
  ret = 0;
  <D.20935>:
  goto <D.20936>;
  <D.20930>:
  ret = 0;
  <D.20936>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20937>; else goto <D.20938>;
    <D.20937>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20938>:
    D.20939 = ret != 0;
    D.20940 = (long int) D.20939;
    D.20941 = __builtin_expect (D.20940, 0);
    if (D.20941 != 0) goto <D.20942>; else goto <D.20943>;
    <D.20942>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 308, "ret == 0");
    <D.20943>:
  }
  D.20944 = ret;
  return D.20944;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_free_static_data (void * * static_data, gboolean threadlocal)
{
  long unsigned int D.20946;
  long unsigned int D.20947;
  void * * D.20948;
  int D.20953;
  int i;

  i = 1;
  goto <D.20144>;
  <D.20143>:
  {
    void * p;

    D.20946 = (long unsigned int) i;
    D.20947 = D.20946 * 8;
    D.20948 = static_data + D.20947;
    p = *D.20948;
    if (p == 0B) goto <D.20949>; else goto <D.20950>;
    <D.20949>:
    // predicted unlikely by continue predictor.
    goto <D.20142>;
    <D.20950>:
    D.20946 = (long unsigned int) i;
    D.20947 = D.20946 * 8;
    D.20948 = static_data + D.20947;
    *D.20948 = 0B;
    mono_memory_write_barrier ();
    D.20953 = mono_gc_user_markers_supported ();
    if (D.20953 != 0) goto <D.20954>; else goto <D.20951>;
    <D.20954>:
    if (threadlocal != 0) goto <D.20955>; else goto <D.20951>;
    <D.20955>:
    monoeg_g_free (p);
    goto <D.20952>;
    <D.20951>:
    mono_gc_free_fixed (p);
    <D.20952>:
  }
  <D.20142>:
  i = i + 1;
  <D.20144>:
  if (i <= 7) goto <D.20143>; else goto <D.20145>;
  <D.20145>:
  mono_gc_free_fixed (static_data);
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


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

  rs = ptr;
  if (rs != 0B) goto <D.20956>; else goto <D.20957>;
  <D.20956>:
  D.20958 = rs->refs;
  monoeg_g_free (D.20958);
  monoeg_g_free (rs);
  <D.20957>:
}


mono_native_tls_set_value (pthread_key_t key, void * value)
{
  int D.20959;
  int D.20960;
  _Bool D.20961;

  D.20960 = pthread_setspecific (key, value);
  D.20961 = D.20960 == 0;
  D.20959 = (int) D.20961;
  return D.20959;
}


handle_store (struct MonoThread * thread, gboolean force_attach)
{
  _Bool D.20965;
  long int D.20966;
  long int D.20967;
  struct MonoGHashTable * threads_starting_up.27;
  int shutting_down.28;
  _Bool D.20980;
  long int D.20981;
  long int D.20982;
  gboolean D.20985;
  struct MonoGHashTable * threads.29;
  int D.20989;
  struct MonoGHashTable * D.20992;
  struct _MonoInternalThread * D.20993;
  _Bool D.20994;
  long int D.20995;
  long int D.20996;
  long unsigned int D.20999;
  void * D.21000;
  _Bool D.21003;
  long int D.21004;
  long int D.21005;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20963>; else goto <D.20964>;
    <D.20963>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20964>:
    D.20965 = ret != 0;
    D.20966 = (long int) D.20965;
    D.20967 = __builtin_expect (D.20966, 0);
    if (D.20967 != 0) goto <D.20968>; else goto <D.20969>;
    <D.20968>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 253, "ret == 0");
    <D.20969>:
  }
  threads_starting_up.27 = threads_starting_up;
  if (threads_starting_up.27 != 0B) goto <D.20971>; else goto <D.20972>;
  <D.20971>:
  threads_starting_up.27 = threads_starting_up;
  mono_g_hash_table_remove (threads_starting_up.27, thread);
  <D.20972>:
  shutting_down.28 = shutting_down;
  if (shutting_down.28 != 0) goto <D.20974>; else goto <D.20975>;
  <D.20974>:
  if (force_attach == 0) goto <D.20976>; else goto <D.20977>;
  <D.20976>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20978>; else goto <D.20979>;
    <D.20978>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20979>:
    D.20980 = ret != 0;
    D.20981 = (long int) D.20980;
    D.20982 = __builtin_expect (D.20981, 0);
    if (D.20982 != 0) goto <D.20983>; else goto <D.20984>;
    <D.20983>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 261, "ret == 0");
    <D.20984>:
  }
  D.20985 = 0;
  return D.20985;
  <D.20977>:
  <D.20975>:
  threads.29 = threads;
  if (threads.29 == 0B) goto <D.20987>; else goto <D.20988>;
  <D.20987>:
  D.20989 = mono_gc_is_moving ();
  if (D.20989 == 0) goto <D.20990>; else goto <D.20991>;
  <D.20990>:
  mono_gc_register_root (&threads, 8, 0B);
  <D.20991>:
  D.20992 = mono_g_hash_table_new_type (0B, 0B, 2);
  threads = D.20992;
  <D.20988>:
  D.20993 = thread->internal_thread;
  D.20994 = D.20993 == 0B;
  D.20995 = (long int) D.20994;
  D.20996 = __builtin_expect (D.20995, 0);
  if (D.20996 != 0) goto <D.20997>; else goto <D.20998>;
  <D.20997>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 273, "thread->internal_thread");
  <D.20998>:
  threads.29 = threads;
  D.20993 = thread->internal_thread;
  D.20999 = D.20993->tid;
  D.21000 = (void *) D.20999;
  D.20993 = thread->internal_thread;
  mono_g_hash_table_insert (threads.29, D.21000, D.20993);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21001>; else goto <D.21002>;
    <D.21001>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21002>:
    D.21003 = ret != 0;
    D.21004 = (long int) D.21003;
    D.21005 = __builtin_expect (D.21004, 0);
    if (D.21005 != 0) goto <D.21006>; else goto <D.21007>;
    <D.21006>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 277, "ret == 0");
    <D.21007>:
  }
  D.20985 = 1;
  return D.20985;
}


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


__attribute__((visibility ("hidden")))
mono_thread_get_stack_bounds (guint8 * * staddr, size_t * stsize)
{
  long unsigned int D.21009;
  guint8 * D.21010;
  int iftmp.30;
  long unsigned int D.21018;
  guint8 * D.21019;
  _Bool D.21020;
  long int D.21021;
  long int D.21022;
  long int D.21025;
  int D.21026;
  int D.21027;
  int D.21028;
  long int D.21029;
  long int D.21030;
  guint8 * D.21031;
  union pthread_attr_t attr;
  guint8 * current;

  try
    {
      current = &attr;
      *staddr = 0B;
      *stsize = 18446744073709551615;
      pthread_attr_init (&attr);
      D.21009 = pthread_self ();
      pthread_getattr_np (D.21009, &attr);
      pthread_attr_getstack (&attr, staddr, stsize);
      pthread_attr_destroy (&attr);
      D.21010 = *staddr;
      if (D.21010 != 0B) goto <D.21011>; else goto <D.21012>;
      <D.21011>:
      D.21010 = *staddr;
      if (D.21010 >= current) goto <D.21014>; else goto <D.21017>;
      <D.21017>:
      D.21010 = *staddr;
      D.21018 = *stsize;
      D.21019 = D.21010 + D.21018;
      if (D.21019 <= current) goto <D.21014>; else goto <D.21015>;
      <D.21014>:
      iftmp.30 = 1;
      goto <D.21016>;
      <D.21015>:
      iftmp.30 = 0;
      <D.21016>:
      D.21020 = iftmp.30 != 0;
      D.21021 = (long int) D.21020;
      D.21022 = __builtin_expect (D.21021, 0);
      if (D.21022 != 0) goto <D.21023>; else goto <D.21024>;
      <D.21023>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 944, "(current > *staddr) && (current < *staddr + *stsize)");
      <D.21024>:
      <D.21012>:
      D.21010 = *staddr;
      D.21025 = (long int) D.21010;
      D.21026 = mono_pagesize ();
      D.21027 = D.21026 + -1;
      D.21028 = ~D.21027;
      D.21029 = (long int) D.21028;
      D.21030 = D.21025 & D.21029;
      D.21031 = (guint8 *) D.21030;
      *staddr = D.21031;
      return;
    }
  finally
    {
      attr = {CLOBBER};
    }
}


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

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


__attribute__((visibility ("hidden")))
mono_thread_attach_full (struct MonoDomain * domain, gboolean force_attach)
{
  struct MonoDomain * D.21038;
  struct MonoDomain * domain.31;
  struct MonoThread * D.21042;
  int D.21043;
  long unsigned int D.21046;
  void * thread_handle.32;
  void * thread_handle.33;
  _Bool D.21049;
  long int D.21050;
  long int D.21051;
  long unsigned int tid.34;
  void * D.21055;
  void * D.21056;
  long unsigned int tid.35;
  _Bool D.21058;
  long int D.21059;
  long int D.21060;
  int D.21063;
  unsigned int current_object_key.36;
  struct MonoDomain * D.21067;
  void (*<T14f9>) (intptr_t, void *) mono_thread_attach_cb.37;
  guint8 * staddr.38;
  long int tid.39;
  long unsigned int stsize.40;
  guint8 * D.21079;
  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.21036>; else goto <D.21037>;
      <D.21036>:
      D.21038 = mono_domain_get ();
      domain.31 = domain;
      if (D.21038 != domain.31) goto <D.21040>; else goto <D.21041>;
      <D.21040>:
      domain.31 = domain;
      mono_domain_set (domain.31, 1);
      <D.21041>:
      D.21042 = mono_thread_current ();
      return D.21042;
      <D.21037>:
      D.21043 = mono_gc_register_thread (&domain);
      if (D.21043 == 0) goto <D.21044>; else goto <D.21045>;
      <D.21044>:
      D.21046 = GetCurrentThreadId ();
      monoeg_g_log (0B, 4, "Thread %lu 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.21046);
      <D.19268>:
      goto <D.19268>;
      <D.21045>:
      thread = create_internal_thread ();
      thread_handle.32 = GetCurrentThread ();
      thread_handle = thread_handle.32;
      thread_handle.33 = thread_handle;
      D.21049 = thread_handle.33 == 0B;
      D.21050 = (long int) D.21049;
      D.21051 = __builtin_expect (D.21050, 0);
      if (D.21051 != 0) goto <D.21052>; else goto <D.21053>;
      <D.21052>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1028, "thread_handle");
      <D.21053>:
      tid.34 = GetCurrentThreadId ();
      tid = tid.34;
      D.21055 = GetCurrentProcess ();
      thread_handle.33 = thread_handle;
      D.21056 = GetCurrentProcess ();
      DuplicateHandle (D.21055, thread_handle.33, D.21056, &thread_handle, 2032639, 1, 0);
      thread_handle.33 = thread_handle;
      thread->handle = thread_handle.33;
      tid.35 = tid;
      thread->tid = tid.35;
      thread->stack_ptr = &tid;
      info = mono_thread_info_current ();
      D.21058 = info == 0B;
      D.21059 = (long int) D.21058;
      D.21060 = __builtin_expect (D.21059, 0);
      if (D.21060 != 0) goto <D.21061>; else goto <D.21062>;
      <D.21061>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1049, "info");
      <D.21062>:
      thread->thread_info = info;
      domain.31 = domain;
      current_thread = new_thread_with_internal (domain.31, thread);
      D.21063 = handle_store (current_thread, force_attach);
      if (D.21063 == 0) goto <D.21064>; else goto <D.21065>;
      <D.21064>:
      <D.19269>:
      Sleep (10000);
      goto <D.19269>;
      <D.21065>:
      tls_current_object = thread;
      current_object_key.36 = current_object_key;
      mono_native_tls_set_value (current_object_key.36, thread);
      domain.31 = domain;
      mono_domain_set (domain.31, 1);
      mono_monitor_init_tls ();
      thread_adjust_static_data (thread);
      init_root_domain_thread (thread, current_thread);
      D.21067 = mono_get_root_domain ();
      domain.31 = domain;
      if (D.21067 != domain.31) goto <D.21068>; else goto <D.21069>;
      <D.21068>:
      domain.31 = domain;
      set_current_thread_for_domain (domain.31, thread, current_thread);
      <D.21069>:
      mono_thread_attach_cb.37 = mono_thread_attach_cb;
      if (mono_thread_attach_cb.37 != 0B) goto <D.21071>; else goto <D.21072>;
      <D.21071>:
      {
        guint8 * staddr;
        size_t stsize;

        try
          {
            mono_thread_get_stack_bounds (&staddr, &stsize);
            staddr.38 = staddr;
            if (staddr.38 == 0B) goto <D.21074>; else goto <D.21075>;
            <D.21074>:
            mono_thread_attach_cb.37 = mono_thread_attach_cb;
            tid.35 = tid;
            tid.39 = (long int) tid.35;
            mono_thread_attach_cb.37 (tid.39, &tid);
            goto <D.21077>;
            <D.21075>:
            mono_thread_attach_cb.37 = mono_thread_attach_cb;
            tid.35 = tid;
            tid.39 = (long int) tid.35;
            staddr.38 = staddr;
            stsize.40 = stsize;
            D.21079 = staddr.38 + stsize.40;
            mono_thread_attach_cb.37 (tid.39, D.21079);
            <D.21077>:
          }
        finally
          {
            staddr = {CLOBBER};
            stsize = {CLOBBER};
          }
      }
      <D.21072>:
      tid.35 = tid;
      mono_profiler_thread_start (tid.35);
      D.21042 = current_thread;
      return D.21042;
    }
  finally
    {
      thread_handle = {CLOBBER};
      tid = {CLOBBER};
    }
}


mono_thread_detach (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.21084;
  unsigned int current_object_key.41;

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


mono_thread_exit ()
{
  unsigned int current_object_key.42;
  struct MonoThread * D.21088;
  struct MonoThread * D.21091;
  struct _MonoInternalThread * D.21092;
  int D.21095;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  thread_cleanup (thread);
  tls_current_object = 0B;
  current_object_key.42 = current_object_key;
  mono_native_tls_set_value (current_object_key.42, 0B);
  mono_domain_unset ();
  D.21088 = mono_thread_get_main ();
  if (D.21088 != 0B) goto <D.21089>; else goto <D.21090>;
  <D.21089>:
  D.21091 = mono_thread_get_main ();
  D.21092 = D.21091->internal_thread;
  if (D.21092 == thread) goto <D.21093>; else goto <D.21094>;
  <D.21093>:
  D.21095 = mono_environment_exitcode_get ();
  exit (D.21095);
  <D.21094>:
  <D.21090>:
  ExitThread (4294967295);
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_ConstructInternalThread (struct MonoThread * this)
{
  struct _MonoInternalThread * * D.21096;
  struct MonoInternalThread * internal;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Thread_internal (struct MonoThread * this, struct MonoObject * start)
{
  struct _MonoInternalThread * D.21097;
  unsigned int D.21100;
  unsigned int D.21101;
  struct MonoException * D.21104;
  void * D.21105;
  unsigned int D.21106;
  struct MonoObject * D.21109;
  struct MonoVTable * D.21110;
  struct MonoDomain * D.21111;
  struct MonoDomain * D.21112;
  _Bool D.21113;
  long int D.21114;
  long int D.21115;
  unsigned int D.21120;
  struct StartInfo * start_info;
  struct MonoInternalThread * internal;
  gboolean res;

  D.21097 = this->internal_thread;
  if (D.21097 == 0B) goto <D.21098>; else goto <D.21099>;
  <D.21098>:
  ves_icall_System_Threading_Thread_ConstructInternalThread (this);
  <D.21099>:
  internal = this->internal_thread;
  lock_thread (internal);
  D.21100 = internal->state;
  D.21101 = D.21100 & 8;
  if (D.21101 == 0) goto <D.21102>; else goto <D.21103>;
  <D.21102>:
  unlock_thread (internal);
  D.21104 = mono_get_exception_thread_state ("Thread has already been started.");
  mono_raise_exception (D.21104);
  D.21105 = 0B;
  return D.21105;
  <D.21103>:
  D.21100 = internal->state;
  D.21106 = D.21100 & 256;
  if (D.21106 != 0) goto <D.21107>; else goto <D.21108>;
  <D.21107>:
  unlock_thread (internal);
  D.21105 = this;
  return D.21105;
  <D.21108>:
  start_info = monoeg_malloc0 (32);
  start_info->func = 0B;
  D.21109 = this->start_obj;
  start_info->start_arg = D.21109;
  start_info->delegate = start;
  start_info->obj = this;
  D.21110 = this->obj.vtable;
  D.21111 = D.21110->domain;
  D.21112 = mono_domain_get ();
  D.21113 = D.21111 != D.21112;
  D.21114 = (long int) D.21113;
  D.21115 = __builtin_expect (D.21114, 0);
  if (D.21115 != 0) goto <D.21116>; else goto <D.21117>;
  <D.21116>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1169, "this->obj.vtable->domain == mono_domain_get ()");
  <D.21117>:
  res = create_thread (this, internal, start_info, 0, 0, 0, 0);
  if (res == 0) goto <D.21118>; else goto <D.21119>;
  <D.21118>:
  unlock_thread (internal);
  D.21105 = 0B;
  return D.21105;
  <D.21119>:
  D.21100 = internal->state;
  D.21120 = D.21100 & 4294967287;
  internal->state = D.21120;
  unlock_thread (internal);
  D.21105 = internal->handle;
  return D.21105;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_InternalThread_Thread_free_internal (struct MonoInternalThread * this, void * thread)
{
  struct CRITICAL_SECTION * D.21124;
  gunichar2 * D.21127;

  if (thread != 0B) goto <D.21122>; else goto <D.21123>;
  <D.21122>:
  CloseHandle (thread);
  <D.21123>:
  D.21124 = this->synch_cs;
  if (D.21124 != 0B) goto <D.21125>; else goto <D.21126>;
  <D.21125>:
  {
    struct CRITICAL_SECTION * synch_cs;

    synch_cs = this->synch_cs;
    this->synch_cs = 0B;
    DeleteCriticalSection (synch_cs);
    monoeg_g_free (synch_cs);
  }
  <D.21126>:
  D.21127 = this->name;
  if (D.21127 != 0B) goto <D.21128>; else goto <D.21129>;
  <D.21128>:
  {
    void * name;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Sleep_internal (gint32 ms)
{
  unsigned int ms.43;
  guint32 res;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  <D.19302>:
  mono_thread_set_state (thread, 32);
  ms.43 = (unsigned int) ms;
  res = SleepEx (ms.43, 1);
  mono_thread_clr_state (thread, 32);
  if (res == 192) goto <D.21131>; else goto <D.19301>;
  <D.21131>:
  {
    struct MonoException * exc;

    exc = mono_thread_execute_interruption (thread);
    if (exc != 0B) goto <D.21132>; else goto <D.21133>;
    <D.21132>:
    mono_raise_exception (exc);
    goto <D.21134>;
    <D.21133>:
    if (ms != -1) goto <D.19301>; else goto <D.21135>;
    <D.21135>:
    <D.21134>:
  }
  goto <D.19302>;
  <D.19301>:
}


mono_thread_execute_interruption (struct MonoInternalThread * thread)
{
  gint32 * D.21136;
  int D.21137;
  void * D.21140;
  unsigned int D.21141;
  unsigned int D.21142;
  struct MonoException * D.21145;
  struct MonoException * * D.21148;
  struct MonoException * D.21149;
  struct MonoException * D.21150;
  unsigned int D.21151;
  unsigned int D.21154;
  struct MonoException * D.21157;
  unsigned char D.21160;

  lock_thread (thread);
  D.21136 = &thread->interruption_requested;
  D.21137 = InterlockedCompareExchange (D.21136, 0, 1);
  if (D.21137 != 0) goto <D.21138>; else goto <D.21139>;
  <D.21138>:
  D.21140 = GetCurrentThread ();
  WaitForSingleObjectEx (D.21140, 0, 1);
  InterlockedDecrement (&thread_interruption_requested);
  wapi_clear_interruption ();
  <D.21139>:
  D.21141 = thread->state;
  D.21142 = D.21141 & 128;
  if (D.21142 != 0) goto <D.21143>; else goto <D.21144>;
  <D.21143>:
  unlock_thread (thread);
  D.21145 = thread->abort_exc;
  if (D.21145 == 0B) goto <D.21146>; else goto <D.21147>;
  <D.21146>:
  D.21148 = &thread->abort_exc;
  D.21149 = mono_get_exception_thread_abort ();
  mono_gc_wbarrier_set_field (thread, D.21148, D.21149);
  <D.21147>:
  D.21150 = thread->abort_exc;
  return D.21150;
  <D.21144>:
  D.21141 = thread->state;
  D.21151 = D.21141 & 2;
  if (D.21151 != 0) goto <D.21152>; else goto <D.21153>;
  <D.21152>:
  self_suspend_internal (thread);
  D.21150 = 0B;
  return D.21150;
  <D.21153>:
  D.21141 = thread->state;
  D.21154 = D.21141 & 1;
  if (D.21154 != 0) goto <D.21155>; else goto <D.21156>;
  <D.21155>:
  unlock_thread (thread);
  mono_thread_exit ();
  D.21150 = 0B;
  return D.21150;
  <D.21156>:
  D.21157 = thread->pending_exception;
  if (D.21157 != 0B) goto <D.21158>; else goto <D.21159>;
  <D.21158>:
  {
    struct MonoException * exc;

    exc = thread->pending_exception;
    thread->pending_exception = 0B;
    unlock_thread (thread);
    D.21150 = exc;
    return D.21150;
  }
  <D.21159>:
  D.21160 = thread->thread_interrupt_requested;
  if (D.21160 != 0) goto <D.21161>; else goto <D.21162>;
  <D.21161>:
  thread->thread_interrupt_requested = 0;
  unlock_thread (thread);
  D.21150 = mono_get_exception_thread_interrupted ();
  return D.21150;
  <D.21162>:
  unlock_thread (thread);
  D.21150 = 0B;
  return D.21150;
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.21164;
  unsigned int comp.44;
  unsigned int exch.45;
  unsigned int D.21167;

  comp.44 = (unsigned int) comp;
  exch.45 = (unsigned int) exch;
  D.21167 = __sync_val_compare_and_swap_4 (dest, comp.44, exch.45);
  D.21164 = (gint32) D.21167;
  return D.21164;
}


self_suspend_internal (struct MonoInternalThread * thread)
{
  int D.21169;
  unsigned int D.21172;
  unsigned int D.21173;
  unsigned int D.21174;
  void * D.21175;
  void * D.21176;
  void * D.21179;
  int shutting_down.46;
  unsigned int D.21185;
  void * D.21186;

  D.21169 = mono_thread_info_new_interrupt_enabled ();
  if (D.21169 == 0) goto <D.21170>; else goto <D.21171>;
  <D.21170>:
  D.21172 = thread->state;
  D.21173 = D.21172 & 4294967293;
  thread->state = D.21173;
  D.21172 = thread->state;
  D.21174 = D.21172 | 64;
  thread->state = D.21174;
  D.21175 = CreateEvent (0B, 1, 0, 0B);
  thread->suspend_event = D.21175;
  D.21176 = thread->suspend_event;
  if (D.21176 == 0B) goto <D.21177>; else goto <D.21178>;
  <D.21177>:
  unlock_thread (thread);
  return;
  <D.21178>:
  D.21179 = thread->suspended_event;
  if (D.21179 != 0B) goto <D.21180>; else goto <D.21181>;
  <D.21180>:
  D.21179 = thread->suspended_event;
  SetEvent (D.21179);
  <D.21181>:
  unlock_thread (thread);
  shutting_down.46 = shutting_down;
  if (shutting_down.46 != 0) goto <D.21183>; else goto <D.21184>;
  <D.21183>:
  <D.20449>:
  Sleep (1000);
  goto <D.20449>;
  <D.21184>:
  D.21176 = thread->suspend_event;
  WaitForSingleObject (D.21176, 4294967295);
  lock_thread (thread);
  D.21176 = thread->suspend_event;
  CloseHandle (D.21176);
  thread->suspend_event = 0B;
  D.21172 = thread->state;
  D.21185 = D.21172 & 4294967231;
  thread->state = D.21185;
  D.21186 = thread->resume_event;
  SetEvent (D.21186);
  unlock_thread (thread);
  return;
  <D.21171>:
  transition_to_suspended (thread);
  mono_thread_info_self_suspend ();
}


transition_to_suspended (struct MonoInternalThread * thread)
{
  unsigned int D.21188;
  unsigned int D.21189;
  long unsigned int D.21194;
  unsigned int D.21196;
  unsigned int D.21197;

  D.21188 = thread->state;
  D.21189 = D.21188 & 2;
  if (D.21189 == 0) goto <D.21190>; else goto <D.21191>;
  <D.21190>:
  if (1 != 0) goto <D.21192>; else goto <D.21193>;
  <D.21192>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4693, "0");
  <D.21193>:
  D.21194 = thread->tid;
  mono_thread_info_resume (D.21194);
  goto <D.21195>;
  <D.21191>:
  D.21188 = thread->state;
  D.21196 = D.21188 & 4294967293;
  thread->state = D.21196;
  D.21188 = thread->state;
  D.21197 = D.21188 | 64;
  thread->state = D.21197;
  mono_thread_info_finish_suspend ();
  <D.21195>:
  unlock_thread (thread);
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_SpinWait_nop ()
{

}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_GetDomainID ()
{
  gint32 D.21198;
  struct MonoDomain * D.21199;

  D.21199 = mono_domain_get ();
  D.21198 = D.21199->domain_id;
  return D.21198;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Yield ()
{
  gboolean D.21201;
  int D.21202;
  _Bool D.21203;

  D.21202 = sched_yield ();
  D.21203 = D.21202 == 0;
  D.21201 = (gboolean) D.21203;
  return D.21201;
}


__attribute__((visibility ("hidden")))
mono_thread_get_name (struct MonoInternalThread * this_obj, guint32 * name_len)
{
  gunichar2 * D.21205;
  unsigned int D.21209;
  long unsigned int D.21210;
  long unsigned int D.21211;
  gunichar2 * D.21212;
  gunichar2 * res;

  lock_thread (this_obj);
  D.21205 = this_obj->name;
  if (D.21205 == 0B) goto <D.21206>; else goto <D.21207>;
  <D.21206>:
  *name_len = 0;
  res = 0B;
  goto <D.21208>;
  <D.21207>:
  D.21209 = this_obj->name_len;
  *name_len = D.21209;
  D.21209 = this_obj->name_len;
  D.21210 = (long unsigned int) D.21209;
  D.21211 = D.21210 * 2;
  res = monoeg_malloc (D.21211);
  D.21205 = this_obj->name;
  D.21209 = this_obj->name_len;
  D.21210 = (long unsigned int) D.21209;
  D.21211 = D.21210 * 2;
  memcpy (res, D.21205, D.21211);
  <D.21208>:
  unlock_thread (this_obj);
  D.21212 = res;
  return D.21212;
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.21214;
  long unsigned int D.21215;

  D.21215 = __builtin_object_size (__dest, 0);
  D.21214 = __builtin___memcpy_chk (__dest, __src, __len, D.21215);
  return D.21214;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_GetName_internal (struct MonoInternalThread * this_obj)
{
  gunichar2 * D.21217;
  struct MonoDomain * D.21221;
  unsigned int D.21222;
  int D.21223;
  struct MonoString * D.21224;
  struct MonoString * str;

  lock_thread (this_obj);
  D.21217 = this_obj->name;
  if (D.21217 == 0B) goto <D.21218>; else goto <D.21219>;
  <D.21218>:
  str = 0B;
  goto <D.21220>;
  <D.21219>:
  D.21221 = mono_domain_get ();
  D.21217 = this_obj->name;
  D.21222 = this_obj->name_len;
  D.21223 = (int) D.21222;
  str = mono_string_new_utf16 (D.21221, D.21217, D.21223);
  <D.21220>:
  unlock_thread (this_obj);
  D.21224 = str;
  return D.21224;
}


__attribute__((visibility ("hidden")))
mono_thread_set_name_internal (struct MonoInternalThread * this_obj, struct MonoString * name, gboolean managed)
{
  long unsigned int D.21226;
  long unsigned int D.21227;
  struct MonoException * D.21230;
  int D.21233;
  long unsigned int D.21234;
  long unsigned int D.21235;
  void * D.21236;
  gunichar2 * D.21237;
  mono_unichar2 * D.21238;
  int D.21239;
  int D.21240;
  long unsigned int D.21241;
  int D.21242;
  unsigned int D.21243;
  long unsigned int D.21247;
  long unsigned int D.21250;

  lock_thread (this_obj);
  D.21226 = this_obj->flags;
  D.21227 = D.21226 & 2;
  if (D.21227 != 0) goto <D.21228>; else goto <D.21229>;
  <D.21228>:
  unlock_thread (this_obj);
  D.21230 = mono_get_exception_invalid_operation ("Thread.Name can only be set once.");
  mono_raise_exception (D.21230);
  return;
  <D.21229>:
  if (name != 0B) goto <D.21231>; else goto <D.21232>;
  <D.21231>:
  D.21233 = mono_string_length (name);
  D.21234 = (long unsigned int) D.21233;
  D.21235 = D.21234 * 2;
  D.21236 = monoeg_malloc (D.21235);
  this_obj->name = D.21236;
  D.21237 = this_obj->name;
  D.21238 = mono_string_chars (name);
  D.21239 = mono_string_length (name);
  D.21240 = D.21239 * 2;
  D.21241 = (long unsigned int) D.21240;
  memcpy (D.21237, D.21238, D.21241);
  D.21242 = mono_string_length (name);
  D.21243 = (unsigned int) D.21242;
  this_obj->name_len = D.21243;
  goto <D.21244>;
  <D.21232>:
  this_obj->name = 0B;
  <D.21244>:
  if (managed != 0) goto <D.21245>; else goto <D.21246>;
  <D.21245>:
  D.21226 = this_obj->flags;
  D.21247 = D.21226 | 2;
  this_obj->flags = D.21247;
  <D.21246>:
  unlock_thread (this_obj);
  D.21237 = this_obj->name;
  if (D.21237 != 0B) goto <D.21248>; else goto <D.21249>;
  <D.21248>:
  {
    char * tname;

    tname = mono_string_to_utf8 (name);
    D.21250 = this_obj->tid;
    mono_profiler_thread_name (D.21250, tname);
    mono_free (tname);
  }
  <D.21249>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_SetName_internal (struct MonoInternalThread * this_obj, struct MonoString * name)
{
  mono_thread_set_name_internal (this_obj, name, 1);
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_ByteArrayToRootDomain (struct MonoArray * arr)
{
  struct MonoArray * D.21252;
  struct MonoDomain * D.21253;

  D.21253 = mono_get_root_domain ();
  D.21252 = byte_array_to_domain (arr, D.21253);
  return D.21252;
}


byte_array_to_domain (struct MonoArray * arr, struct MonoDomain * domain)
{
  struct MonoArray * D.21257;
  struct MonoVTable * D.21258;
  struct MonoDomain * D.21259;
  struct MonoClass * D.21262;
  unsigned int D.21263;
  long unsigned int D.21264;
  char * D.21265;
  char * D.21266;
  long unsigned int D.21267;
  struct MonoArray * copy;

  if (arr == 0B) goto <D.21255>; else goto <D.21256>;
  <D.21255>:
  D.21257 = 0B;
  return D.21257;
  <D.21256>:
  D.21258 = MEM[(struct MonoObject *)arr].vtable;
  D.21259 = D.21258->domain;
  if (D.21259 == domain) goto <D.21260>; else goto <D.21261>;
  <D.21260>:
  D.21257 = arr;
  return D.21257;
  <D.21261>:
  D.21262 = mono_defaults.byte_class;
  D.21263 = arr->max_length;
  D.21264 = (long unsigned int) D.21263;
  copy = mono_array_new (domain, D.21262, D.21264);
  D.21265 = mono_array_addr_with_size (copy, 1, 0);
  D.21266 = mono_array_addr_with_size (arr, 1, 0);
  D.21263 = arr->max_length;
  D.21267 = (long unsigned int) D.21263;
  memmove (D.21265, D.21266, D.21267);
  D.21257 = copy;
  return D.21257;
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memmove (void * __dest, const void * __src, size_t __len)
{
  void * D.21269;
  long unsigned int D.21270;

  D.21270 = __builtin_object_size (__dest, 0);
  D.21269 = __builtin___memmove_chk (__dest, __src, __len, D.21270);
  return D.21269;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_ByteArrayToCurrentDomain (struct MonoArray * arr)
{
  struct MonoArray * D.21272;
  struct MonoDomain * D.21273;

  D.21273 = mono_domain_get ();
  D.21272 = byte_array_to_domain (arr, D.21273);
  return D.21272;
}


mono_thread_current ()
{
  _Bool D.21275;
  long int D.21276;
  long int D.21277;
  struct MonoThread * D.21280;
  struct MonoDomain * D.21283;
  _Bool D.21284;
  long int D.21285;
  long int D.21286;
  struct MonoThread * D.21289;
  struct MonoThread * D.21290;
  struct MonoDomain * domain;
  struct MonoInternalThread * internal;
  struct MonoThread * * current_thread_ptr;

  domain = mono_domain_get ();
  internal = mono_thread_internal_current ();
  D.21275 = internal == 0B;
  D.21276 = (long int) D.21275;
  D.21277 = __builtin_expect (D.21276, 0);
  if (D.21277 != 0) goto <D.21278>; else goto <D.21279>;
  <D.21278>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1382, "internal");
  <D.21279>:
  current_thread_ptr = get_current_thread_ptr_for_domain (domain, internal);
  D.21280 = *current_thread_ptr;
  if (D.21280 == 0B) goto <D.21281>; else goto <D.21282>;
  <D.21281>:
  D.21283 = mono_get_root_domain ();
  D.21284 = D.21283 == domain;
  D.21285 = (long int) D.21284;
  D.21286 = __builtin_expect (D.21285, 0);
  if (D.21286 != 0) goto <D.21287>; else goto <D.21288>;
  <D.21287>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1386, "domain != mono_get_root_domain ()");
  <D.21288>:
  D.21289 = new_thread_with_internal (domain, internal);
  *current_thread_ptr = D.21289;
  <D.21282>:
  D.21290 = *current_thread_ptr;
  return D.21290;
}


__attribute__((visibility ("hidden")))
mono_thread_internal_current ()
{
  struct MonoInternalThread * D.21292;
  struct MonoInternalThread * res;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Join_internal (struct MonoInternalThread * this, int ms, void * thread)
{
  unsigned int D.21294;
  unsigned int D.21295;
  struct MonoException * D.21298;
  gboolean D.21299;
  unsigned int ms.47;
  unsigned int D.21303;
  struct MonoInternalThread * cur_thread;
  gboolean ret;

  cur_thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  lock_thread (this);
  D.21294 = this->state;
  D.21295 = D.21294 & 8;
  if (D.21295 != 0) goto <D.21296>; else goto <D.21297>;
  <D.21296>:
  unlock_thread (this);
  D.21298 = mono_get_exception_thread_state ("Thread has not been started.");
  mono_raise_exception (D.21298);
  D.21299 = 0;
  return D.21299;
  <D.21297>:
  unlock_thread (this);
  if (ms == -1) goto <D.21300>; else goto <D.21301>;
  <D.21300>:
  ms = -1;
  <D.21301>:
  mono_thread_set_state (cur_thread, 32);
  ms.47 = (unsigned int) ms;
  D.21303 = WaitForSingleObjectEx (thread, ms.47, 1);
  ret = (gboolean) D.21303;
  mono_thread_clr_state (cur_thread, 32);
  if (ret == 0) goto <D.21304>; else goto <D.21305>;
  <D.21304>:
  D.21299 = 1;
  return D.21299;
  <D.21305>:
  D.21299 = 0;
  return D.21299;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_WaitHandle_WaitAll_internal (struct MonoArray * mono_handles, gint32 ms, gboolean exitContext)
{
  long unsigned int D.21307;
  long unsigned int D.21308;
  long unsigned int D.21309;
  long unsigned int D.21310;
  char * D.21311;
  long unsigned int D.21312;
  long unsigned int D.21313;
  void * * D.21314;
  void * D.21315;
  int D.21318;
  gboolean D.21321;
  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 ();
  D.21307 = mono_array_length (mono_handles);
  numhandles = (guint32) D.21307;
  D.21308 = (long unsigned int) numhandles;
  D.21309 = D.21308 * 8;
  handles = monoeg_malloc0 (D.21309);
  i = 0;
  goto <D.19388>;
  <D.19387>:
  D.21310 = (long unsigned int) i;
  D.21311 = mono_array_addr_with_size (mono_handles, 8, D.21310);
  waitHandle = MEM[(struct MonoObject * *)D.21311];
  D.21312 = (long unsigned int) i;
  D.21313 = D.21312 * 8;
  D.21314 = handles + D.21313;
  D.21315 = mono_wait_handle_get_handle (waitHandle);
  *D.21314 = D.21315;
  i = i + 1;
  <D.19388>:
  if (i < numhandles) goto <D.19387>; else goto <D.19389>;
  <D.19389>:
  if (ms == -1) goto <D.21316>; else goto <D.21317>;
  <D.21316>:
  ms = -1;
  <D.21317>:
  mono_thread_set_state (thread, 32);
  D.21318 = mono_wait_uninterrupted (thread, 1, numhandles, handles, 1, ms, 1);
  ret = (guint32) D.21318;
  mono_thread_clr_state (thread, 32);
  monoeg_g_free (handles);
  if (ret == 4294967295) goto <D.21319>; else goto <D.21320>;
  <D.21319>:
  D.21321 = 0;
  return D.21321;
  <D.21320>:
  if (ret == 258) goto <D.21322>; else goto <D.21323>;
  <D.21322>:
  D.21321 = 0;
  return D.21321;
  <D.21323>:
  D.21321 = 1;
  return D.21321;
}


mono_wait_uninterrupted (struct MonoInternalThread * thread, gboolean multiple, guint32 numhandles, void * * handles, gboolean waitall, gint32 ms, gboolean alertable)
{
  gint64 iftmp.48;
  unsigned int wait.49;
  void * D.21333;
  unsigned int ms.50;
  long int D.21340;
  long int D.21341;
  long int D.21342;
  gint32 D.21345;
  struct MonoException * exc;
  guint32 ret;
  gint64 start;
  gint32 diff_ms;
  gint32 wait;

  wait = ms;
  if (ms != -1) goto <D.21326>; else goto <D.21327>;
  <D.21326>:
  iftmp.48 = mono_100ns_ticks ();
  goto <D.21328>;
  <D.21327>:
  iftmp.48 = 0;
  <D.21328>:
  start = iftmp.48;
  <D.19375>:
  if (multiple != 0) goto <D.21329>; else goto <D.21330>;
  <D.21329>:
  wait.49 = (unsigned int) wait;
  ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait.49, alertable);
  goto <D.21332>;
  <D.21330>:
  D.21333 = *handles;
  ms.50 = (unsigned int) ms;
  ret = WaitForSingleObjectEx (D.21333, ms.50, alertable);
  <D.21332>:
  if (ret != 192) goto <D.19373>; else goto <D.21335>;
  <D.21335>:
  exc = mono_thread_execute_interruption (thread);
  if (exc != 0B) goto <D.21336>; else goto <D.21337>;
  <D.21336>:
  mono_raise_exception (exc);
  <D.21337>:
  if (ms == -1) goto <D.21338>; else goto <D.21339>;
  <D.21338>:
  // predicted unlikely by continue predictor.
  goto <D.19374>;
  <D.21339>:
  D.21340 = mono_100ns_ticks ();
  D.21341 = D.21340 - start;
  D.21342 = D.21341 / 10000;
  diff_ms = (gint32) D.21342;
  if (diff_ms >= ms) goto <D.21343>; else goto <D.21344>;
  <D.21343>:
  ret = 258;
  goto <D.19373>;
  <D.21344>:
  wait = ms - diff_ms;
  <D.19374>:
  goto <D.19375>;
  <D.19373>:
  D.21345 = (gint32) ret;
  return D.21345;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_WaitHandle_WaitAny_internal (struct MonoArray * mono_handles, gint32 ms, gboolean exitContext)
{
  long unsigned int D.21347;
  gint32 D.21350;
  long unsigned int D.21351;
  char * D.21352;
  void * D.21353;
  int D.21356;
  unsigned int D.21357;
  unsigned int D.21362;
  unsigned int D.21364;
  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 ();
      D.21347 = mono_array_length (mono_handles);
      numhandles = (guint32) D.21347;
      if (numhandles > 64) goto <D.21348>; else goto <D.21349>;
      <D.21348>:
      D.21350 = -1;
      return D.21350;
      <D.21349>:
      i = 0;
      goto <D.19402>;
      <D.19401>:
      D.21351 = (long unsigned int) i;
      D.21352 = mono_array_addr_with_size (mono_handles, 8, D.21351);
      waitHandle = MEM[(struct MonoObject * *)D.21352];
      D.21353 = mono_wait_handle_get_handle (waitHandle);
      handles[i] = D.21353;
      i = i + 1;
      <D.19402>:
      if (i < numhandles) goto <D.19401>; else goto <D.19403>;
      <D.19403>:
      if (ms == -1) goto <D.21354>; else goto <D.21355>;
      <D.21354>:
      ms = -1;
      <D.21355>:
      mono_thread_set_state (thread, 32);
      D.21356 = mono_wait_uninterrupted (thread, 1, numhandles, &handles, 0, ms, 1);
      ret = (guint32) D.21356;
      mono_thread_clr_state (thread, 32);
      D.21357 = numhandles + 4294967295;
      if (D.21357 >= ret) goto <D.21358>; else goto <D.21359>;
      <D.21358>:
      D.21350 = (gint32) ret;
      return D.21350;
      <D.21359>:
      if (ret > 127) goto <D.21361>; else goto <D.21360>;
      <D.21361>:
      D.21362 = numhandles + 127;
      if (D.21362 >= ret) goto <D.21363>; else goto <D.21360>;
      <D.21363>:
      D.21364 = ret + 4294967168;
      D.21350 = (gint32) D.21364;
      return D.21350;
      <D.21360>:
      D.21350 = (gint32) ret;
      return D.21350;
    }
  finally
    {
      handles = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_WaitHandle_WaitOne_internal (struct MonoObject * this, void * handle, gint32 ms, gboolean exitContext)
{
  int D.21369;
  gboolean D.21372;
  guint32 ret;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (ms == -1) goto <D.21367>; else goto <D.21368>;
  <D.21367>:
  ms = -1;
  <D.21368>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.21369 = mono_wait_uninterrupted (thread, 0, 1, &handle, 0, ms, 1);
  ret = (guint32) D.21369;
  mono_thread_clr_state (thread, 32);
  if (ret == 4294967295) goto <D.21370>; else goto <D.21371>;
  <D.21370>:
  D.21372 = 0;
  return D.21372;
  <D.21371>:
  if (ret == 258) goto <D.21373>; else goto <D.21374>;
  <D.21373>:
  D.21372 = 0;
  return D.21372;
  <D.21374>:
  D.21372 = 1;
  return D.21372;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (void * toSignal, void * toWait, gint32 ms, gboolean exitContext)
{
  unsigned int ms.51;
  gboolean D.21379;
  int iftmp.52;
  guint32 ret;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (ms == -1) goto <D.21376>; else goto <D.21377>;
  <D.21376>:
  ms = -1;
  <D.21377>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  ms.51 = (unsigned int) ms;
  ret = SignalObjectAndWait (toSignal, toWait, ms.51, 1);
  mono_thread_clr_state (thread, 32);
  if (ret != 258) goto <D.21383>; else goto <D.21381>;
  <D.21383>:
  if (ret != 192) goto <D.21384>; else goto <D.21381>;
  <D.21384>:
  if (ret != 4294967295) goto <D.21385>; else goto <D.21381>;
  <D.21385>:
  iftmp.52 = 1;
  goto <D.21382>;
  <D.21381>:
  iftmp.52 = 0;
  <D.21382>:
  D.21379 = iftmp.52;
  return D.21379;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, struct MonoString * name, MonoBoolean * created)
{
  int D.21389;
  mono_unichar2 * D.21391;
  unsigned int D.21392;
  void * D.21395;
  void * mutex;

  *created = 1;
  if (name == 0B) goto <D.21387>; else goto <D.21388>;
  <D.21387>:
  D.21389 = (int) owned;
  mutex = CreateMutex (0B, D.21389, 0B);
  goto <D.21390>;
  <D.21388>:
  D.21389 = (int) owned;
  D.21391 = mono_string_chars (name);
  mutex = CreateMutex (0B, D.21389, D.21391);
  D.21392 = GetLastError ();
  if (D.21392 == 183) goto <D.21393>; else goto <D.21394>;
  <D.21393>:
  *created = 0;
  <D.21394>:
  <D.21390>:
  D.21395 = mutex;
  return D.21395;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Mutex_ReleaseMutex_internal (void * handle)
{
  MonoBoolean D.21397;
  int D.21398;

  D.21398 = ReleaseMutex (handle);
  D.21397 = (MonoBoolean) D.21398;
  return D.21397;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Mutex_OpenMutex_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.53;
  mono_unichar2 * D.21401;
  unsigned int D.21404;
  int D.21405;
  void * D.21406;
  void * ret;

  *error = 0;
  rights.53 = (unsigned int) rights;
  D.21401 = mono_string_chars (name);
  ret = OpenMutex (rights.53, 0, D.21401);
  if (ret == 0B) goto <D.21402>; else goto <D.21403>;
  <D.21402>:
  D.21404 = GetLastError ();
  D.21405 = (int) D.21404;
  *error = D.21405;
  <D.21403>:
  D.21406 = ret;
  return D.21406;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, struct MonoString * name, MonoBoolean * created)
{
  mono_unichar2 * D.21411;
  unsigned int D.21412;
  void * D.21415;
  void * sem;

  *created = 1;
  if (name == 0B) goto <D.21408>; else goto <D.21409>;
  <D.21408>:
  sem = CreateSemaphore (0B, initialCount, maximumCount, 0B);
  goto <D.21410>;
  <D.21409>:
  D.21411 = mono_string_chars (name);
  sem = CreateSemaphore (0B, initialCount, maximumCount, D.21411);
  D.21412 = GetLastError ();
  if (D.21412 == 183) goto <D.21413>; else goto <D.21414>;
  <D.21413>:
  *created = 0;
  <D.21414>:
  <D.21410>:
  D.21415 = sem;
  return D.21415;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (void * handle, gint32 releaseCount, MonoBoolean * fail)
{
  int D.21417;
  _Bool D.21418;
  unsigned char D.21419;
  gint32 D.21420;
  gint32 prevcount;

  try
    {
      D.21417 = ReleaseSemaphore (handle, releaseCount, &prevcount);
      D.21418 = D.21417 == 0;
      D.21419 = (unsigned char) D.21418;
      *fail = D.21419;
      D.21420 = prevcount;
      return D.21420;
    }
  finally
    {
      prevcount = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.54;
  mono_unichar2 * D.21424;
  unsigned int D.21427;
  int D.21428;
  void * D.21429;
  void * ret;

  *error = 0;
  rights.54 = (unsigned int) rights;
  D.21424 = mono_string_chars (name);
  ret = OpenSemaphore (rights.54, 0, D.21424);
  if (ret == 0B) goto <D.21425>; else goto <D.21426>;
  <D.21425>:
  D.21427 = GetLastError ();
  D.21428 = (int) D.21427;
  *error = D.21428;
  <D.21426>:
  D.21429 = ret;
  return D.21429;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, struct MonoString * name, MonoBoolean * created)
{
  int D.21433;
  int D.21434;
  mono_unichar2 * D.21436;
  unsigned int D.21437;
  void * D.21440;
  void * event;

  *created = 1;
  if (name == 0B) goto <D.21431>; else goto <D.21432>;
  <D.21431>:
  D.21433 = (int) manual;
  D.21434 = (int) initial;
  event = CreateEvent (0B, D.21433, D.21434, 0B);
  goto <D.21435>;
  <D.21432>:
  D.21433 = (int) manual;
  D.21434 = (int) initial;
  D.21436 = mono_string_chars (name);
  event = CreateEvent (0B, D.21433, D.21434, D.21436);
  D.21437 = GetLastError ();
  if (D.21437 == 183) goto <D.21438>; else goto <D.21439>;
  <D.21438>:
  *created = 0;
  <D.21439>:
  <D.21435>:
  D.21440 = event;
  return D.21440;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Events_SetEvent_internal (void * handle)
{
  gboolean D.21442;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Events_ResetEvent_internal (void * handle)
{
  gboolean D.21444;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Events_CloseEvent_internal (void * handle)
{
  CloseHandle (handle);
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Events_OpenEvent_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.55;
  mono_unichar2 * D.21447;
  unsigned int D.21450;
  int D.21451;
  void * D.21452;
  void * ret;

  *error = 0;
  rights.55 = (unsigned int) rights;
  D.21447 = mono_string_chars (name);
  ret = OpenEvent (rights.55, 0, D.21447);
  if (ret == 0B) goto <D.21448>; else goto <D.21449>;
  <D.21448>:
  D.21450 = GetLastError ();
  D.21451 = (int) D.21450;
  *error = D.21451;
  <D.21449>:
  D.21452 = ret;
  return D.21452;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Increment_Int (gint32 * location)
{
  gint32 D.21454;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Increment_Long (gint64 * location)
{
  gint64 D.21456;

  D.21456 = InterlockedIncrement64 (location);
  return D.21456;
}


InterlockedIncrement64 (volatile gint64 * val)
{
  gint64 D.21458;
  long unsigned int D.21459;

  D.21459 = __sync_add_and_fetch_8 (val, 1);
  D.21458 = (gint64) D.21459;
  return D.21458;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 * location)
{
  gint32 D.21461;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
{
  gint64 D.21463;

  D.21463 = InterlockedDecrement64 (location);
  return D.21463;
}


InterlockedDecrement64 (volatile gint64 * val)
{
  gint64 D.21465;
  long unsigned int D.21466;

  D.21466 = __sync_sub_and_fetch_8 (val, 1);
  D.21465 = (gint64) D.21466;
  return D.21465;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_Int (gint32 * location, gint32 value)
{
  gint32 D.21468;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_Object (struct MonoObject * * location, struct MonoObject * value)
{
  struct MonoObject * D.21470;
  struct MonoObject * res;

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


InterlockedExchangePointer (void * volatile * val, void * new_val)
{
  long unsigned int old_val.56;
  long unsigned int new_val.57;
  long unsigned int D.21474;
  void * D.21475;
  void * D.21476;
  void * old_val;

  <D.18944>:
  old_val = *val;
  old_val.56 = (long unsigned int) old_val;
  new_val.57 = (long unsigned int) new_val;
  D.21474 = __sync_val_compare_and_swap_8 (val, old_val.56, new_val.57);
  D.21475 = (void *) D.21474;
  if (D.21475 != old_val) goto <D.18944>; else goto <D.18945>;
  <D.18945>:
  D.21476 = old_val;
  return D.21476;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_IntPtr (void * * location, void * value)
{
  void * D.21478;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat * location, gfloat value)
{
  int D.21480;
  int D.21481;
  gfloat D.21482;
  union IntFloatUnion val;
  union IntFloatUnion ret;

  try
    {
      val.fval = value;
      D.21480 = val.ival;
      D.21481 = InterlockedExchange (location, D.21480);
      ret.ival = D.21481;
      D.21482 = ret.fval;
      return D.21482;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_Long (gint64 * location, gint64 value)
{
  gint64 D.21485;

  D.21485 = InterlockedExchange64 (location, value);
  return D.21485;
}


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

  <D.19014>:
  old_val = *val;
  D.21487 = InterlockedCompareExchange64 (val, new_val, old_val);
  if (D.21487 != old_val) goto <D.19014>; else goto <D.19015>;
  <D.19015>:
  D.21488 = old_val;
  return D.21488;
}


InterlockedCompareExchange64 (volatile gint64 * dest, gint64 exch, gint64 comp)
{
  gint64 D.21490;
  long unsigned int comp.58;
  long unsigned int exch.59;
  long unsigned int D.21493;

  comp.58 = (long unsigned int) comp;
  exch.59 = (long unsigned int) exch;
  D.21493 = __sync_val_compare_and_swap_8 (dest, comp.58, exch.59);
  D.21490 = (gint64) D.21493;
  return D.21490;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_Double (gdouble * location, gdouble value)
{
  long int D.21495;
  long int D.21496;
  gdouble D.21497;
  union LongDoubleUnion val;
  union LongDoubleUnion ret;

  try
    {
      val.fval = value;
      D.21495 = val.ival;
      D.21496 = InterlockedExchange64 (location, D.21495);
      ret.ival = D.21496;
      D.21497 = ret.fval;
      return D.21497;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_Int (gint32 * location, gint32 value, gint32 comparand)
{
  gint32 D.21500;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_Object (struct MonoObject * * location, struct MonoObject * value, struct MonoObject * comparand)
{
  struct MonoObject * D.21502;
  struct MonoObject * res;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_IntPtr (void * * location, void * value, void * comparand)
{
  void * D.21504;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat * location, gfloat value, gfloat comparand)
{
  int D.21506;
  int D.21507;
  int D.21508;
  gfloat D.21509;
  union IntFloatUnion val;
  union IntFloatUnion ret;
  union IntFloatUnion cmp;

  try
    {
      val.fval = value;
      cmp.fval = comparand;
      D.21506 = val.ival;
      D.21507 = cmp.ival;
      D.21508 = InterlockedCompareExchange (location, D.21506, D.21507);
      ret.ival = D.21508;
      D.21509 = ret.fval;
      return D.21509;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
      cmp = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_Double (gdouble * location, gdouble value, gdouble comparand)
{
  long int D.21512;
  void * D.21513;
  long int D.21514;
  void * D.21515;
  void * D.21516;
  long int D.21517;
  gdouble D.21518;
  union LongDoubleUnion val;
  union LongDoubleUnion comp;
  union LongDoubleUnion ret;

  try
    {
      val.fval = value;
      comp.fval = comparand;
      D.21512 = val.ival;
      D.21513 = (void *) D.21512;
      D.21514 = comp.ival;
      D.21515 = (void *) D.21514;
      D.21516 = InterlockedCompareExchangePointer (location, D.21513, D.21515);
      D.21517 = (long int) D.21516;
      ret.ival = D.21517;
      D.21518 = ret.fval;
      return D.21518;
    }
  finally
    {
      val = {CLOBBER};
      comp = {CLOBBER};
      ret = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_Long (gint64 * location, gint64 value, gint64 comparand)
{
  gint64 D.21521;

  D.21521 = InterlockedCompareExchange64 (location, value, comparand);
  return D.21521;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_CompareExchange_T (struct MonoObject * * location, struct MonoObject * value, struct MonoObject * comparand)
{
  struct MonoObject * D.21523;
  struct MonoObject * res;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Exchange_T (struct MonoObject * * location, struct MonoObject * value)
{
  struct MonoObject * D.21525;
  struct MonoObject * res;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Add_Int (gint32 * location, gint32 value)
{
  gint32 D.21527;

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


InterlockedAdd (volatile gint32 * dest, gint32 add)
{
  gint32 D.21529;
  unsigned int add.60;
  unsigned int D.21531;

  add.60 = (unsigned int) add;
  D.21531 = __sync_add_and_fetch_4 (dest, add.60);
  D.21529 = (gint32) D.21531;
  return D.21529;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Add_Long (gint64 * location, gint64 value)
{
  gint64 D.21533;

  D.21533 = InterlockedAdd64 (location, value);
  return D.21533;
}


InterlockedAdd64 (volatile gint64 * dest, gint64 add)
{
  gint64 D.21535;
  long unsigned int add.61;
  long unsigned int D.21537;

  add.61 = (long unsigned int) add;
  D.21537 = __sync_add_and_fetch_8 (dest, add.61);
  D.21535 = (gint64) D.21537;
  return D.21535;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Interlocked_Read_Long (gint64 * location)
{
  gint64 D.21539;

  D.21539 = InterlockedRead64 (location);
  return D.21539;
}


InterlockedRead64 (volatile gint64 * src)
{
  gint64 D.21541;
  long unsigned int D.21542;

  D.21542 = __sync_fetch_and_add_8 (src, 0);
  D.21541 = (gint64) D.21542;
  return D.21541;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_MemoryBarrier ()
{
  mono_memory_barrier ();
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_ClrState (struct MonoInternalThread * this, guint32 state)
{
  unsigned int D.21544;
  void * background_change_event.62;

  mono_thread_clr_state (this, state);
  D.21544 = state & 4;
  if (D.21544 != 0) goto <D.21545>; else goto <D.21546>;
  <D.21545>:
  background_change_event.62 = background_change_event;
  SetEvent (background_change_event.62);
  <D.21546>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_SetState (struct MonoInternalThread * this, guint32 state)
{
  unsigned int D.21548;
  void * background_change_event.63;

  mono_thread_set_state (this, state);
  D.21548 = state & 4;
  if (D.21548 != 0) goto <D.21549>; else goto <D.21550>;
  <D.21549>:
  background_change_event.63 = background_change_event;
  SetEvent (background_change_event.63);
  <D.21550>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_GetState (struct MonoInternalThread * this)
{
  guint32 D.21552;
  guint32 state;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Interrupt_internal (struct MonoInternalThread * this)
{
  int iftmp.64;
  unsigned int D.21558;
  unsigned int D.21559;
  struct MonoInternalThread * current;
  gboolean throw;

  lock_thread (this);
  current = mono_thread_internal_current ();
  this->thread_interrupt_requested = 1;
  if (current != this) goto <D.21557>; else goto <D.21555>;
  <D.21557>:
  D.21558 = this->state;
  D.21559 = D.21558 & 32;
  if (D.21559 != 0) goto <D.21560>; else goto <D.21555>;
  <D.21560>:
  iftmp.64 = 1;
  goto <D.21556>;
  <D.21555>:
  iftmp.64 = 0;
  <D.21556>:
  throw = iftmp.64;
  unlock_thread (this);
  if (throw != 0) goto <D.21561>; else goto <D.21562>;
  <D.21561>:
  abort_thread_internal (this, 1, 0);
  <D.21562>:
}


abort_thread_internal (struct MonoInternalThread * thread, gboolean can_raise_exception, gboolean install_async_abort)
{
  int D.21563;
  struct MonoInternalThread * D.21566;
  void * D.21571;
  long unsigned int D.21572;
  struct MonoRuntimeExceptionHandlingCallbacks * D.21575;
  gboolean (*<T285f>) (struct MonoThreadUnwindState *) D.21576;
  struct MonoThreadUnwindState * D.21577;
  int D.21578;
  long unsigned int D.21581;
  gint32 * D.21582;
  int D.21583;
  int iftmp.65;
  struct MonoMethod * D.21590;
  int D.21591;
  long unsigned int D.21593;
  void * D.21594;
  struct MonoJitInfo * ji;
  struct MonoThreadInfo * info;
  gboolean protected_wrapper;
  gboolean running_managed;

  info = 0B;
  D.21563 = mono_thread_info_new_interrupt_enabled ();
  if (D.21563 == 0) goto <D.21564>; else goto <D.21565>;
  <D.21564>:
  signal_thread_state_change (thread);
  return;
  <D.21565>:
  D.21566 = mono_thread_internal_current ();
  if (D.21566 == thread) goto <D.21567>; else goto <D.21568>;
  <D.21567>:
  {
    struct MonoException * exc;

    exc = mono_thread_request_interruption (can_raise_exception);
    if (exc != 0B) goto <D.21569>; else goto <D.21570>;
    <D.21569>:
    mono_raise_exception (exc);
    <D.21570>:
    D.21571 = thread->handle;
    wapi_interrupt_thread (D.21571);
    return;
  }
  <D.21568>:
  D.21572 = thread->tid;
  info = mono_thread_info_safe_suspend_sync (D.21572, 1);
  if (info == 0B) goto <D.21573>; else goto <D.21574>;
  <D.21573>:
  return;
  <D.21574>:
  D.21575 = mono_get_eh_callbacks ();
  D.21576 = D.21575->mono_install_handler_block_guard;
  D.21577 = &info->suspend_state;
  D.21578 = D.21576 (D.21577);
  if (D.21578 != 0) goto <D.21579>; else goto <D.21580>;
  <D.21579>:
  D.21581 = info->node.key;
  mono_thread_info_resume (D.21581);
  return;
  <D.21580>:
  D.21582 = &thread->interruption_requested;
  D.21583 = InterlockedCompareExchange (D.21582, 1, 0);
  if (D.21583 == 1) goto <D.21584>; else goto <D.21585>;
  <D.21584>:
  D.21581 = info->node.key;
  mono_thread_info_resume (D.21581);
  return;
  <D.21585>:
  InterlockedIncrement (&thread_interruption_requested);
  ji = mono_thread_info_get_last_managed (info);
  if (ji != 0B) goto <D.21589>; else goto <D.21587>;
  <D.21589>:
  D.21590 = mono_jit_info_get_method (ji);
  D.21591 = mono_threads_is_critical_method (D.21590);
  if (D.21591 != 0) goto <D.21592>; else goto <D.21587>;
  <D.21592>:
  iftmp.65 = 1;
  goto <D.21588>;
  <D.21587>:
  iftmp.65 = 0;
  <D.21588>:
  protected_wrapper = iftmp.65;
  D.21593 = info->suspend_state.ctx.uc_mcontext.psw.addr;
  D.21594 = (void *) D.21593;
  running_managed = mono_jit_info_match (ji, D.21594);
  if (protected_wrapper == 0) goto <D.21597>; else goto <D.21595>;
  <D.21597>:
  if (running_managed != 0) goto <D.21598>; else goto <D.21595>;
  <D.21598>:
  if (install_async_abort != 0) goto <D.21599>; else goto <D.21600>;
  <D.21599>:
  mono_thread_info_setup_async_call (info, self_interrupt_thread, 0B);
  <D.21600>:
  D.21581 = info->node.key;
  mono_thread_info_resume (D.21581);
  goto <D.21596>;
  <D.21595>:
  {
    void * interrupt_handle;

    D.21571 = thread->handle;
    interrupt_handle = wapi_prepare_interrupt_thread (D.21571);
    D.21581 = info->node.key;
    mono_thread_info_resume (D.21581);
    wapi_finish_interrupt_thread (interrupt_handle);
  }
  <D.21596>:
}


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

  info = mono_thread_info_current ();
  D.21602 = mono_thread_internal_current ();
  exc = mono_thread_execute_interruption (D.21602);
  if (exc != 0B) goto <D.21603>; else goto <D.21604>;
  <D.21603>:
  D.21605 = &info->suspend_state.ctx;
  mono_raise_exception_with_context (exc, D.21605);
  <D.21604>:
  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.21606;
  int D.21611;
  void * D.21612;

  D.21606 = mono_thread_internal_current ();
  if (D.21606 == thread) goto <D.21607>; else goto <D.21608>;
  <D.21607>:
  {
    struct MonoException * exc;

    exc = mono_thread_request_interruption (0);
    if (exc != 0B) goto <D.21609>; else goto <D.21610>;
    <D.21609>:
    mono_raise_exception (exc);
    <D.21610>:
  }
  <D.21608>:
  D.21611 = mono_thread_get_abort_signal ();
  mono_thread_kill (thread, D.21611);
  D.21612 = thread->handle;
  wapi_interrupt_thread (D.21612);
}


mono_thread_info_get_last_managed (struct MonoThreadInfo * info)
{
  struct MonoJitInfo * D.21615;
  struct MonoRuntimeExceptionHandlingCallbacks * D.21616;
  void (*<T284f>) (gboolean (*MonoInternalStackWalk) (struct MonoStackFrameInfo *, struct MonoContext *, void *), struct MonoThreadUnwindState *, MonoUnwindOptions, void *) D.21617;
  struct MonoThreadUnwindState * D.21618;
  struct MonoJitInfo * ji;

  try
    {
      ji = 0B;
      if (info == 0B) goto <D.21613>; else goto <D.21614>;
      <D.21613>:
      D.21615 = 0B;
      return D.21615;
      <D.21614>:
      D.21616 = mono_get_eh_callbacks ();
      D.21617 = D.21616->mono_walk_stack_with_state;
      D.21618 = &info->suspend_state;
      D.21617 (last_managed, D.21618, 0, &ji);
      D.21615 = ji;
      return D.21615;
    }
  finally
    {
      ji = {CLOBBER};
    }
}


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

  dest = data;
  D.21621 = frame->ji;
  *dest = D.21621;
  D.21622 = 1;
  return D.21622;
}


mono_threads_is_critical_method (struct MonoMethod * method)
{
  <unnamed-unsigned:5> D.21624;
  int D.21625;
  gboolean D.21626;

  D.21624 = method->wrapper_type;
  D.21625 = (int) D.21624;
  switch (D.21625) <default: <D.21627>, case 4: <D.19650>, case 10: <D.19651>, case 11: <D.19652>>
  <D.19650>:
  <D.19651>:
  <D.19652>:
  D.21626 = 1;
  return D.21626;
  <D.21627>:
  D.21626 = 0;
  return D.21626;
}


mono_jit_info_match (struct MonoJitInfo * ji, void * ip)
{
  gboolean D.21631;
  int iftmp.66;
  void * D.21635;
  int D.21637;
  sizetype D.21638;
  char * D.21639;

  if (ji == 0B) goto <D.21629>; else goto <D.21630>;
  <D.21629>:
  D.21631 = 0;
  return D.21631;
  <D.21630>:
  D.21635 = ji->code_start;
  if (D.21635 <= ip) goto <D.21636>; else goto <D.21633>;
  <D.21636>:
  D.21635 = ji->code_start;
  D.21637 = ji->code_size;
  D.21638 = (sizetype) D.21637;
  D.21639 = D.21635 + D.21638;
  if (D.21639 > ip) goto <D.21640>; else goto <D.21633>;
  <D.21640>:
  iftmp.66 = 1;
  goto <D.21634>;
  <D.21633>:
  iftmp.66 = 0;
  <D.21634>:
  D.21631 = iftmp.66;
  return D.21631;
}


__attribute__((visibility ("hidden")))
mono_thread_current_check_pending_interrupt ()
{
  unsigned char D.21642;
  struct MonoException * D.21647;
  struct MonoInternalThread * thread;
  gboolean throw;

  thread = mono_thread_internal_current ();
  throw = 0;
  lock_thread (thread);
  D.21642 = thread->thread_interrupt_requested;
  if (D.21642 != 0) goto <D.21643>; else goto <D.21644>;
  <D.21643>:
  throw = 1;
  thread->thread_interrupt_requested = 0;
  <D.21644>:
  unlock_thread (thread);
  if (throw != 0) goto <D.21645>; else goto <D.21646>;
  <D.21645>:
  D.21647 = mono_get_exception_thread_interrupted ();
  mono_raise_exception (D.21647);
  <D.21646>:
}


__attribute__((visibility ("hidden")))
mono_thread_get_abort_signal ()
{
  int abort_signum.67;
  int D.21651;
  int D.21652;
  void (*<Tfc3>) (int) D.21653;
  void (*<T1005>) (int, struct siginfo_t *, void *) D.21656;
  int D.21659;
  static int abort_signum = -1;
  int i;

  abort_signum.67 = abort_signum;
  if (abort_signum.67 != -1) goto <D.21649>; else goto <D.21650>;
  <D.21649>:
  D.21651 = abort_signum;
  return D.21651;
  <D.21650>:
  D.21652 = __libc_current_sigrtmin ();
  i = D.21652 + 1;
  goto <D.19607>;
  <D.19606>:
  {
    struct sigaction sinfo;

    try
      {
        sigaction (i, 0B, &sinfo);
        D.21653 = sinfo.__sigaction_handler.sa_handler;
        if (D.21653 == 0B) goto <D.21654>; else goto <D.21655>;
        <D.21654>:
        D.21656 = sinfo.__sigaction_handler.sa_sigaction;
        if (D.21656 == 0B) goto <D.21657>; else goto <D.21658>;
        <D.21657>:
        abort_signum = i;
        D.21651 = i;
        return D.21651;
        <D.21658>:
        <D.21655>:
      }
    finally
      {
        sinfo = {CLOBBER};
      }
  }
  i = i + 1;
  <D.19607>:
  D.21659 = __libc_current_sigrtmax ();
  if (D.21659 > i) goto <D.19606>; else goto <D.19608>;
  <D.19608>:
  D.21651 = __libc_current_sigrtmin ();
  return D.21651;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Abort (struct MonoInternalThread * thread, struct MonoObject * state)
{
  long unsigned int D.21663;
  long unsigned int D.21664;
  unsigned int D.21667;
  unsigned int D.21668;
  unsigned int D.21671;
  unsigned int D.21672;
  int D.21673;
  unsigned int D.21676;
  unsigned int D.21679;
  int D.21680;
  _Bool D.21681;
  long int D.21682;
  long int D.21683;
  int shutting_down.68;

  lock_thread (thread);
  D.21663 = BIT_FIELD_REF <*thread, 64, 384>;
  D.21664 = D.21663 & 145;
  if (D.21664 != 0) goto <D.21665>; else goto <D.21666>;
  <D.21665>:
  unlock_thread (thread);
  return;
  <D.21666>:
  D.21667 = thread->state;
  D.21668 = D.21667 & 8;
  if (D.21668 != 0) goto <D.21669>; else goto <D.21670>;
  <D.21669>:
  D.21667 = thread->state;
  D.21671 = D.21667 | 256;
  thread->state = D.21671;
  unlock_thread (thread);
  return;
  <D.21670>:
  D.21667 = thread->state;
  D.21672 = D.21667 | 128;
  thread->state = D.21672;
  D.21673 = thread->abort_state_handle;
  if (D.21673 != 0) goto <D.21674>; else goto <D.21675>;
  <D.21674>:
  D.21673 = thread->abort_state_handle;
  D.21676 = (unsigned int) D.21673;
  mono_gchandle_free (D.21676);
  <D.21675>:
  if (state != 0B) goto <D.21677>; else goto <D.21678>;
  <D.21677>:
  D.21679 = mono_gchandle_new (state, 0);
  D.21680 = (int) D.21679;
  thread->abort_state_handle = D.21680;
  D.21673 = thread->abort_state_handle;
  D.21681 = D.21673 == 0;
  D.21682 = (long int) D.21681;
  D.21683 = __builtin_expect (D.21682, 0);
  if (D.21683 != 0) goto <D.21684>; else goto <D.21685>;
  <D.21684>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2156, "thread->abort_state_handle");
  <D.21685>:
  goto <D.21686>;
  <D.21678>:
  thread->abort_state_handle = 0;
  <D.21686>:
  thread->abort_exc = 0B;
  unlock_thread (thread);
  shutting_down.68 = shutting_down;
  if (shutting_down.68 == 0) goto <D.21688>; else goto <D.21689>;
  <D.21688>:
  mono_thread_resume (thread);
  <D.21689>:
  abort_thread_internal (thread, 1, 1);
}


mono_thread_resume (struct MonoInternalThread * thread)
{
  unsigned int D.21691;
  unsigned int D.21692;
  unsigned int D.21695;
  gboolean D.21696;
  long unsigned int D.21697;
  long unsigned int D.21698;

  lock_thread (thread);
  D.21691 = thread->state;
  D.21692 = D.21691 & 2;
  if (D.21692 != 0) goto <D.21693>; else goto <D.21694>;
  <D.21693>:
  D.21691 = thread->state;
  D.21695 = D.21691 & 4294967293;
  thread->state = D.21695;
  unlock_thread (thread);
  D.21696 = 1;
  return D.21696;
  <D.21694>:
  D.21697 = BIT_FIELD_REF <*thread, 64, 384>;
  D.21698 = D.21697 & 344;
  if (D.21698 != 64) goto <D.21699>; else goto <D.21700>;
  <D.21699>:
  unlock_thread (thread);
  D.21696 = 0;
  return D.21696;
  <D.21700>:
  D.21696 = resume_thread_internal (thread);
  return D.21696;
}


resume_thread_internal (struct MonoInternalThread * thread)
{
  int D.21702;
  void * D.21705;
  void * D.21706;
  gboolean D.21709;
  void * D.21710;
  long unsigned int D.21711;
  int D.21712;
  unsigned int D.21715;
  unsigned int D.21716;

  D.21702 = mono_thread_info_new_interrupt_enabled ();
  if (D.21702 == 0) goto <D.21703>; else goto <D.21704>;
  <D.21703>:
  D.21705 = CreateEvent (0B, 1, 0, 0B);
  thread->resume_event = D.21705;
  D.21706 = thread->resume_event;
  if (D.21706 == 0B) goto <D.21707>; else goto <D.21708>;
  <D.21707>:
  unlock_thread (thread);
  D.21709 = 0;
  return D.21709;
  <D.21708>:
  D.21710 = thread->suspend_event;
  SetEvent (D.21710);
  unlock_thread (thread);
  D.21706 = thread->resume_event;
  WaitForSingleObject (D.21706, 4294967295);
  D.21706 = thread->resume_event;
  CloseHandle (D.21706);
  thread->resume_event = 0B;
  D.21709 = 1;
  return D.21709;
  <D.21704>:
  unlock_thread (thread);
  D.21711 = thread->tid;
  D.21712 = mono_thread_info_resume (D.21711);
  if (D.21712 == 0) goto <D.21713>; else goto <D.21714>;
  <D.21713>:
  D.21709 = 0;
  return D.21709;
  <D.21714>:
  lock_thread (thread);
  D.21715 = thread->state;
  D.21716 = D.21715 & 4294967231;
  thread->state = D.21716;
  unlock_thread (thread);
  D.21709 = 1;
  return D.21709;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_ResetAbort ()
{
  unsigned int D.21718;
  int D.21719;
  unsigned int D.21720;
  struct MonoException * D.21723;
  int D.21724;
  unsigned int D.21727;
  struct MonoInternalThread * thread;
  gboolean was_aborting;

  thread = mono_thread_internal_current ();
  lock_thread (thread);
  D.21718 = thread->state;
  D.21719 = (int) D.21718;
  was_aborting = D.21719 & 128;
  D.21718 = thread->state;
  D.21720 = D.21718 & 4294967167;
  thread->state = D.21720;
  unlock_thread (thread);
  if (was_aborting == 0) goto <D.21721>; else goto <D.21722>;
  <D.21721>:
  {
    const char * msg;

    msg = "Unable to reset abort because no abort was requested";
    D.21723 = mono_get_exception_thread_state (msg);
    mono_raise_exception (D.21723);
  }
  <D.21722>:
  thread->abort_exc = 0B;
  D.21724 = thread->abort_state_handle;
  if (D.21724 != 0) goto <D.21725>; else goto <D.21726>;
  <D.21725>:
  D.21724 = thread->abort_state_handle;
  D.21727 = (unsigned int) D.21724;
  mono_gchandle_free (D.21727);
  thread->abort_state_handle = 0;
  <D.21726>:
}


__attribute__((visibility ("hidden")))
mono_thread_internal_reset_abort (struct MonoInternalThread * thread)
{
  unsigned int D.21728;
  unsigned int D.21729;
  struct MonoException * D.21730;
  int D.21733;
  unsigned int D.21736;

  lock_thread (thread);
  D.21728 = thread->state;
  D.21729 = D.21728 & 4294967167;
  thread->state = D.21729;
  D.21730 = thread->abort_exc;
  if (D.21730 != 0B) goto <D.21731>; else goto <D.21732>;
  <D.21731>:
  thread->abort_exc = 0B;
  D.21733 = thread->abort_state_handle;
  if (D.21733 != 0) goto <D.21734>; else goto <D.21735>;
  <D.21734>:
  D.21733 = thread->abort_state_handle;
  D.21736 = (unsigned int) D.21733;
  mono_gchandle_free (D.21736);
  thread->abort_state_handle = 0;
  <D.21735>:
  <D.21732>:
  unlock_thread (thread);
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_GetAbortExceptionState (struct MonoThread * this)
{
  int D.21737;
  struct MonoObject * D.21740;
  unsigned int D.21741;
  _Bool D.21742;
  long int D.21743;
  long int D.21744;
  struct MonoVTable * D.21747;
  struct MonoDomain * D.21748;
  struct MonoObject * exc.69;
  struct MonoObject * * D.21756;
  struct MonoInternalThread * thread;
  struct MonoObject * state;
  struct MonoObject * deserialized;
  struct MonoObject * exc;
  struct MonoDomain * domain;

  try
    {
      thread = this->internal_thread;
      deserialized = 0B;
      D.21737 = thread->abort_state_handle;
      if (D.21737 == 0) goto <D.21738>; else goto <D.21739>;
      <D.21738>:
      D.21740 = 0B;
      return D.21740;
      <D.21739>:
      D.21737 = thread->abort_state_handle;
      D.21741 = (unsigned int) D.21737;
      state = mono_gchandle_get_target (D.21741);
      D.21742 = state == 0B;
      D.21743 = (long int) D.21742;
      D.21744 = __builtin_expect (D.21743, 0);
      if (D.21744 != 0) goto <D.21745>; else goto <D.21746>;
      <D.21745>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2237, "state");
      <D.21746>:
      domain = mono_domain_get ();
      D.21747 = state->vtable;
      D.21748 = D.21747->domain;
      if (D.21748 == domain) goto <D.21749>; else goto <D.21750>;
      <D.21749>:
      D.21740 = state;
      return D.21740;
      <D.21750>:
      deserialized = mono_object_xdomain_representation (state, domain, &exc);
      if (deserialized == 0B) goto <D.21751>; else goto <D.21752>;
      <D.21751>:
      {
        struct MonoException * invalid_op_exc;

        invalid_op_exc = mono_get_exception_invalid_operation ("Thread.ExceptionState cannot access an ExceptionState from a different AppDomain");
        exc.69 = exc;
        if (exc.69 != 0B) goto <D.21754>; else goto <D.21755>;
        <D.21754>:
        D.21756 = &invalid_op_exc->inner_ex;
        exc.69 = exc;
        mono_gc_wbarrier_set_field (invalid_op_exc, D.21756, exc.69);
        <D.21755>:
        mono_raise_exception (invalid_op_exc);
      }
      <D.21752>:
      D.21740 = deserialized;
      return D.21740;
    }
  finally
    {
      exc = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Suspend (struct MonoInternalThread * thread)
{
  int D.21759;
  struct MonoException * D.21762;

  D.21759 = mono_thread_suspend (thread);
  if (D.21759 == 0) goto <D.21760>; else goto <D.21761>;
  <D.21760>:
  D.21762 = mono_get_exception_thread_state ("Thread has not been started, or is dead.");
  mono_raise_exception (D.21762);
  <D.21761>:
}


mono_thread_suspend (struct MonoInternalThread * thread)
{
  long unsigned int D.21763;
  long unsigned int D.21764;
  gboolean D.21767;
  long unsigned int D.21768;
  unsigned int D.21771;
  unsigned int D.21772;

  lock_thread (thread);
  D.21763 = BIT_FIELD_REF <*thread, 64, 384>;
  D.21764 = D.21763 & 280;
  if (D.21764 != 0) goto <D.21765>; else goto <D.21766>;
  <D.21765>:
  unlock_thread (thread);
  D.21767 = 0;
  return D.21767;
  <D.21766>:
  D.21763 = BIT_FIELD_REF <*thread, 64, 384>;
  D.21768 = D.21763 & 67;
  if (D.21768 != 0) goto <D.21769>; else goto <D.21770>;
  <D.21769>:
  unlock_thread (thread);
  D.21767 = 1;
  return D.21767;
  <D.21770>:
  D.21771 = thread->state;
  D.21772 = D.21771 | 2;
  thread->state = D.21772;
  unlock_thread (thread);
  suspend_thread_internal (thread, 0);
  D.21767 = 1;
  return D.21767;
}


suspend_thread_internal (struct MonoInternalThread * thread, gboolean interrupt)
{
  int D.21774;
  struct MonoInternalThread * D.21777;
  long unsigned int D.21781;
  int iftmp.70;
  struct MonoMethod * D.21788;
  int D.21789;
  long unsigned int D.21791;
  void * D.21792;
  gint32 * D.21797;
  int D.21798;
  void * D.21803;
  long unsigned int D.21804;

  D.21774 = mono_thread_info_new_interrupt_enabled ();
  if (D.21774 == 0) goto <D.21775>; else goto <D.21776>;
  <D.21775>:
  signal_thread_state_change (thread);
  return;
  <D.21776>:
  lock_thread (thread);
  D.21777 = mono_thread_internal_current ();
  if (D.21777 == thread) goto <D.21778>; else goto <D.21779>;
  <D.21778>:
  transition_to_suspended (thread);
  mono_thread_info_self_suspend ();
  goto <D.21780>;
  <D.21779>:
  {
    struct MonoThreadInfo * info;
    struct MonoJitInfo * ji;
    gboolean protected_wrapper;
    gboolean running_managed;

    D.21781 = thread->tid;
    info = mono_thread_info_safe_suspend_sync (D.21781, interrupt);
    if (info == 0B) goto <D.21782>; else goto <D.21783>;
    <D.21782>:
    unlock_thread (thread);
    return;
    <D.21783>:
    ji = mono_thread_info_get_last_managed (info);
    if (ji != 0B) goto <D.21787>; else goto <D.21785>;
    <D.21787>:
    D.21788 = mono_jit_info_get_method (ji);
    D.21789 = mono_threads_is_critical_method (D.21788);
    if (D.21789 != 0) goto <D.21790>; else goto <D.21785>;
    <D.21790>:
    iftmp.70 = 1;
    goto <D.21786>;
    <D.21785>:
    iftmp.70 = 0;
    <D.21786>:
    protected_wrapper = iftmp.70;
    D.21791 = info->suspend_state.ctx.uc_mcontext.psw.addr;
    D.21792 = (void *) D.21791;
    running_managed = mono_jit_info_match (ji, D.21792);
    if (running_managed != 0) goto <D.21795>; else goto <D.21793>;
    <D.21795>:
    if (protected_wrapper == 0) goto <D.21796>; else goto <D.21793>;
    <D.21796>:
    transition_to_suspended (thread);
    goto <D.21794>;
    <D.21793>:
    {
      void * interrupt_handle;

      D.21797 = &thread->interruption_requested;
      D.21798 = InterlockedCompareExchange (D.21797, 1, 0);
      if (D.21798 == 0) goto <D.21799>; else goto <D.21800>;
      <D.21799>:
      InterlockedIncrement (&thread_interruption_requested);
      <D.21800>:
      if (interrupt != 0) goto <D.21801>; else goto <D.21802>;
      <D.21801>:
      D.21803 = thread->handle;
      interrupt_handle = wapi_prepare_interrupt_thread (D.21803);
      <D.21802>:
      D.21804 = info->node.key;
      mono_thread_info_resume (D.21804);
      if (interrupt != 0) goto <D.21805>; else goto <D.21806>;
      <D.21805>:
      wapi_finish_interrupt_thread (interrupt_handle);
      <D.21806>:
      unlock_thread (thread);
    }
    <D.21794>:
  }
  <D.21780>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_Resume (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.21810;
  int D.21812;
  struct MonoException * D.21813;

  D.21810 = thread->internal_thread;
  if (D.21810 == 0B) goto <D.21808>; else goto <D.21811>;
  <D.21811>:
  D.21810 = thread->internal_thread;
  D.21812 = mono_thread_resume (D.21810);
  if (D.21812 == 0) goto <D.21808>; else goto <D.21809>;
  <D.21808>:
  D.21813 = mono_get_exception_thread_state ("Thread has not been started, or is dead.");
  mono_raise_exception (D.21813);
  <D.21809>:
}


__attribute__((visibility ("hidden")))
mono_thread_internal_stop (struct MonoInternalThread * thread)
{
  long unsigned int D.21814;
  long unsigned int D.21815;
  unsigned int D.21818;
  unsigned int D.21819;
  unsigned int D.21820;

  lock_thread (thread);
  D.21814 = BIT_FIELD_REF <*thread, 64, 384>;
  D.21815 = D.21814 & 17;
  if (D.21815 != 0) goto <D.21816>; else goto <D.21817>;
  <D.21816>:
  unlock_thread (thread);
  return;
  <D.21817>:
  mono_thread_resume (thread);
  D.21818 = thread->state;
  D.21819 = D.21818 | 1;
  thread->state = D.21819;
  D.21818 = thread->state;
  D.21820 = D.21818 & 4294967167;
  thread->state = D.21820;
  unlock_thread (thread);
  abort_thread_internal (thread, 1, 1);
}


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

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileRead1 (void * ptr)
{
  gint8 D.21823;
  gint8 tmp;

  {
    gint8 __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileRead2 (void * ptr)
{
  gint16 D.21825;
  gint16 tmp;

  {
    gint16 __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileRead4 (void * ptr)
{
  gint32 D.21827;
  gint32 tmp;

  {
    gint32 __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileRead8 (void * ptr)
{
  gint64 D.21829;
  gint64 tmp;

  {
    gint64 __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileReadIntPtr (void * ptr)
{
  void * D.21831;
  volatile void * tmp;

  {
    volatile void * __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileReadObject (void * ptr)
{
  void * D.21833;
  volatile struct MonoObject * tmp;

  {
    volatile struct MonoObject * __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileReadDouble (void * ptr)
{
  double D.21835;
  double tmp;

  {
    double __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileReadFloat (void * ptr)
{
  float D.21837;
  float tmp;

  {
    float __tmp;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Read1 (void * ptr)
{
  gint8 D.21839;

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


InterlockedRead8 (volatile gint8 * src)
{
  gint8 D.21841;
  unsigned char D.21842;

  D.21842 = __sync_fetch_and_add_1 (src, 0);
  D.21841 = (gint8) D.21842;
  return D.21841;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Read2 (void * ptr)
{
  gint16 D.21844;

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


InterlockedRead16 (volatile gint16 * src)
{
  gint16 D.21846;
  short unsigned int D.21847;

  D.21847 = __sync_fetch_and_add_2 (src, 0);
  D.21846 = (gint16) D.21847;
  return D.21846;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Read4 (void * ptr)
{
  gint32 D.21849;

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


InterlockedRead (volatile gint32 * src)
{
  gint32 D.21851;
  unsigned int D.21852;

  D.21852 = __sync_fetch_and_add_4 (src, 0);
  D.21851 = (gint32) D.21852;
  return D.21851;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Read8 (void * ptr)
{
  gint64 D.21854;

  D.21854 = InterlockedRead64 (ptr);
  return D.21854;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_ReadIntPtr (void * ptr)
{
  void * D.21856;

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


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

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_ReadDouble (void * ptr)
{
  long int D.21860;
  double D.21861;
  union LongDoubleUnion u;

  try
    {
      D.21860 = InterlockedRead64 (ptr);
      u.ival = D.21860;
      D.21861 = u.fval;
      return D.21861;
    }
  finally
    {
      u = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_ReadFloat (void * ptr)
{
  int D.21864;
  float D.21865;
  union IntFloatUnion u;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Read_T (void * ptr)
{
  struct MonoObject * D.21868;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWrite1 (void * ptr, gint8 value)
{
  MEM[(volatile gint8 *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWrite2 (void * ptr, gint16 value)
{
  MEM[(volatile gint16 *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWrite4 (void * ptr, gint32 value)
{
  MEM[(volatile gint32 *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWrite8 (void * ptr, gint64 value)
{
  MEM[(volatile gint64 *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void * ptr, void * value)
{
  MEM[(volatile void * *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWriteObject (void * ptr, struct MonoObject * value)
{
  mono_gc_wbarrier_generic_store_atomic (ptr, value);
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWriteDouble (void * ptr, double value)
{
  MEM[(volatile double *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Thread_VolatileWriteFloat (void * ptr, float value)
{
  MEM[(volatile float *)ptr] = value;
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Write1 (void * ptr, gint8 value)
{
  InterlockedWrite8 (ptr, value);
}


InterlockedWrite8 (volatile gint8 * dst, gint8 val)
{
  unsigned char old_val.71;
  unsigned char val.72;
  unsigned char D.21872;
  signed char D.21873;
  gint8 old_val;

  <D.18964>:
  old_val = *dst;
  old_val.71 = (unsigned char) old_val;
  val.72 = (unsigned char) val;
  D.21872 = __sync_val_compare_and_swap_1 (dst, old_val.71, val.72);
  D.21873 = (signed char) D.21872;
  if (D.21873 != old_val) goto <D.18964>; else goto <D.18965>;
  <D.18965>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Write2 (void * ptr, gint16 value)
{
  InterlockedWrite16 (ptr, value);
}


InterlockedWrite16 (volatile gint16 * dst, gint16 val)
{
  short unsigned int old_val.73;
  short unsigned int val.74;
  short unsigned int D.21876;
  short int D.21877;
  gint16 old_val;

  <D.18971>:
  old_val = *dst;
  old_val.73 = (short unsigned int) old_val;
  val.74 = (short unsigned int) val;
  D.21876 = __sync_val_compare_and_swap_2 (dst, old_val.73, val.74);
  D.21877 = (short int) D.21876;
  if (D.21877 != old_val) goto <D.18971>; else goto <D.18972>;
  <D.18972>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Write4 (void * ptr, gint32 value)
{
  InterlockedWrite (ptr, value);
}


InterlockedWrite (volatile gint32 * dst, gint32 val)
{
  unsigned int old_val.75;
  unsigned int val.76;
  unsigned int D.21880;
  int D.21881;
  gint32 old_val;

  <D.18978>:
  old_val = *dst;
  old_val.75 = (unsigned int) old_val;
  val.76 = (unsigned int) val;
  D.21880 = __sync_val_compare_and_swap_4 (dst, old_val.75, val.76);
  D.21881 = (int) D.21880;
  if (D.21881 != old_val) goto <D.18978>; else goto <D.18979>;
  <D.18979>:
}


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Write8 (void * ptr, gint64 value)
{
  InterlockedWrite64 (ptr, value);
}


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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_WriteIntPtr (void * ptr, void * value)
{
  InterlockedWritePointer (ptr, value);
}


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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_WriteDouble (void * ptr, double value)
{
  long int D.21882;
  union LongDoubleUnion u;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_WriteFloat (void * ptr, float value)
{
  int D.21883;
  union IntFloatUnion u;

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


__attribute__((visibility ("hidden")))
ves_icall_System_Threading_Volatile_Write_T (void * ptr, struct MonoObject * value)
{
  mono_gc_wbarrier_generic_store_atomic (ptr, value);
}


__attribute__((visibility ("hidden")))
mono_thread_init_tls ()
{
  mono_native_tls_alloc (&current_object_key, 0B);
}


mono_native_tls_alloc (pthread_key_t * key, void * destructor)
{
  int D.21884;
  void (*<Tc6>) (void *) destructor.77;
  int D.21886;
  _Bool D.21887;

  destructor.77 = (void (*<Tc6>) (void *)) destructor;
  D.21886 = pthread_key_create (key, destructor.77);
  D.21887 = D.21886 == 0;
  D.21884 = (int) D.21887;
  return D.21884;
}


mono_thread_init (void (*MonoThreadStartCB) (intptr_t, void *, void *) start_cb, void (*MonoThreadAttachCB) (intptr_t, void *) attach_cb)
{
  void * D.21889;
  void * background_change_event.78;
  _Bool D.21891;
  long int D.21892;
  long int D.21893;

  InitializeCriticalSection (&threads_mutex);
  InitializeCriticalSection (&interlocked_mutex);
  InitializeCriticalSection (&contexts_mutex);
  D.21889 = CreateEvent (0B, 1, 0, 0B);
  background_change_event = D.21889;
  background_change_event.78 = background_change_event;
  D.21891 = background_change_event.78 == 0B;
  D.21892 = (long int) D.21891;
  D.21893 = __builtin_expect (D.21892, 0);
  if (D.21893 != 0) goto <D.21894>; else goto <D.21895>;
  <D.21894>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2657, "background_change_event != NULL");
  <D.21895>:
  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.21896;
  unsigned int D.21897;
  unsigned int current_object_key.79;

  D.21896 = mono_environment_exitcode_get ();
  D.21897 = (unsigned int) D.21896;
  _wapi_thread_signal_self (D.21897);
  current_object_key.79 = current_object_key;
  mono_native_tls_free (current_object_key.79);
}


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


__attribute__((visibility ("hidden")))
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.21899;

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


__attribute__((visibility ("hidden")))
mono_threads_install_notify_pending_exc (void (*MonoThreadNotifyPendingExcFunc) (void) func)
{
  mono_thread_notify_pending_exc_fn = func;
}


__attribute__((visibility ("hidden")))
mono_threads_set_shutting_down ()
{
  _Bool D.21902;
  long int D.21903;
  long int D.21904;
  int shutting_down.80;
  _Bool D.21912;
  long int D.21913;
  long int D.21914;
  long unsigned int D.21917;
  long unsigned int D.21918;
  unsigned int D.21922;
  unsigned int D.21923;
  void * background_change_event.81;
  _Bool D.21927;
  long int D.21928;
  long int D.21929;
  struct MonoInternalThread * current_thread;

  current_thread = mono_thread_internal_current ();
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21900>; else goto <D.21901>;
    <D.21900>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.21901>:
    D.21902 = ret != 0;
    D.21903 = (long int) D.21902;
    D.21904 = __builtin_expect (D.21903, 0);
    if (D.21904 != 0) goto <D.21905>; else goto <D.21906>;
    <D.21905>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2934, "ret == 0");
    <D.21906>:
  }
  shutting_down.80 = shutting_down;
  if (shutting_down.80 != 0) goto <D.21908>; else goto <D.21909>;
  <D.21908>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21910>; else goto <D.21911>;
    <D.21910>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21911>:
    D.21912 = ret != 0;
    D.21913 = (long int) D.21912;
    D.21914 = __builtin_expect (D.21913, 0);
    if (D.21914 != 0) goto <D.21915>; else goto <D.21916>;
    <D.21915>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2937, "ret == 0");
    <D.21916>:
  }
  lock_thread (current_thread);
  D.21917 = BIT_FIELD_REF <*current_thread, 64, 384>;
  D.21918 = D.21917 & 131;
  if (D.21918 != 0) goto <D.21919>; else goto <D.21920>;
  <D.21919>:
  unlock_thread (current_thread);
  mono_thread_execute_interruption (current_thread);
  goto <D.21921>;
  <D.21920>:
  D.21922 = current_thread->state;
  D.21923 = D.21922 | 16;
  current_thread->state = D.21923;
  unlock_thread (current_thread);
  <D.21921>:
  mono_domain_unset ();
  ExitThread (0);
  <D.21909>:
  shutting_down = 1;
  background_change_event.81 = background_change_event;
  SetEvent (background_change_event.81);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21925>; else goto <D.21926>;
    <D.21925>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21926>:
    D.21927 = ret != 0;
    D.21928 = (long int) D.21927;
    D.21929 = __builtin_expect (D.21928, 0);
    if (D.21929 != 0) goto <D.21930>; else goto <D.21931>;
    <D.21930>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2967, "ret == 0");
    <D.21931>:
  }
}


mono_thread_manage ()
{
  _Bool D.21934;
  long int D.21935;
  long int D.21936;
  struct MonoGHashTable * threads.82;
  _Bool D.21944;
  long int D.21945;
  long int D.21946;
  _Bool D.21951;
  long int D.21952;
  long int D.21953;
  _Bool D.21958;
  long int D.21959;
  long int D.21960;
  int shutting_down.83;
  _Bool D.21968;
  long int D.21969;
  long int D.21970;
  void * background_change_event.84;
  struct MonoInternalThread *[64] * D.21974;
  _Bool D.21977;
  long int D.21978;
  long int D.21979;
  unsigned int D.21982;
  int D.21985;
  struct MonoInternalThread * D.21988;
  struct MonoInternalThread * D.21989;
  _Bool D.21992;
  long int D.21993;
  long int D.21994;
  _Bool D.21999;
  long int D.22000;
  long int D.22001;
  struct wait_data wait_data;
  struct wait_data * wait;

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

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21932>; else goto <D.21933>;
        <D.21932>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21933>:
        D.21934 = ret != 0;
        D.21935 = (long int) D.21934;
        D.21936 = __builtin_expect (D.21935, 0);
        if (D.21936 != 0) goto <D.21937>; else goto <D.21938>;
        <D.21937>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2980, "ret == 0");
        <D.21938>:
      }
      threads.82 = threads;
      if (threads.82 == 0B) goto <D.21940>; else goto <D.21941>;
      <D.21940>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21942>; else goto <D.21943>;
        <D.21942>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21943>:
        D.21944 = ret != 0;
        D.21945 = (long int) D.21944;
        D.21946 = __builtin_expect (D.21945, 0);
        if (D.21946 != 0) goto <D.21947>; else goto <D.21948>;
        <D.21947>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2983, "ret == 0");
        <D.21948>:
      }
      return;
      <D.21941>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21949>; else goto <D.21950>;
        <D.21949>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21950>:
        D.21951 = ret != 0;
        D.21952 = (long int) D.21951;
        D.21953 = __builtin_expect (D.21952, 0);
        if (D.21953 != 0) goto <D.21954>; else goto <D.21955>;
        <D.21954>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2986, "ret == 0");
        <D.21955>:
      }
      <D.19897>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21956>; else goto <D.21957>;
        <D.21956>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21957>:
        D.21958 = ret != 0;
        D.21959 = (long int) D.21958;
        D.21960 = __builtin_expect (D.21959, 0);
        if (D.21960 != 0) goto <D.21961>; else goto <D.21962>;
        <D.21961>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2989, "ret == 0");
        <D.21962>:
      }
      shutting_down.83 = shutting_down;
      if (shutting_down.83 != 0) goto <D.21964>; else goto <D.21965>;
      <D.21964>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21966>; else goto <D.21967>;
        <D.21966>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21967>:
        D.21968 = ret != 0;
        D.21969 = (long int) D.21968;
        D.21970 = __builtin_expect (D.21969, 0);
        if (D.21970 != 0) goto <D.21971>; else goto <D.21972>;
        <D.21971>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2992, "ret == 0");
        <D.21972>:
      }
      goto <D.19895>;
      <D.21965>:
      background_change_event.84 = background_change_event;
      ResetEvent (background_change_event.84);
      wait->num = 0;
      D.21974 = &wait->threads;
      memset (D.21974, 0, 512);
      threads.82 = threads;
      mono_g_hash_table_foreach (threads.82, build_wait_tids, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21975>; else goto <D.21976>;
        <D.21975>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21976>:
        D.21977 = ret != 0;
        D.21978 = (long int) D.21977;
        D.21979 = __builtin_expect (D.21978, 0);
        if (D.21979 != 0) goto <D.21980>; else goto <D.21981>;
        <D.21980>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3003, "ret == 0");
        <D.21981>:
      }
      D.21982 = wait->num;
      if (D.21982 != 0) goto <D.21983>; else goto <D.21984>;
      <D.21983>:
      wait_for_tids_or_state_change (wait, 4294967295);
      <D.21984>:
      D.21982 = wait->num;
      if (D.21982 != 0) goto <D.19897>; else goto <D.19895>;
      <D.19895>:
      D.21985 = mono_runtime_try_shutdown ();
      if (D.21985 == 0) goto <D.21986>; else goto <D.21987>;
      <D.21986>:
      D.21988 = mono_thread_internal_current ();
      mono_thread_suspend (D.21988);
      D.21989 = mono_thread_internal_current ();
      mono_thread_execute_interruption (D.21989);
      <D.21987>:
      <D.19900>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21990>; else goto <D.21991>;
        <D.21990>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21991>:
        D.21992 = ret != 0;
        D.21993 = (long int) D.21992;
        D.21994 = __builtin_expect (D.21993, 0);
        if (D.21994 != 0) goto <D.21995>; else goto <D.21996>;
        <D.21995>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3023, "ret == 0");
        <D.21996>:
      }
      wait->num = 0;
      D.21974 = &wait->threads;
      memset (D.21974, 0, 512);
      threads.82 = threads;
      mono_g_hash_table_foreach_remove (threads.82, remove_and_abort_threads, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21997>; else goto <D.21998>;
        <D.21997>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21998>:
        D.21999 = ret != 0;
        D.22000 = (long int) D.21999;
        D.22001 = __builtin_expect (D.22000, 0);
        if (D.22001 != 0) goto <D.22002>; else goto <D.22003>;
        <D.22002>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3030, "ret == 0");
        <D.22003>:
      }
      D.21982 = wait->num;
      if (D.21982 != 0) goto <D.22004>; else goto <D.22005>;
      <D.22004>:
      wait_for_tids (wait, 4294967295);
      <D.22005>:
      D.21982 = wait->num;
      if (D.21982 != 0) goto <D.19900>; else goto <D.19901>;
      <D.19901>:
      sched_yield ();
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


remove_and_abort_threads (void * key, void * value, void * user)
{
  unsigned int D.22009;
  gboolean D.22012;
  long unsigned int D.22013;
  unsigned int D.22016;
  unsigned int D.22017;
  long unsigned int D.22020;
  long unsigned int D.22021;
  void * D.22026;
  unsigned int D.22027;
  int iftmp.85;
  int D.22032;
  struct wait_data * wait;
  gsize self;
  struct MonoInternalThread * thread;
  void * handle;

  wait = user;
  self = GetCurrentThreadId ();
  thread = value;
  D.22009 = wait->num;
  if (D.22009 > 63) goto <D.22010>; else goto <D.22011>;
  <D.22010>:
  D.22012 = 0;
  return D.22012;
  <D.22011>:
  D.22013 = thread->tid;
  if (D.22013 != self) goto <D.22014>; else goto <D.22015>;
  <D.22014>:
  D.22016 = thread->state;
  D.22017 = D.22016 & 4;
  if (D.22017 != 0) goto <D.22018>; else goto <D.22019>;
  <D.22018>:
  D.22020 = thread->flags;
  D.22021 = D.22020 & 1;
  if (D.22021 == 0) goto <D.22022>; else goto <D.22023>;
  <D.22022>:
  D.22013 = thread->tid;
  handle = OpenThread (2032639, 1, D.22013);
  if (handle == 0B) goto <D.22024>; else goto <D.22025>;
  <D.22024>:
  D.22012 = 0;
  return D.22012;
  <D.22025>:
  D.22009 = wait->num;
  D.22026 = thread->handle;
  wait->handles[D.22009] = D.22026;
  D.22009 = wait->num;
  wait->threads[D.22009] = thread;
  D.22009 = wait->num;
  D.22027 = D.22009 + 1;
  wait->num = D.22027;
  mono_thread_internal_stop (thread);
  D.22012 = 1;
  return D.22012;
  <D.22023>:
  <D.22019>:
  <D.22015>:
  D.22013 = thread->tid;
  if (D.22013 != self) goto <D.22031>; else goto <D.22029>;
  <D.22031>:
  D.22032 = mono_gc_is_finalizer_internal_thread (thread);
  if (D.22032 == 0) goto <D.22033>; else goto <D.22029>;
  <D.22033>:
  iftmp.85 = 1;
  goto <D.22030>;
  <D.22029>:
  iftmp.85 = 0;
  <D.22030>:
  D.22012 = iftmp.85;
  return D.22012;
}


build_wait_tids (void * key, void * value, void * user)
{
  unsigned int D.22035;
  unsigned int D.22038;
  unsigned int D.22039;
  int D.22042;
  struct MonoInternalThread * D.22045;
  struct MonoThread * D.22048;
  struct MonoThread * D.22051;
  struct _MonoInternalThread * D.22052;
  long unsigned int D.22055;
  long unsigned int D.22056;
  long unsigned int D.22059;
  mono_bool (*<T1dff>) (struct MonoThread *) D.22064;
  struct MonoThread * D.22066;
  int D.22067;
  unsigned int D.22068;
  struct wait_data * wait;

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

    thread = value;
    D.22038 = thread->state;
    D.22039 = D.22038 & 4;
    if (D.22039 != 0) goto <D.22040>; else goto <D.22041>;
    <D.22040>:
    return;
    <D.22041>:
    D.22042 = mono_gc_is_finalizer_internal_thread (thread);
    if (D.22042 != 0) goto <D.22043>; else goto <D.22044>;
    <D.22043>:
    return;
    <D.22044>:
    D.22045 = mono_thread_internal_current ();
    if (D.22045 == thread) goto <D.22046>; else goto <D.22047>;
    <D.22046>:
    return;
    <D.22047>:
    D.22048 = mono_thread_get_main ();
    if (D.22048 != 0B) goto <D.22049>; else goto <D.22050>;
    <D.22049>:
    D.22051 = mono_thread_get_main ();
    D.22052 = D.22051->internal_thread;
    if (D.22052 == thread) goto <D.22053>; else goto <D.22054>;
    <D.22053>:
    return;
    <D.22054>:
    <D.22050>:
    D.22055 = thread->flags;
    D.22056 = D.22055 & 1;
    if (D.22056 != 0) goto <D.22057>; else goto <D.22058>;
    <D.22057>:
    return;
    <D.22058>:
    D.22059 = thread->tid;
    handle = OpenThread (2032639, 1, D.22059);
    if (handle == 0B) goto <D.22060>; else goto <D.22061>;
    <D.22060>:
    return;
    <D.22061>:
    D.22064 = thread->manage_callback;
    if (D.22064 == 0B) goto <D.22062>; else goto <D.22065>;
    <D.22065>:
    D.22064 = thread->manage_callback;
    D.22066 = thread->root_domain_thread;
    D.22067 = D.22064 (D.22066);
    if (D.22067 == 1) goto <D.22062>; else goto <D.22063>;
    <D.22062>:
    D.22035 = wait->num;
    wait->handles[D.22035] = handle;
    D.22035 = wait->num;
    wait->threads[D.22035] = thread;
    D.22035 = wait->num;
    D.22068 = D.22035 + 1;
    wait->num = D.22068;
    <D.22063>:
  }
  goto <D.22069>;
  <D.22037>:
  <D.22069>:
}


wait_for_tids_or_state_change (struct wait_data * wait, guint32 timeout)
{
  void * background_change_event.86;
  void *[64] * D.22074;
  void * D.22077;
  unsigned int D.22078;
  struct MonoInternalThread * D.22083;
  _Bool D.22086;
  long int D.22087;
  long int D.22088;
  struct MonoGHashTable * threads.87;
  const void * tid.88;
  void * D.22093;
  _Bool D.22098;
  long int D.22099;
  long int D.22100;
  _Bool D.22106;
  long int D.22107;
  long int D.22108;
  guint32 i;
  guint32 ret;
  guint32 count;

  count = wait->num;
  if (count <= 63) goto <D.22071>; else goto <D.22072>;
  <D.22071>:
  background_change_event.86 = background_change_event;
  wait->handles[count] = background_change_event.86;
  count = count + 1;
  <D.22072>:
  D.22074 = &wait->handles;
  ret = WaitForMultipleObjectsEx (count, D.22074, 0, timeout, 1);
  if (ret == 4294967295) goto <D.22075>; else goto <D.22076>;
  <D.22075>:
  return;
  <D.22076>:
  i = 0;
  goto <D.19855>;
  <D.19854>:
  D.22077 = wait->handles[i];
  CloseHandle (D.22077);
  i = i + 1;
  <D.19855>:
  D.22078 = wait->num;
  if (D.22078 > i) goto <D.19854>; else goto <D.19856>;
  <D.19856>:
  if (ret == 258) goto <D.22079>; else goto <D.22080>;
  <D.22079>:
  return;
  <D.22080>:
  D.22078 = wait->num;
  if (D.22078 > ret) goto <D.22081>; else goto <D.22082>;
  <D.22081>:
  {
    gsize tid;

    D.22083 = wait->threads[ret];
    tid = D.22083->tid;
    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22084>; else goto <D.22085>;
      <D.22084>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22085>:
      D.22086 = ret != 0;
      D.22087 = (long int) D.22086;
      D.22088 = __builtin_expect (D.22087, 0);
      if (D.22088 != 0) goto <D.22089>; else goto <D.22090>;
      <D.22089>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2819, "ret == 0");
      <D.22090>:
    }
    threads.87 = threads;
    tid.88 = (const void *) tid;
    D.22093 = mono_g_hash_table_lookup (threads.87, tid.88);
    if (D.22093 != 0B) goto <D.22094>; else goto <D.22095>;
    <D.22094>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22096>; else goto <D.22097>;
      <D.22096>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22097>:
      D.22098 = ret != 0;
      D.22099 = (long int) D.22098;
      D.22100 = __builtin_expect (D.22099, 0);
      if (D.22100 != 0) goto <D.22101>; else goto <D.22102>;
      <D.22101>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2822, "ret == 0");
      <D.22102>:
    }
    D.22083 = wait->threads[ret];
    thread_cleanup (D.22083);
    goto <D.22103>;
    <D.22095>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22104>; else goto <D.22105>;
      <D.22104>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22105>:
      D.22106 = ret != 0;
      D.22107 = (long int) D.22106;
      D.22108 = __builtin_expect (D.22107, 0);
      if (D.22108 != 0) goto <D.22109>; else goto <D.22110>;
      <D.22109>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2826, "ret == 0");
      <D.22110>:
    }
    <D.22103>:
  }
  <D.22082>:
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memset (void * __dest, int __ch, size_t __len)
{
  void * D.22112;
  long unsigned int D.22113;

  D.22113 = __builtin_object_size (__dest, 0);
  D.22112 = __builtin___memset_chk (__dest, __ch, __len, D.22113);
  return D.22112;
}


wait_for_tids (struct wait_data * wait, guint32 timeout)
{
  unsigned int D.22115;
  void *[64] * D.22116;
  void * D.22119;
  struct MonoInternalThread * D.22122;
  _Bool D.22125;
  long int D.22126;
  long int D.22127;
  struct MonoGHashTable * threads.89;
  const void * tid.90;
  void * D.22132;
  _Bool D.22137;
  long int D.22138;
  long int D.22139;
  _Bool D.22145;
  long int D.22146;
  long int D.22147;
  guint32 i;
  guint32 ret;

  D.22115 = wait->num;
  D.22116 = &wait->handles;
  ret = WaitForMultipleObjectsEx (D.22115, D.22116, 1, timeout, 1);
  if (ret == 4294967295) goto <D.22117>; else goto <D.22118>;
  <D.22117>:
  return;
  <D.22118>:
  i = 0;
  goto <D.19838>;
  <D.19837>:
  D.22119 = wait->handles[i];
  CloseHandle (D.22119);
  i = i + 1;
  <D.19838>:
  D.22115 = wait->num;
  if (D.22115 > i) goto <D.19837>; else goto <D.19839>;
  <D.19839>:
  if (ret == 258) goto <D.22120>; else goto <D.22121>;
  <D.22120>:
  return;
  <D.22121>:
  i = 0;
  goto <D.19845>;
  <D.19844>:
  {
    gsize tid;

    D.22122 = wait->threads[i];
    tid = D.22122->tid;
    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22123>; else goto <D.22124>;
      <D.22123>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22124>:
      D.22125 = ret != 0;
      D.22126 = (long int) D.22125;
      D.22127 = __builtin_expect (D.22126, 0);
      if (D.22127 != 0) goto <D.22128>; else goto <D.22129>;
      <D.22128>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2766, "ret == 0");
      <D.22129>:
    }
    threads.89 = threads;
    tid.90 = (const void *) tid;
    D.22132 = mono_g_hash_table_lookup (threads.89, tid.90);
    if (D.22132 != 0B) goto <D.22133>; else goto <D.22134>;
    <D.22133>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22135>; else goto <D.22136>;
      <D.22135>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22136>:
      D.22137 = ret != 0;
      D.22138 = (long int) D.22137;
      D.22139 = __builtin_expect (D.22138, 0);
      if (D.22139 != 0) goto <D.22140>; else goto <D.22141>;
      <D.22140>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2779, "ret == 0");
      <D.22141>:
    }
    D.22122 = wait->threads[i];
    thread_cleanup (D.22122);
    goto <D.22142>;
    <D.22134>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22143>; else goto <D.22144>;
      <D.22143>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22144>:
      D.22145 = ret != 0;
      D.22146 = (long int) D.22145;
      D.22147 = __builtin_expect (D.22146, 0);
      if (D.22147 != 0) goto <D.22148>; else goto <D.22149>;
      <D.22148>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2783, "ret == 0");
      <D.22149>:
    }
    <D.22142>:
  }
  i = i + 1;
  <D.19845>:
  D.22115 = wait->num;
  if (D.22115 > i) goto <D.19844>; else goto <D.19846>;
  <D.19846>:
}


__attribute__((visibility ("hidden")))
mono_thread_abort_all_other_threads ()
{
  _Bool D.22153;
  long int D.22154;
  long int D.22155;
  struct MonoGHashTable * threads.91;
  void * self.92;
  _Bool D.22162;
  long int D.22163;
  long int D.22164;
  gsize self;

  self = GetCurrentThreadId ();
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22151>; else goto <D.22152>;
    <D.22151>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22152>:
    D.22153 = ret != 0;
    D.22154 = (long int) D.22153;
    D.22155 = __builtin_expect (D.22154, 0);
    if (D.22155 != 0) goto <D.22156>; else goto <D.22157>;
    <D.22156>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3062, "ret == 0");
    <D.22157>:
  }
  threads.91 = threads;
  self.92 = (void *) self;
  mono_g_hash_table_foreach (threads.91, terminate_thread, self.92);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22160>; else goto <D.22161>;
    <D.22160>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22161>:
    D.22162 = ret != 0;
    D.22163 = (long int) D.22162;
    D.22164 = __builtin_expect (D.22163, 0);
    if (D.22164 != 0) goto <D.22165>; else goto <D.22166>;
    <D.22165>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3069, "ret == 0");
    <D.22166>:
  }
}


terminate_thread (void * key, void * value, void * user)
{
  long unsigned int D.22167;
  long unsigned int user.93;
  struct MonoInternalThread * thread;

  thread = value;
  D.22167 = thread->tid;
  user.93 = (long unsigned int) user;
  if (D.22167 != user.93) goto <D.22169>; else goto <D.22170>;
  <D.22169>:
  <D.22170>:
}


__attribute__((visibility ("hidden")))
mono_thread_suspend_all_other_threads ()
{
  int shutting_down.94;
  _Bool D.22172;
  long int D.22173;
  long int D.22174;
  struct MonoInternalThread *[64] * D.22177;
  _Bool D.22180;
  long int D.22181;
  long int D.22182;
  struct MonoGHashTable * threads.95;
  _Bool D.22188;
  long int D.22189;
  long int D.22190;
  unsigned int D.22193;
  long unsigned int D.22194;
  long unsigned int D.22195;
  long unsigned int D.22198;
  int D.22200;
  long unsigned int D.22202;
  long unsigned int D.22203;
  void * D.22204;
  void * D.22207;
  long unsigned int D.22210;
  long unsigned int D.22211;
  void * D.22214;
  unsigned int D.22215;
  unsigned int D.22216;
  unsigned int eventidx.96;
  long unsigned int D.22220;
  long unsigned int D.22221;
  void * * D.22222;
  unsigned int D.22223;
  unsigned int D.22226;
  unsigned int D.22227;
  int D.22228;
  unsigned int i.97;
  int D.22237;
  unsigned int D.22242;
  unsigned int D.22243;
  void * D.22246;
  _Bool D.22251;
  long int D.22252;
  long int D.22253;
  struct MonoGHashTable * threads_starting_up.98;
  unsigned int D.22259;
  _Bool D.22260;
  _Bool D.22264;
  long int D.22265;
  long int D.22266;
  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, 1032);
      shutting_down.94 = shutting_down;
      D.22172 = shutting_down.94 == 0;
      D.22173 = (long int) D.22172;
      D.22174 = __builtin_expect (D.22173, 0);
      if (D.22174 != 0) goto <D.22175>; else goto <D.22176>;
      <D.22175>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3128, "shutting_down");
      <D.22176>:
      finished = 0;
      goto <D.19949>;
      <D.19948>:
      wait->num = 0;
      D.22177 = &wait->threads;
      memset (D.22177, 0, 512);
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22178>; else goto <D.22179>;
        <D.22178>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22179>:
        D.22180 = ret != 0;
        D.22181 = (long int) D.22180;
        D.22182 = __builtin_expect (D.22181, 0);
        if (D.22182 != 0) goto <D.22183>; else goto <D.22184>;
        <D.22183>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3144, "ret == 0");
        <D.22184>:
      }
      threads.95 = threads;
      mono_g_hash_table_foreach (threads.95, collect_threads_for_suspend, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22186>; else goto <D.22187>;
        <D.22186>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22187>:
        D.22188 = ret != 0;
        D.22189 = (long int) D.22188;
        D.22190 = __builtin_expect (D.22189, 0);
        if (D.22190 != 0) goto <D.22191>; else goto <D.22192>;
        <D.22191>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3146, "ret == 0");
        <D.22192>:
      }
      D.22193 = wait->num;
      D.22194 = (long unsigned int) D.22193;
      D.22195 = D.22194 * 8;
      events = monoeg_malloc0 (D.22195);
      eventidx = 0;
      i = 0;
      goto <D.19939>;
      <D.19938>:
      {
        struct MonoInternalThread * thread;
        gboolean signal_suspend;

        thread = wait->threads[i];
        signal_suspend = 0;
        D.22198 = thread->tid;
        if (D.22198 == self) goto <D.22196>; else goto <D.22199>;
        <D.22199>:
        D.22200 = mono_gc_is_finalizer_internal_thread (thread);
        if (D.22200 != 0) goto <D.22196>; else goto <D.22201>;
        <D.22201>:
        D.22202 = thread->flags;
        D.22203 = D.22202 & 1;
        if (D.22203 != 0) goto <D.22196>; else goto <D.22197>;
        <D.22196>:
        wait->threads[i] = 0B;
        // predicted unlikely by continue predictor.
        goto <D.19937>;
        <D.22197>:
        lock_thread (thread);
        D.22204 = thread->suspended_event;
        if (D.22204 == 0B) goto <D.22205>; else goto <D.22206>;
        <D.22205>:
        D.22207 = CreateEvent (0B, 1, 0, 0B);
        thread->suspended_event = D.22207;
        D.22204 = thread->suspended_event;
        if (D.22204 == 0B) goto <D.22208>; else goto <D.22209>;
        <D.22208>:
        unlock_thread (thread);
        // predicted unlikely by continue predictor.
        goto <D.19937>;
        <D.22209>:
        <D.22206>:
        D.22210 = BIT_FIELD_REF <*thread, 64, 384>;
        D.22211 = D.22210 & 81;
        if (D.22211 != 0) goto <D.22212>; else goto <D.22213>;
        <D.22212>:
        unlock_thread (thread);
        D.22214 = wait->handles[i];
        CloseHandle (D.22214);
        wait->threads[i] = 0B;
        // predicted unlikely by continue predictor.
        goto <D.19937>;
        <D.22213>:
        D.22215 = thread->state;
        D.22216 = D.22215 & 2;
        if (D.22216 == 0) goto <D.22217>; else goto <D.22218>;
        <D.22217>:
        signal_suspend = 1;
        <D.22218>:
        eventidx.96 = eventidx;
        eventidx = eventidx.96 + 1;
        D.22220 = (long unsigned int) eventidx.96;
        D.22221 = D.22220 * 8;
        D.22222 = events + D.22221;
        D.22204 = thread->suspended_event;
        *D.22222 = D.22204;
        D.22215 = thread->state;
        D.22223 = D.22215 & 128;
        if (D.22223 != 0) goto <D.22224>; else goto <D.22225>;
        <D.22224>:
        D.22215 = thread->state;
        D.22226 = D.22215 & 4294967167;
        thread->state = D.22226;
        <D.22225>:
        D.22215 = thread->state;
        D.22227 = D.22215 | 2;
        thread->state = D.22227;
        unlock_thread (thread);
        D.22228 = mono_thread_info_new_interrupt_enabled ();
        if (D.22228 != 0) goto <D.22229>; else goto <D.22230>;
        <D.22229>:
        suspend_thread_internal (thread, 1);
        goto <D.22231>;
        <D.22230>:
        if (signal_suspend != 0) goto <D.22232>; else goto <D.22233>;
        <D.22232>:
        signal_thread_state_change (thread);
        <D.22233>:
        <D.22231>:
      }
      <D.19937>:
      i = i + 1;
      <D.19939>:
      D.22193 = wait->num;
      i.97 = (unsigned int) i;
      if (D.22193 > i.97) goto <D.19938>; else goto <D.19940>;
      <D.19940>:
      if (eventidx != 0) goto <D.22235>; else goto <D.22236>;
      <D.22235>:
      D.22237 = mono_thread_info_new_interrupt_enabled ();
      if (D.22237 == 0) goto <D.22238>; else goto <D.22239>;
      <D.22238>:
      WaitForMultipleObjectsEx (eventidx, events, 1, 100, 0);
      i = 0;
      goto <D.19944>;
      <D.19943>:
      {
        struct MonoInternalThread * thread;

        thread = wait->threads[i];
        if (thread == 0B) goto <D.22240>; else goto <D.22241>;
        <D.22240>:
        // predicted unlikely by continue predictor.
        goto <D.19942>;
        <D.22241>:
        lock_thread (thread);
        D.22242 = thread->state;
        D.22243 = D.22242 & 64;
        if (D.22243 != 0) goto <D.22244>; else goto <D.22245>;
        <D.22244>:
        D.22246 = thread->suspended_event;
        CloseHandle (D.22246);
        thread->suspended_event = 0B;
        <D.22245>:
        unlock_thread (thread);
      }
      <D.19942>:
      i = i + 1;
      <D.19944>:
      D.22193 = wait->num;
      i.97 = (unsigned int) i;
      if (D.22193 > i.97) goto <D.19943>; else goto <D.19945>;
      <D.19945>:
      <D.22239>:
      <D.22236>:
      if (eventidx == 0) goto <D.22247>; else goto <D.22248>;
      <D.22247>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22249>; else goto <D.22250>;
        <D.22249>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22250>:
        D.22251 = ret != 0;
        D.22252 = (long int) D.22251;
        D.22253 = __builtin_expect (D.22252, 0);
        if (D.22253 != 0) goto <D.22254>; else goto <D.22255>;
        <D.22254>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3227, "ret == 0");
        <D.22255>:
      }
      threads_starting_up.98 = threads_starting_up;
      if (threads_starting_up.98 != 0B) goto <D.22257>; else goto <D.22258>;
      <D.22257>:
      threads_starting_up.98 = threads_starting_up;
      D.22259 = mono_g_hash_table_size (threads_starting_up.98);
      D.22260 = D.22259 != 0;
      starting = (gboolean) D.22260;
      goto <D.22261>;
      <D.22258>:
      starting = 0;
      <D.22261>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22262>; else goto <D.22263>;
        <D.22262>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22263>:
        D.22264 = ret != 0;
        D.22265 = (long int) D.22264;
        D.22266 = __builtin_expect (D.22265, 0);
        if (D.22266 != 0) goto <D.22267>; else goto <D.22268>;
        <D.22267>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3232, "ret == 0");
        <D.22268>:
      }
      if (starting != 0) goto <D.22269>; else goto <D.22270>;
      <D.22269>:
      Sleep (100);
      goto <D.22271>;
      <D.22270>:
      finished = 1;
      <D.22271>:
      <D.22248>:
      monoeg_g_free (events);
      <D.19949>:
      if (finished == 0) goto <D.19948>; else goto <D.19950>;
      <D.19950>:
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


collect_threads_for_suspend (void * key, void * value, void * user_data)
{
  long unsigned int D.22272;
  long unsigned int D.22273;
  unsigned int D.22276;
  long unsigned int D.22279;
  unsigned int D.22282;
  struct MonoInternalThread * thread;
  struct wait_data * wait;
  void * handle;

  thread = value;
  wait = user_data;
  D.22272 = BIT_FIELD_REF <*thread, 64, 384>;
  D.22273 = D.22272 & 80;
  if (D.22273 != 0) goto <D.22274>; else goto <D.22275>;
  <D.22274>:
  return;
  <D.22275>:
  D.22276 = wait->num;
  if (D.22276 <= 63) goto <D.22277>; else goto <D.22278>;
  <D.22277>:
  D.22279 = thread->tid;
  handle = OpenThread (2032639, 1, D.22279);
  if (handle == 0B) goto <D.22280>; else goto <D.22281>;
  <D.22280>:
  return;
  <D.22281>:
  D.22276 = wait->num;
  wait->handles[D.22276] = handle;
  D.22276 = wait->num;
  wait->threads[D.22276] = thread;
  D.22276 = wait->num;
  D.22282 = D.22276 + 1;
  wait->num = D.22282;
  <D.22278>:
}


__attribute__((visibility ("hidden")))
mono_threads_perform_thread_dump ()
{
  int thread_dump_requested.99;
  _Bool D.22289;
  long int D.22290;
  long int D.22291;
  struct MonoGHashTable * threads.100;
  _Bool D.22297;
  long int D.22298;
  long int D.22299;

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

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22287>; else goto <D.22288>;
    <D.22287>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22288>:
    D.22289 = ret != 0;
    D.22290 = (long int) D.22289;
    D.22291 = __builtin_expect (D.22290, 0);
    if (D.22291 != 0) goto <D.22292>; else goto <D.22293>;
    <D.22292>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3357, "ret == 0");
    <D.22293>:
  }
  threads.100 = threads;
  mono_g_hash_table_foreach (threads.100, dump_thread, 0B);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22295>; else goto <D.22296>;
    <D.22295>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22296>:
    D.22297 = ret != 0;
    D.22298 = (long int) D.22297;
    D.22299 = __builtin_expect (D.22298, 0);
    if (D.22299 != 0) goto <D.22300>; else goto <D.22301>;
    <D.22300>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3359, "ret == 0");
    <D.22301>:
  }
  thread_dump_requested = 0;
}


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

  thread = value;
  D.22303 = mono_thread_internal_current ();
  if (D.22303 == thread) goto <D.22304>; else goto <D.22305>;
  <D.22304>:
  return;
  <D.22305>:
  D.22306 = thread->tid;
  info = mono_thread_info_safe_suspend_sync (D.22306, 0);
  if (info == 0B) goto <D.22307>; else goto <D.22308>;
  <D.22307>:
  return;
  <D.22308>:
  print_thread_dump (thread, info);
}


print_thread_dump (struct MonoInternalThread * thread, struct MonoThreadInfo * info)
{
  gunichar2 * D.22310;
  unsigned int D.22313;
  long int D.22314;
  struct GError * error.101;
  _Bool D.22316;
  long int D.22317;
  long int D.22318;
  unsigned char D.22322;
  struct MonoRuntimeExceptionHandlingCallbacks * D.22326;
  void (*<T284f>) (gboolean (*MonoInternalStackWalk) (struct MonoStackFrameInfo *, struct MonoContext *, void *), struct MonoThreadUnwindState *, MonoUnwindOptions, void *) D.22327;
  struct MonoThreadUnwindState * D.22328;
  long unsigned int D.22329;
  struct _IO_FILE * stdout.102;
  char * D.22331;
  struct GString * text;
  char * name;
  struct GError * error;

  try
    {
      text = monoeg_g_string_new (0B);
      error = 0B;
      D.22310 = thread->name;
      if (D.22310 != 0B) goto <D.22311>; else goto <D.22312>;
      <D.22311>:
      D.22310 = thread->name;
      D.22313 = thread->name_len;
      D.22314 = (long int) D.22313;
      name = monoeg_g_utf16_to_utf8 (D.22310, D.22314, 0B, 0B, &error);
      error.101 = error;
      D.22316 = error.101 != 0B;
      D.22317 = (long int) D.22316;
      D.22318 = __builtin_expect (D.22317, 0);
      if (D.22318 != 0) goto <D.22319>; else goto <D.22320>;
      <D.22319>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3290, "!error");
      <D.22320>:
      monoeg_g_string_append_printf (text, "\n\"%s\"", name);
      monoeg_g_free (name);
      goto <D.22321>;
      <D.22312>:
      D.22322 = thread->threadpool_thread;
      if (D.22322 != 0) goto <D.22323>; else goto <D.22324>;
      <D.22323>:
      monoeg_g_string_append (text, "\n\"<threadpool thread>\"");
      goto <D.22325>;
      <D.22324>:
      monoeg_g_string_append (text, "\n\"<unnamed thread>\"");
      <D.22325>:
      <D.22321>:
      D.22326 = mono_get_eh_callbacks ();
      D.22327 = D.22326->mono_walk_stack_with_state;
      D.22328 = &info->suspend_state;
      D.22327 (print_stack_frame_to_string, D.22328, 0, text);
      D.22329 = info->node.key;
      mono_thread_info_resume (D.22329);
      stdout.102 = stdout;
      D.22331 = text->str;
      fprintf (stdout.102, "%s", D.22331);
      monoeg_g_string_free (text, 1);
      stdout.102 = stdout;
      fflush (stdout.102);
    }
  finally
    {
      error = {CLOBBER};
    }
}


__attribute__((__unused__))
print_stack_frame_to_string (struct MonoStackFrameInfo * frame, struct MonoContext * ctx, void * data)
{
  struct MonoJitInfo * D.22332;
  int D.22337;
  unsigned int D.22338;
  struct MonoDomain * D.22339;
  gboolean D.22341;
  struct GString * p;
  struct MonoMethod * method;

  p = data;
  method = 0B;
  D.22332 = frame->ji;
  if (D.22332 != 0B) goto <D.22333>; else goto <D.22334>;
  <D.22333>:
  D.22332 = frame->ji;
  method = mono_jit_info_get_method (D.22332);
  <D.22334>:
  if (method != 0B) goto <D.22335>; else goto <D.22336>;
  <D.22335>:
  {
    gchar * location;

    D.22337 = frame->native_offset;
    D.22338 = (unsigned int) D.22337;
    D.22339 = frame->domain;
    location = mono_debug_print_stack_frame (method, D.22338, D.22339);
    monoeg_g_string_append_printf (p, "  %s\n", location);
    monoeg_g_free (location);
  }
  goto <D.22340>;
  <D.22336>:
  D.22337 = frame->native_offset;
  monoeg_g_string_append_printf (p, "  at <unknown> <0x%05x>\n", D.22337);
  <D.22340>:
  D.22341 = 0;
  return D.22341;
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__))
fprintf (struct FILE * restrict __stream, const char * restrict __fmt)
{
  int D.22343;

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


__attribute__((__artificial__, __gnu_inline__, __always_inline__))
printf (const char * restrict __fmt)
{
  int D.22345;

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


mono_threads_request_thread_dump ()
{
  int D.22347;
  _Bool D.22352;
  long int D.22353;
  long int D.22354;
  struct MonoGHashTable * threads.103;
  _Bool D.22360;
  long int D.22361;
  long int D.22362;
  int D.22365;
  struct MonoInternalThread * D.22368;
  unsigned char D.22371;
  void * D.22374;
  unsigned int D.22375;
  unsigned int i.104;
  struct wait_data wait_data;
  struct wait_data * wait;
  int i;

  try
    {
      wait = &wait_data;
      D.22347 = mono_thread_info_new_interrupt_enabled ();
      if (D.22347 != 0) goto <D.22348>; else goto <D.22349>;
      <D.22348>:
      thread_dump_requested = 1;
      mono_gc_finalize_notify ();
      return;
      <D.22349>:
      memset (wait, 0, 1032);
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22350>; else goto <D.22351>;
        <D.22350>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22351>:
        D.22352 = ret != 0;
        D.22353 = (long int) D.22352;
        D.22354 = __builtin_expect (D.22353, 0);
        if (D.22354 != 0) goto <D.22355>; else goto <D.22356>;
        <D.22355>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3390, "ret == 0");
        <D.22356>:
      }
      threads.103 = threads;
      mono_g_hash_table_foreach (threads.103, collect_threads, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22358>; else goto <D.22359>;
        <D.22358>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22359>:
        D.22360 = ret != 0;
        D.22361 = (long int) D.22360;
        D.22362 = __builtin_expect (D.22361, 0);
        if (D.22362 != 0) goto <D.22363>; else goto <D.22364>;
        <D.22363>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3392, "ret == 0");
        <D.22364>:
      }
      i = 0;
      goto <D.19997>;
      <D.19996>:
      {
        struct MonoInternalThread * thread;

        thread = wait->threads[i];
        D.22365 = mono_gc_is_finalizer_internal_thread (thread);
        if (D.22365 == 0) goto <D.22366>; else goto <D.22367>;
        <D.22366>:
        D.22368 = mono_thread_internal_current ();
        if (D.22368 != thread) goto <D.22369>; else goto <D.22370>;
        <D.22369>:
        D.22371 = thread->thread_dump_requested;
        if (D.22371 == 0) goto <D.22372>; else goto <D.22373>;
        <D.22372>:
        thread->thread_dump_requested = 1;
        signal_thread_state_change (thread);
        <D.22373>:
        <D.22370>:
        <D.22367>:
        D.22374 = wait->handles[i];
        CloseHandle (D.22374);
      }
      i = i + 1;
      <D.19997>:
      D.22375 = wait->num;
      i.104 = (unsigned int) i;
      if (D.22375 > i.104) goto <D.19996>; else goto <D.19998>;
      <D.19998>:
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


collect_threads (void * key, void * value, void * user_data)
{
  unsigned int D.22380;
  long unsigned int D.22383;
  unsigned int D.22386;
  struct MonoInternalThread * thread;
  struct wait_data * wait;
  void * handle;

  thread = value;
  wait = user_data;
  D.22380 = wait->num;
  if (D.22380 <= 63) goto <D.22381>; else goto <D.22382>;
  <D.22381>:
  D.22383 = thread->tid;
  handle = OpenThread (2032639, 1, D.22383);
  if (handle == 0B) goto <D.22384>; else goto <D.22385>;
  <D.22384>:
  return;
  <D.22385>:
  D.22380 = wait->num;
  wait->handles[D.22380] = handle;
  D.22380 = wait->num;
  wait->threads[D.22380] = thread;
  D.22380 = wait->num;
  D.22386 = D.22380 + 1;
  wait->num = D.22386;
  <D.22382>:
}


__attribute__((visibility ("hidden")))
mono_thread_push_appdomain_ref (struct MonoDomain * domain)
{
  volatile int * D.22390;
  int D.22391;
  void * D.22393;
  struct RefStack * D.22396;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.22388>; else goto <D.22389>;
  <D.22388>:
  <D.20032>:
  D.22390 = &thread->lock_thread_id;
  D.22391 = InterlockedCompareExchange (D.22390, 1, 0);
  if (D.22391 == 0) goto <D.20031>; else goto <D.22392>;
  <D.22392>:
  goto <D.20032>;
  <D.20031>:
  D.22393 = thread->appdomain_refs;
  if (D.22393 == 0B) goto <D.22394>; else goto <D.22395>;
  <D.22394>:
  D.22396 = ref_stack_new (16);
  thread->appdomain_refs = D.22396;
  <D.22395>:
  D.22393 = thread->appdomain_refs;
  ref_stack_push (D.22393, domain);
  thread->lock_thread_id = 0;
  <D.22389>:
}


ref_stack_new (gint initial_size)
{
  int D.22397;
  long unsigned int D.22398;
  long unsigned int D.22399;
  void * D.22400;
  struct RefStack * D.22401;
  struct RefStack * rs;

  D.22397 = MAX_EXPR <initial_size, 16>;
  initial_size = D.22397 + 1;
  rs = monoeg_malloc0 (16);
  D.22398 = (long unsigned int) initial_size;
  D.22399 = D.22398 * 8;
  D.22400 = monoeg_malloc0 (D.22399);
  rs->refs = D.22400;
  rs->allocated = initial_size;
  D.22401 = rs;
  return D.22401;
}


ref_stack_push (struct RefStack * rs, void * ptr)
{
  _Bool D.22403;
  long int D.22404;
  long int D.22405;
  int D.22408;
  int D.22409;
  void * * D.22412;
  int D.22413;
  long unsigned int D.22414;
  long unsigned int D.22415;
  long unsigned int D.22416;
  void * D.22417;
  int D.22418;
  long unsigned int D.22419;
  long unsigned int D.22420;
  void * * D.22421;
  int D.22422;
  int D.22423;
  long unsigned int D.22424;
  long unsigned int D.22425;
  void * * D.22426;

  D.22403 = rs == 0B;
  D.22404 = (long int) D.22403;
  D.22405 = __builtin_expect (D.22404, 0);
  if (D.22405 != 0) goto <D.22406>; else goto <D.22407>;
  <D.22406>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3443, "rs != NULL");
  <D.22407>:
  D.22408 = rs->bottom;
  D.22409 = rs->allocated;
  if (D.22408 >= D.22409) goto <D.22410>; else goto <D.22411>;
  <D.22410>:
  D.22412 = rs->refs;
  D.22409 = rs->allocated;
  D.22413 = D.22409 * 2;
  D.22414 = (long unsigned int) D.22413;
  D.22415 = D.22414 * 8;
  D.22416 = D.22415 + 1;
  D.22417 = monoeg_realloc (D.22412, D.22416);
  rs->refs = D.22417;
  D.22409 = rs->allocated;
  D.22418 = D.22409 << 1;
  rs->allocated = D.22418;
  D.22412 = rs->refs;
  D.22409 = rs->allocated;
  D.22419 = (long unsigned int) D.22409;
  D.22420 = D.22419 * 8;
  D.22421 = D.22412 + D.22420;
  *D.22421 = 0B;
  <D.22411>:
  D.22412 = rs->refs;
  D.22408 = rs->bottom;
  D.22422 = D.22408;
  D.22423 = D.22422 + 1;
  rs->bottom = D.22423;
  D.22424 = (long unsigned int) D.22422;
  D.22425 = D.22424 * 8;
  D.22426 = D.22412 + D.22425;
  *D.22426 = ptr;
}


__attribute__((visibility ("hidden")))
mono_thread_pop_appdomain_ref ()
{
  volatile int * D.22429;
  int D.22430;
  void * D.22432;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.22427>; else goto <D.22428>;
  <D.22427>:
  <D.20038>:
  D.22429 = &thread->lock_thread_id;
  D.22430 = InterlockedCompareExchange (D.22429, 1, 0);
  if (D.22430 == 0) goto <D.20037>; else goto <D.22431>;
  <D.22431>:
  goto <D.20038>;
  <D.20037>:
  D.22432 = thread->appdomain_refs;
  ref_stack_pop (D.22432);
  thread->lock_thread_id = 0;
  <D.22428>:
}


ref_stack_pop (struct RefStack * rs)
{
  int D.22436;
  int D.22437;
  void * * D.22438;
  long unsigned int D.22439;
  long unsigned int D.22440;
  void * * D.22441;

  if (rs == 0B) goto <D.22433>; else goto <D.22435>;
  <D.22435>:
  D.22436 = rs->bottom;
  if (D.22436 == 0) goto <D.22433>; else goto <D.22434>;
  <D.22433>:
  return;
  <D.22434>:
  D.22436 = rs->bottom;
  D.22437 = D.22436 + -1;
  rs->bottom = D.22437;
  D.22438 = rs->refs;
  D.22436 = rs->bottom;
  D.22439 = (long unsigned int) D.22436;
  D.22440 = D.22439 * 8;
  D.22441 = D.22438 + D.22440;
  *D.22441 = 0B;
}


__attribute__((visibility ("hidden")))
mono_thread_internal_has_appdomain_ref (struct MonoInternalThread * thread, struct MonoDomain * domain)
{
  volatile int * D.22443;
  int D.22444;
  void * D.22446;
  gboolean D.22447;
  gboolean res;

  <D.20045>:
  D.22443 = &thread->lock_thread_id;
  D.22444 = InterlockedCompareExchange (D.22443, 1, 0);
  if (D.22444 == 0) goto <D.20044>; else goto <D.22445>;
  <D.22445>:
  goto <D.20045>;
  <D.20044>:
  D.22446 = thread->appdomain_refs;
  res = ref_stack_find (D.22446, domain);
  thread->lock_thread_id = 0;
  D.22447 = res;
  return D.22447;
}


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

  if (rs == 0B) goto <D.22449>; else goto <D.22450>;
  <D.22449>:
  D.22451 = 0;
  return D.22451;
  <D.22450>:
  refs = rs->refs;
  goto <D.20025>;
  <D.20024>:
  D.22452 = *refs;
  if (D.22452 == ptr) goto <D.22453>; else goto <D.22454>;
  <D.22453>:
  D.22451 = 1;
  return D.22451;
  <D.22454>:
  refs = refs + 8;
  <D.20025>:
  if (refs != 0B) goto <D.22455>; else goto <D.20026>;
  <D.22455>:
  D.22452 = *refs;
  if (D.22452 != 0B) goto <D.20024>; else goto <D.20026>;
  <D.20026>:
  D.22451 = 0;
  return D.22451;
}


__attribute__((visibility ("hidden")))
mono_thread_has_appdomain_ref (struct MonoThread * thread, struct MonoDomain * domain)
{
  gboolean D.22457;
  struct _MonoInternalThread * D.22458;

  D.22458 = thread->internal_thread;
  D.22457 = mono_thread_internal_has_appdomain_ref (D.22458, domain);
  return D.22457;
}


__attribute__((visibility ("hidden")))
mono_threads_abort_appdomain_threads (struct MonoDomain * domain, int timeout)
{
  _Bool D.22462;
  long int D.22463;
  long int D.22464;
  struct MonoGHashTable * threads.105;
  _Bool D.22470;
  long int D.22471;
  long int D.22472;
  unsigned int D.22475;
  struct MonoInternalThread * D.22478;
  unsigned int i.106;
  unsigned int D.22480;
  unsigned int D.22481;
  unsigned int timeout.107;
  unsigned int D.22483;
  gboolean D.22488;
  struct abort_appdomain_data user_data;
  guint32 start_time;
  int orig_timeout;
  int i;

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

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22460>; else goto <D.22461>;
        <D.22460>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22461>:
        D.22462 = ret != 0;
        D.22463 = (long int) D.22462;
        D.22464 = __builtin_expect (D.22463, 0);
        if (D.22464 != 0) goto <D.22465>; else goto <D.22466>;
        <D.22465>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3580, "ret == 0");
        <D.22466>:
      }
      user_data.domain = domain;
      user_data.wait.num = 0;
      threads.105 = threads;
      mono_g_hash_table_foreach (threads.105, collect_appdomain_thread, &user_data);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22468>; else goto <D.22469>;
        <D.22468>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22469>:
        D.22470 = ret != 0;
        D.22471 = (long int) D.22470;
        D.22472 = __builtin_expect (D.22471, 0);
        if (D.22472 != 0) goto <D.22473>; else goto <D.22474>;
        <D.22473>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3586, "ret == 0");
        <D.22474>:
      }
      D.22475 = user_data.wait.num;
      if (D.22475 != 0) goto <D.22476>; else goto <D.22477>;
      <D.22476>:
      i = 0;
      goto <D.20074>;
      <D.20073>:
      D.22478 = user_data.wait.threads[i];
      ves_icall_System_Threading_Thread_Abort (D.22478, 0B);
      i = i + 1;
      <D.20074>:
      D.22475 = user_data.wait.num;
      i.106 = (unsigned int) i;
      if (D.22475 > i.106) goto <D.20073>; else goto <D.20075>;
      <D.20075>:
      wait_for_tids (&user_data.wait, 100);
      <D.22477>:
      D.22480 = mono_msec_ticks ();
      D.22481 = D.22480 - start_time;
      timeout.107 = (unsigned int) timeout;
      D.22483 = timeout.107 - D.22481;
      timeout = (int) D.22483;
      start_time = mono_msec_ticks ();
      if (orig_timeout != -1) goto <D.22484>; else goto <D.22485>;
      <D.22484>:
      if (timeout < 0) goto <D.22486>; else goto <D.22487>;
      <D.22486>:
      D.22488 = 0;
      return D.22488;
      <D.22487>:
      <D.22485>:
      D.22475 = user_data.wait.num;
      if (D.22475 != 0) goto <D.20076>; else goto <D.20077>;
      <D.20077>:
      D.22488 = 1;
      return D.22488;
    }
  finally
    {
      user_data = {CLOBBER};
    }
}


collect_appdomain_thread (void * key, void * value, void * user_data)
{
  int D.22491;
  unsigned int D.22494;
  long unsigned int D.22497;
  unsigned int D.22500;
  struct MonoInternalThread * thread;
  struct abort_appdomain_data * data;
  struct MonoDomain * domain;

  thread = value;
  data = user_data;
  domain = data->domain;
  D.22491 = mono_thread_internal_has_appdomain_ref (thread, domain);
  if (D.22491 != 0) goto <D.22492>; else goto <D.22493>;
  <D.22492>:
  D.22494 = data->wait.num;
  if (D.22494 <= 63) goto <D.22495>; else goto <D.22496>;
  <D.22495>:
  {
    void * handle;

    D.22497 = thread->tid;
    handle = OpenThread (2032639, 1, D.22497);
    if (handle == 0B) goto <D.22498>; else goto <D.22499>;
    <D.22498>:
    return;
    <D.22499>:
    D.22494 = data->wait.num;
    data->wait.handles[D.22494] = handle;
    D.22494 = data->wait.num;
    data->wait.threads[D.22494] = thread;
    D.22494 = data->wait.num;
    D.22500 = D.22494 + 1;
    data->wait.num = D.22500;
  }
  goto <D.22501>;
  <D.22496>:
  <D.22501>:
  <D.22493>:
}


__attribute__((visibility ("hidden")))
mono_threads_clear_cached_culture (struct MonoDomain * domain)
{
  _Bool D.22505;
  long int D.22506;
  long int D.22507;
  struct MonoGHashTable * threads.108;
  _Bool D.22513;
  long int D.22514;
  long int D.22515;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22503>; else goto <D.22504>;
    <D.22503>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22504>:
    D.22505 = ret != 0;
    D.22506 = (long int) D.22505;
    D.22507 = __builtin_expect (D.22506, 0);
    if (D.22507 != 0) goto <D.22508>; else goto <D.22509>;
    <D.22508>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3642, "ret == 0");
    <D.22509>:
  }
  threads.108 = threads;
  mono_g_hash_table_foreach (threads.108, clear_cached_culture, domain);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22511>; else goto <D.22512>;
    <D.22511>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22512>:
    D.22513 = ret != 0;
    D.22514 = (long int) D.22513;
    D.22515 = __builtin_expect (D.22514, 0);
    if (D.22515 != 0) goto <D.22516>; else goto <D.22517>;
    <D.22516>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3644, "ret == 0");
    <D.22517>:
  }
}


clear_cached_culture (void * key, void * value, void * user_data)
{
  struct MonoArray * D.22518;
  long unsigned int D.22521;
  char * D.22522;
  struct MonoVTable * D.22525;
  struct MonoDomain * D.22526;
  struct MonoInternalThread * thread;
  struct MonoDomain * domain;
  int i;

  thread = value;
  domain = user_data;
  D.22518 = thread->cached_culture_info;
  if (D.22518 != 0B) goto <D.22519>; else goto <D.22520>;
  <D.22519>:
  i = 0;
  goto <D.20089>;
  <D.20088>:
  {
    struct MonoObject * obj;

    D.22518 = thread->cached_culture_info;
    D.22521 = (long unsigned int) i;
    D.22522 = mono_array_addr_with_size (D.22518, 8, D.22521);
    obj = MEM[(struct MonoObject * *)D.22522];
    if (obj != 0B) goto <D.22523>; else goto <D.22524>;
    <D.22523>:
    D.22525 = obj->vtable;
    D.22526 = D.22525->domain;
    if (D.22526 == domain) goto <D.22527>; else goto <D.22528>;
    <D.22527>:
    {
      struct MonoObject * * __p;

      D.22518 = thread->cached_culture_info;
      D.22521 = (long unsigned int) i;
      __p = mono_array_addr_with_size (D.22518, 8, D.22521);
      *__p = 0B;
    }
    <D.22528>:
    <D.22524>:
  }
  i = i + 1;
  <D.20089>:
  if (i <= 7) goto <D.20088>; else goto <D.20090>;
  <D.20090>:
  <D.22520>:
}


mono_thread_get_undeniable_exception ()
{
  struct MonoException * D.22531;
  int D.22534;
  struct MonoException * D.22537;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.22529>; else goto <D.22530>;
  <D.22529>:
  D.22531 = thread->abort_exc;
  if (D.22531 != 0B) goto <D.22532>; else goto <D.22533>;
  <D.22532>:
  D.22534 = is_running_protected_wrapper ();
  if (D.22534 == 0) goto <D.22535>; else goto <D.22536>;
  <D.22535>:
  D.22531 = thread->abort_exc;
  D.22531->trace_ips = 0B;
  D.22531 = thread->abort_exc;
  D.22531->stack_trace = 0B;
  D.22537 = thread->abort_exc;
  return D.22537;
  <D.22536>:
  <D.22533>:
  <D.22530>:
  D.22537 = 0B;
  return D.22537;
}


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

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


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

  if (managed != 0) goto <D.22542>; else goto <D.22543>;
  <D.22542>:
  D.22544 = 1;
  return D.22544;
  <D.22543>:
  D.22545 = mono_threads_is_critical_method (m);
  if (D.22545 != 0) goto <D.22546>; else goto <D.22547>;
  <D.22546>:
  MEM[(gboolean *)data] = 1;
  D.22544 = 1;
  return D.22544;
  <D.22547>:
  D.22544 = 0;
  return D.22544;
}


__attribute__((visibility ("hidden")))
mono_alloc_special_static_data (guint32 static_type, guint32 size, guint32 align, uintptr_t * bitmap, int numbits)
{
  _Bool D.22553;
  long int D.22554;
  long int D.22555;
  struct MonoGHashTable * threads.109;
  long unsigned int D.22564;
  void * D.22565;
  _Bool D.22568;
  long int D.22569;
  long int D.22570;
  _Bool D.22574;
  long int D.22575;
  long int D.22576;
  _Bool D.22581;
  long int D.22582;
  long int D.22583;
  _Bool D.22588;
  long int D.22589;
  long int D.22590;
  uint32_t D.22593;
  guint32 offset;

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

    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22551>; else goto <D.22552>;
      <D.22551>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22552>:
      D.22553 = ret != 0;
      D.22554 = (long int) D.22553;
      D.22555 = __builtin_expect (D.22554, 0);
      if (D.22555 != 0) goto <D.22556>; else goto <D.22557>;
      <D.22556>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3902, "ret == 0");
      <D.22557>:
    }
    item = search_tls_slot_in_freelist (&thread_static_info, size, align);
    if (item != 0B) goto <D.22558>; else goto <D.22559>;
    <D.22558>:
    offset = item->offset;
    monoeg_g_free (item);
    goto <D.22560>;
    <D.22559>:
    offset = mono_alloc_static_data_slot (&thread_static_info, size, align);
    <D.22560>:
    update_tls_reference_bitmap (offset, bitmap, numbits);
    threads.109 = threads;
    if (threads.109 != 0B) goto <D.22562>; else goto <D.22563>;
    <D.22562>:
    threads.109 = threads;
    D.22564 = (long unsigned int) offset;
    D.22565 = (void *) D.22564;
    mono_g_hash_table_foreach (threads.109, alloc_thread_static_data_helper, D.22565);
    <D.22563>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22566>; else goto <D.22567>;
      <D.22566>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22567>:
      D.22568 = ret != 0;
      D.22569 = (long int) D.22568;
      D.22570 = __builtin_expect (D.22569, 0);
      if (D.22570 != 0) goto <D.22571>; else goto <D.22572>;
      <D.22571>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3915, "ret == 0");
      <D.22572>:
    }
  }
  goto <D.22573>;
  <D.22550>:
  D.22574 = static_type != 2;
  D.22575 = (long int) D.22574;
  D.22576 = __builtin_expect (D.22575, 0);
  if (D.22576 != 0) goto <D.22577>; else goto <D.22578>;
  <D.22577>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3917, "static_type == SPECIAL_STATIC_CONTEXT");
  <D.22578>:
  {
    int ret;

    ret = pthread_mutex_lock (&contexts_mutex.mutex);
    if (ret != 0) goto <D.22579>; else goto <D.22580>;
    <D.22579>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22580>:
    D.22581 = ret != 0;
    D.22582 = (long int) D.22581;
    D.22583 = __builtin_expect (D.22582, 0);
    if (D.22583 != 0) goto <D.22584>; else goto <D.22585>;
    <D.22584>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3918, "ret == 0");
    <D.22585>:
  }
  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.22586>; else goto <D.22587>;
    <D.22586>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22587>:
    D.22588 = ret != 0;
    D.22589 = (long int) D.22588;
    D.22590 = __builtin_expect (D.22589, 0);
    if (D.22590 != 0) goto <D.22591>; else goto <D.22592>;
    <D.22591>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3920, "ret == 0");
    <D.22592>:
  }
  offset = offset | 2147483648;
  <D.22573>:
  D.22593 = offset;
  return D.22593;
}


alloc_thread_static_data_helper (void * key, void * value, void * user)
{
  long int user.110;
  void * * * D.22596;
  struct MonoInternalThread * thread;
  guint32 offset;

  thread = value;
  user.110 = (long int) user;
  offset = (guint32) user.110;
  D.22596 = &thread->static_data;
  mono_alloc_static_data (D.22596, offset, 1);
}


search_tls_slot_in_freelist (struct StaticDataInfo * static_data, guint32 size, guint32 align)
{
  unsigned int D.22597;
  struct MonoThreadDomainTls * D.22602;
  struct MonoThreadDomainTls * D.22604;
  struct MonoThreadDomainTls * prev;
  struct MonoThreadDomainTls * tmp;

  prev = 0B;
  tmp = static_data->freelist;
  goto <D.20176>;
  <D.20175>:
  D.22597 = tmp->size;
  if (D.22597 == size) goto <D.22598>; else goto <D.22599>;
  <D.22598>:
  if (prev != 0B) goto <D.22600>; else goto <D.22601>;
  <D.22600>:
  D.22602 = tmp->next;
  prev->next = D.22602;
  goto <D.22603>;
  <D.22601>:
  D.22602 = tmp->next;
  static_data->freelist = D.22602;
  <D.22603>:
  D.22604 = tmp;
  return D.22604;
  <D.22599>:
  tmp = tmp->next;
  <D.20176>:
  if (tmp != 0B) goto <D.20175>; else goto <D.20177>;
  <D.20177>:
  D.22604 = 0B;
  return D.22604;
}


update_tls_reference_bitmap (guint32 offset, uintptr_t * bitmap, int numbits)
{
  unsigned int D.22606;
  unsigned int D.22607;
  uintptr_t * D.22608;
  int D.22611;
  long unsigned int D.22612;
  long unsigned int D.22613;
  long unsigned int D.22614;
  long unsigned int D.22615;
  void * D.22616;
  sizetype D.22617;
  sizetype D.22618;
  uintptr_t * D.22619;
  long unsigned int D.22620;
  unsigned int i.111;
  unsigned int D.22622;
  long int D.22623;
  long unsigned int D.22624;
  long unsigned int D.22625;
  unsigned int i.112;
  unsigned int D.22629;
  unsigned int D.22630;
  long unsigned int D.22631;
  long unsigned int D.22632;
  uintptr_t * D.22633;
  long unsigned int D.22634;
  unsigned int D.22635;
  long int D.22636;
  long unsigned int D.22637;
  long unsigned int D.22638;
  int i;
  int idx;
  uintptr_t * rb;

  D.22606 = offset >> 24;
  D.22607 = D.22606 + 4294967295;
  idx = (int) D.22607;
  D.22608 = static_reference_bitmaps[idx];
  if (D.22608 == 0B) goto <D.22609>; else goto <D.22610>;
  <D.22609>:
  D.22611 = static_data_size[idx];
  D.22612 = (long unsigned int) D.22611;
  D.22613 = D.22612 / 512;
  D.22614 = D.22613 + 1;
  D.22615 = D.22614 * 8;
  D.22616 = monoeg_malloc0 (D.22615);
  static_reference_bitmaps[idx] = D.22616;
  <D.22610>:
  rb = static_reference_bitmaps[idx];
  offset = offset & 16777215;
  offset = offset / 8;
  i = 0;
  goto <D.20187>;
  <D.20186>:
  D.22617 = (sizetype) i;
  D.22618 = D.22617 & 18446744073709551608;
  D.22619 = bitmap + D.22618;
  D.22620 = *D.22619;
  i.111 = (unsigned int) i;
  D.22622 = i.111 & 63;
  D.22623 = 1 << D.22622;
  D.22624 = (long unsigned int) D.22623;
  D.22625 = D.22620 & D.22624;
  if (D.22625 != 0) goto <D.22626>; else goto <D.22627>;
  <D.22626>:
  i.112 = (unsigned int) i;
  D.22629 = offset + i.112;
  D.22630 = D.22629 / 64;
  D.22631 = (long unsigned int) D.22630;
  D.22632 = D.22631 * 8;
  D.22633 = rb + D.22632;
  D.22631 = (long unsigned int) D.22630;
  D.22632 = D.22631 * 8;
  D.22633 = rb + D.22632;
  D.22634 = *D.22633;
  i.112 = (unsigned int) i;
  D.22629 = offset + i.112;
  D.22635 = D.22629 & 63;
  D.22636 = 1 << D.22635;
  D.22637 = (long unsigned int) D.22636;
  D.22638 = D.22634 | D.22637;
  *D.22633 = D.22638;
  <D.22627>:
  i = i + 1;
  <D.20187>:
  if (i < numbits) goto <D.20186>; else goto <D.20188>;
  <D.20188>:
}


mono_alloc_static_data_slot (struct StaticDataInfo * static_data, guint32 size, guint32 align)
{
  signed long D.22639;
  long unsigned int D.22640;
  long unsigned int D.22641;
  int D.22644;
  unsigned int D.22645;
  unsigned int D.22646;
  unsigned int D.22647;
  int D.22648;
  unsigned int D.22649;
  unsigned int D.22650;
  int D.22651;
  unsigned int D.22652;
  int D.22653;
  int D.22654;
  unsigned int D.22655;
  int D.22658;
  _Bool D.22659;
  long int D.22660;
  long int D.22661;
  _Bool D.22664;
  long int D.22665;
  long int D.22666;
  int D.22669;
  int D.22670;
  int D.22671;
  guint32 D.22672;
  guint32 offset;

  D.22639 = BIT_FIELD_REF <*static_data, 64, 0>;
  D.22640 = (long unsigned int) D.22639;
  D.22641 = D.22640;
  if (D.22641 == 0) goto <D.22642>; else goto <D.22643>;
  <D.22642>:
  static_data->offset = 64;
  <D.22643>:
  D.22644 = static_data->offset;
  D.22645 = (unsigned int) D.22644;
  D.22646 = D.22645 + align;
  D.22647 = D.22646 + 4294967295;
  D.22648 = (int) D.22647;
  static_data->offset = D.22648;
  D.22644 = static_data->offset;
  D.22645 = (unsigned int) D.22644;
  D.22649 = -align;
  D.22650 = D.22645 & D.22649;
  D.22651 = (int) D.22650;
  static_data->offset = D.22651;
  D.22644 = static_data->offset;
  D.22645 = (unsigned int) D.22644;
  D.22652 = D.22645 + size;
  D.22653 = static_data->idx;
  D.22654 = static_data_size[D.22653];
  D.22655 = (unsigned int) D.22654;
  if (D.22652 >= D.22655) goto <D.22656>; else goto <D.22657>;
  <D.22656>:
  D.22653 = static_data->idx;
  D.22658 = D.22653 + 1;
  static_data->idx = D.22658;
  D.22653 = static_data->idx;
  D.22654 = static_data_size[D.22653];
  D.22655 = (unsigned int) D.22654;
  D.22659 = D.22655 < size;
  D.22660 = (long int) D.22659;
  D.22661 = __builtin_expect (D.22660, 0);
  if (D.22661 != 0) goto <D.22662>; else goto <D.22663>;
  <D.22662>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3801, "size <= static_data_size [static_data->idx]");
  <D.22663>:
  D.22653 = static_data->idx;
  D.22664 = D.22653 > 7;
  D.22665 = (long int) D.22664;
  D.22666 = __builtin_expect (D.22665, 0);
  if (D.22666 != 0) goto <D.22667>; else goto <D.22668>;
  <D.22667>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3802, "static_data->idx < NUM_STATIC_DATA_IDX");
  <D.22668>:
  static_data->offset = 0;
  <D.22657>:
  D.22644 = static_data->offset;
  D.22653 = static_data->idx;
  D.22658 = D.22653 + 1;
  D.22669 = D.22658 << 24;
  D.22670 = D.22644 | D.22669;
  offset = (guint32) D.22670;
  D.22644 = static_data->offset;
  D.22645 = (unsigned int) D.22644;
  D.22652 = D.22645 + size;
  D.22671 = (int) D.22652;
  static_data->offset = D.22671;
  D.22672 = offset;
  return D.22672;
}


__attribute__((visibility ("hidden")))
mono_get_special_static_data_for_thread (struct MonoInternalThread * thread, guint32 offset)
{
  unsigned int D.22674;
  unsigned int D.22675;
  void * D.22678;
  void * * D.22681;
  long unsigned int D.22683;
  long unsigned int D.22684;
  void * * D.22685;
  void * D.22686;
  _Bool D.22689;
  long int D.22690;
  long int D.22691;
  void * * * D.22694;
  _Bool D.22697;
  long int D.22698;
  long int D.22699;
  sizetype D.22702;
  sizetype D.22703;
  guint32 static_type;
  int idx;

  static_type = offset & 2147483648;
  offset = offset & 2147483647;
  D.22674 = offset >> 24;
  D.22675 = D.22674 + 4294967295;
  idx = (int) D.22675;
  if (static_type == 0) goto <D.22676>; else goto <D.22677>;
  <D.22676>:
  D.22678 = get_thread_static_data (thread, offset);
  return D.22678;
  <D.22677>:
  {
    struct MonoAppContext * context;

    context = mono_context_get ();
    D.22681 = context->static_data;
    if (D.22681 == 0B) goto <D.22679>; else goto <D.22682>;
    <D.22682>:
    D.22681 = context->static_data;
    D.22683 = (long unsigned int) idx;
    D.22684 = D.22683 * 8;
    D.22685 = D.22681 + D.22684;
    D.22686 = *D.22685;
    if (D.22686 == 0B) goto <D.22679>; else goto <D.22680>;
    <D.22679>:
    {
      int ret;

      ret = pthread_mutex_lock (&contexts_mutex.mutex);
      if (ret != 0) goto <D.22687>; else goto <D.22688>;
      <D.22687>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22688>:
      D.22689 = ret != 0;
      D.22690 = (long int) D.22689;
      D.22691 = __builtin_expect (D.22690, 0);
      if (D.22691 != 0) goto <D.22692>; else goto <D.22693>;
      <D.22692>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3945, "ret == 0");
      <D.22693>:
    }
    D.22694 = &context->static_data;
    mono_alloc_static_data (D.22694, offset, 0);
    {
      int ret;

      ret = pthread_mutex_unlock (&contexts_mutex.mutex);
      if (ret != 0) goto <D.22695>; else goto <D.22696>;
      <D.22695>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22696>:
      D.22697 = ret != 0;
      D.22698 = (long int) D.22697;
      D.22699 = __builtin_expect (D.22698, 0);
      if (D.22699 != 0) goto <D.22700>; else goto <D.22701>;
      <D.22700>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3947, "ret == 0");
      <D.22701>:
    }
    <D.22680>:
    D.22681 = context->static_data;
    D.22683 = (long unsigned int) idx;
    D.22684 = D.22683 * 8;
    D.22685 = D.22681 + D.22684;
    D.22686 = *D.22685;
    D.22702 = (sizetype) offset;
    D.22703 = D.22702 & 16777215;
    D.22678 = D.22686 + D.22703;
    return D.22678;
  }
}


__attribute__((visibility ("hidden")))
mono_get_special_static_data (guint32 offset)
{
  void * D.22705;
  struct MonoInternalThread * D.22706;

  D.22706 = mono_thread_internal_current ();
  D.22705 = mono_get_special_static_data_for_thread (D.22706, offset);
  return D.22705;
}


__attribute__((visibility ("hidden")))
mono_alloc_special_static_data_free (struct GHashTable * special_static_fields)
{
  _Bool D.22710;
  long int D.22711;
  long int D.22712;
  _Bool D.22717;
  long int D.22718;
  long int D.22719;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22708>; else goto <D.22709>;
    <D.22708>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22709>:
    D.22710 = ret != 0;
    D.22711 = (long int) D.22710;
    D.22712 = __builtin_expect (D.22711, 0);
    if (D.22712 != 0) goto <D.22713>; else goto <D.22714>;
    <D.22713>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4020, "ret == 0");
    <D.22714>:
  }
  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.22715>; else goto <D.22716>;
    <D.22715>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22716>:
    D.22717 = ret != 0;
    D.22718 = (long int) D.22717;
    D.22719 = __builtin_expect (D.22718, 0);
    if (D.22719 != 0) goto <D.22720>; else goto <D.22721>;
    <D.22720>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4022, "ret == 0");
    <D.22721>:
  }
}


do_free_special (void * key, void * value, void * data)
{
  long int value.113;
  struct MonoType * D.22723;
  int D.22724;
  struct MonoClassField * field;
  guint32 offset;
  gint32 align;
  guint32 size;

  try
    {
      field = key;
      value.113 = (long int) value;
      offset = (guint32) value.113;
      D.22723 = field->type;
      D.22724 = mono_type_size (D.22723, &align);
      size = (guint32) D.22724;
      do_free_special_slot (offset, size);
    }
  finally
    {
      align = {CLOBBER};
    }
}


do_free_special_slot (guint32 offset, guint32 size)
{
  unsigned int D.22727;
  unsigned int D.22728;
  unsigned int D.22729;
  struct MonoGHashTable * threads.114;
  int D.22733;
  struct MonoThreadDomainTls * D.22736;
  guint32 static_type;

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

    try
      {
        item = monoeg_malloc0 (16);
        D.22727 = offset & 2147483647;
        data.offset = D.22727;
        data.size = size;
        D.22728 = data.offset;
        D.22729 = data.size;
        clear_reference_bitmap (D.22728, D.22729);
        threads.114 = threads;
        if (threads.114 != 0B) goto <D.22731>; else goto <D.22732>;
        <D.22731>:
        threads.114 = threads;
        mono_g_hash_table_foreach (threads.114, free_thread_static_data_helper, &data);
        <D.22732>:
        item->offset = offset;
        item->size = size;
        D.22733 = mono_runtime_is_shutting_down ();
        if (D.22733 == 0) goto <D.22734>; else goto <D.22735>;
        <D.22734>:
        D.22736 = thread_static_info.freelist;
        item->next = D.22736;
        thread_static_info.freelist = item;
        goto <D.22737>;
        <D.22735>:
        monoeg_g_free (item);
        <D.22737>:
      }
    finally
      {
        data = {CLOBBER};
      }
  }
  goto <D.22738>;
  <D.22726>:
  <D.22738>:
}


free_thread_static_data_helper (void * key, void * value, void * user)
{
  unsigned int D.22739;
  unsigned int D.22740;
  unsigned int D.22741;
  void * * D.22744;
  long unsigned int D.22746;
  long unsigned int D.22747;
  void * * D.22748;
  void * D.22749;
  sizetype D.22750;
  sizetype D.22751;
  unsigned int D.22752;
  long unsigned int D.22753;
  struct MonoInternalThread * thread;
  struct TlsOffsetSize * data;
  int idx;
  char * ptr;

  thread = value;
  data = user;
  D.22739 = data->offset;
  D.22740 = D.22739 >> 24;
  D.22741 = D.22740 + 4294967295;
  idx = (int) D.22741;
  D.22744 = thread->static_data;
  if (D.22744 == 0B) goto <D.22742>; else goto <D.22745>;
  <D.22745>:
  D.22744 = thread->static_data;
  D.22746 = (long unsigned int) idx;
  D.22747 = D.22746 * 8;
  D.22748 = D.22744 + D.22747;
  D.22749 = *D.22748;
  if (D.22749 == 0B) goto <D.22742>; else goto <D.22743>;
  <D.22742>:
  return;
  <D.22743>:
  D.22744 = thread->static_data;
  D.22746 = (long unsigned int) idx;
  D.22747 = D.22746 * 8;
  D.22748 = D.22744 + D.22747;
  D.22749 = *D.22748;
  D.22739 = data->offset;
  D.22750 = (sizetype) D.22739;
  D.22751 = D.22750 & 16777215;
  ptr = D.22749 + D.22751;
  D.22752 = data->size;
  D.22753 = (long unsigned int) D.22752;
  mono_gc_bzero_atomic (ptr, D.22753);
}


clear_reference_bitmap (guint32 offset, guint32 size)
{
  unsigned int D.22755;
  unsigned int D.22756;
  unsigned int D.22757;
  long unsigned int D.22758;
  long unsigned int D.22759;
  uintptr_t * D.22760;
  long unsigned int D.22761;
  unsigned int D.22762;
  long int D.22763;
  long int D.22764;
  long unsigned int D.22765;
  long unsigned int D.22766;
  int idx;
  uintptr_t * rb;

  D.22755 = offset >> 24;
  D.22756 = D.22755 + 4294967295;
  idx = (int) D.22756;
  rb = static_reference_bitmaps[idx];
  offset = offset & 16777215;
  offset = offset / 8;
  size = size / 8;
  size = size + offset;
  goto <D.20196>;
  <D.20195>:
  D.22757 = offset / 64;
  D.22758 = (long unsigned int) D.22757;
  D.22759 = D.22758 * 8;
  D.22760 = rb + D.22759;
  D.22758 = (long unsigned int) D.22757;
  D.22759 = D.22758 * 8;
  D.22760 = rb + D.22759;
  D.22761 = *D.22760;
  D.22762 = offset & 63;
  D.22763 = 1 << D.22762;
  D.22764 = ~D.22763;
  D.22765 = (long unsigned int) D.22764;
  D.22766 = D.22761 & D.22765;
  *D.22760 = D.22766;
  offset = offset + 1;
  <D.20196>:
  if (offset < size) goto <D.20195>; else goto <D.20197>;
  <D.20197>:
}


__attribute__((visibility ("hidden")))
mono_special_static_data_free_slot (guint32 offset, guint32 size)
{
  _Bool D.22769;
  long int D.22770;
  long int D.22771;
  _Bool D.22776;
  long int D.22777;
  long int D.22778;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22767>; else goto <D.22768>;
    <D.22767>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22768>:
    D.22769 = ret != 0;
    D.22770 = (long int) D.22769;
    D.22771 = __builtin_expect (D.22770, 0);
    if (D.22771 != 0) goto <D.22772>; else goto <D.22773>;
    <D.22772>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4028, "ret == 0");
    <D.22773>:
  }
  do_free_special_slot (offset, size);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22774>; else goto <D.22775>;
    <D.22774>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22775>:
    D.22776 = ret != 0;
    D.22777 = (long int) D.22776;
    D.22778 = __builtin_expect (D.22777, 0);
    if (D.22778 != 0) goto <D.22779>; else goto <D.22780>;
    <D.22779>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4030, "ret == 0");
    <D.22780>:
  }
}


__attribute__((visibility ("hidden")))
mono_thread_alloc_tls (struct MonoReflectionType * type)
{
  struct MonoType * D.22781;
  int D.22782;
  int align.115;
  unsigned int align.116;
  int max_set.117;
  int D.22786;
  union mono_mutex_t * D.22789;
  _Bool D.22792;
  long int D.22793;
  long int D.22794;
  struct MonoTlsDataRecord * D.22797;
  _Bool D.22800;
  long int D.22801;
  long int D.22802;
  uint32_t D.22805;
  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.22781 = type->type;
      klass = mono_class_from_mono_type (D.22781);
      bitmap = mono_class_compute_bitmap (klass, &default_bitmap, 256, -2, &max_set, 0);
      D.22781 = type->type;
      D.22782 = mono_type_size (D.22781, &align);
      size = (guint32) D.22782;
      align.115 = align;
      align.116 = (unsigned int) align.115;
      max_set.117 = max_set;
      D.22786 = max_set.117 + 1;
      tls_offset = mono_alloc_special_static_data (1, size, align.116, bitmap, D.22786);
      if (&default_bitmap != bitmap) goto <D.22787>; else goto <D.22788>;
      <D.22787>:
      monoeg_g_free (bitmap);
      <D.22788>:
      tlsrec = monoeg_malloc0 (16);
      tlsrec->tls_offset = tls_offset;
      tlsrec->size = size;
      {
        int ret;

        D.22789 = &domain->lock.mutex;
        ret = pthread_mutex_lock (D.22789);
        if (ret != 0) goto <D.22790>; else goto <D.22791>;
        <D.22790>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22791>:
        D.22792 = ret != 0;
        D.22793 = (long int) D.22792;
        D.22794 = __builtin_expect (D.22793, 0);
        if (D.22794 != 0) goto <D.22795>; else goto <D.22796>;
        <D.22795>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4060, "ret == 0");
        <D.22796>:
      }
      D.22797 = domain->tlsrec_list;
      tlsrec->next = D.22797;
      domain->tlsrec_list = tlsrec;
      {
        int ret;

        D.22789 = &domain->lock.mutex;
        ret = pthread_mutex_unlock (D.22789);
        if (ret != 0) goto <D.22798>; else goto <D.22799>;
        <D.22798>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22799>:
        D.22800 = ret != 0;
        D.22801 = (long int) D.22800;
        D.22802 = __builtin_expect (D.22801, 0);
        if (D.22802 != 0) goto <D.22803>; else goto <D.22804>;
        <D.22803>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4063, "ret == 0");
        <D.22804>:
      }
      D.22805 = tls_offset;
      return D.22805;
    }
  finally
    {
      max_set = {CLOBBER};
      default_bitmap = {CLOBBER};
      align = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
mono_thread_destroy_tls (uint32_t tls_offset)
{
  union mono_mutex_t * D.22808;
  _Bool D.22811;
  long int D.22812;
  long int D.22813;
  unsigned int D.22816;
  struct MonoTlsDataRecord * D.22821;
  _Bool D.22825;
  long int D.22826;
  long int D.22827;
  struct MonoTlsDataRecord * prev;
  struct MonoTlsDataRecord * cur;
  guint32 size;
  struct MonoDomain * domain;

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

    D.22808 = &domain->lock.mutex;
    ret = pthread_mutex_lock (D.22808);
    if (ret != 0) goto <D.22809>; else goto <D.22810>;
    <D.22809>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22810>:
    D.22811 = ret != 0;
    D.22812 = (long int) D.22811;
    D.22813 = __builtin_expect (D.22812, 0);
    if (D.22813 != 0) goto <D.22814>; else goto <D.22815>;
    <D.22814>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4074, "ret == 0");
    <D.22815>:
  }
  cur = domain->tlsrec_list;
  goto <D.20287>;
  <D.20286>:
  D.22816 = cur->tls_offset;
  if (D.22816 == tls_offset) goto <D.22817>; else goto <D.22818>;
  <D.22817>:
  if (prev != 0B) goto <D.22819>; else goto <D.22820>;
  <D.22819>:
  D.22821 = cur->next;
  prev->next = D.22821;
  goto <D.22822>;
  <D.22820>:
  D.22821 = cur->next;
  domain->tlsrec_list = D.22821;
  <D.22822>:
  size = cur->size;
  monoeg_g_free (cur);
  goto <D.20285>;
  <D.22818>:
  prev = cur;
  cur = cur->next;
  <D.20287>:
  if (cur != 0B) goto <D.20286>; else goto <D.20285>;
  <D.20285>:
  {
    int ret;

    D.22808 = &domain->lock.mutex;
    ret = pthread_mutex_unlock (D.22808);
    if (ret != 0) goto <D.22823>; else goto <D.22824>;
    <D.22823>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22824>:
    D.22825 = ret != 0;
    D.22826 = (long int) D.22825;
    D.22827 = __builtin_expect (D.22826, 0);
    if (D.22827 != 0) goto <D.22828>; else goto <D.22829>;
    <D.22828>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4089, "ret == 0");
    <D.22829>:
  }
  if (size != 0) goto <D.22830>; else goto <D.22831>;
  <D.22830>:
  mono_special_static_data_free_slot (tls_offset, size);
  <D.22831>:
}


__attribute__((visibility ("hidden")))
mono_thread_destroy_domain_tls (struct MonoDomain * domain)
{
  struct MonoTlsDataRecord * D.22832;
  unsigned int D.22833;

  goto <D.20293>;
  <D.20292>:
  D.22832 = domain->tlsrec_list;
  D.22833 = D.22832->tls_offset;
  mono_thread_destroy_tls (D.22833);
  <D.20293>:
  D.22832 = domain->tlsrec_list;
  if (D.22832 != 0B) goto <D.20292>; else goto <D.20294>;
  <D.20294>:
}


__attribute__((visibility ("hidden")))
mono_thread_free_local_slot_values (int slot, MonoBoolean thread_local)
{
  struct MonoClassField * local_slots.118;
  struct MonoClass * D.22839;
  struct MonoClassField * D.22840;
  union mono_mutex_t * D.22843;
  _Bool D.22846;
  long int D.22847;
  long int D.22848;
  struct GHashTable * D.22851;
  _Bool D.22856;
  long int D.22857;
  long int D.22858;
  long int addr.119;
  unsigned int D.22864;
  unsigned int D.22865;
  unsigned int D.22866;
  unsigned int D.22867;
  unsigned int D.22868;
  int D.22869;
  _Bool D.22872;
  long int D.22873;
  long int D.22874;
  struct MonoGHashTable * threads.120;
  _Bool D.22880;
  long int D.22881;
  long int D.22882;
  struct MonoDomain * domain;
  struct LocalSlotID sid;

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

        addr = 0B;
        local_slots.118 = local_slots;
        if (local_slots.118 == 0B) goto <D.22837>; else goto <D.22838>;
        <D.22837>:
        D.22839 = mono_defaults.thread_class;
        D.22840 = mono_class_get_field_from_name (D.22839, "local_slots");
        local_slots = D.22840;
        local_slots.118 = local_slots;
        if (local_slots.118 == 0B) goto <D.22841>; else goto <D.22842>;
        <D.22841>:
        monoeg_g_log (0B, 16, "local_slots field not found in Thread class");
        return;
        <D.22842>:
        <D.22838>:
        domain = mono_domain_get ();
        {
          int ret;

          D.22843 = &domain->lock.mutex;
          ret = pthread_mutex_lock (D.22843);
          if (ret != 0) goto <D.22844>; else goto <D.22845>;
          <D.22844>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.22845>:
          D.22846 = ret != 0;
          D.22847 = (long int) D.22846;
          D.22848 = __builtin_expect (D.22847, 0);
          if (D.22848 != 0) goto <D.22849>; else goto <D.22850>;
          <D.22849>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4150, "ret == 0");
          <D.22850>:
        }
        D.22851 = domain->special_static_fields;
        if (D.22851 != 0B) goto <D.22852>; else goto <D.22853>;
        <D.22852>:
        D.22851 = domain->special_static_fields;
        local_slots.118 = local_slots;
        addr = monoeg_g_hash_table_lookup (D.22851, local_slots.118);
        <D.22853>:
        {
          int ret;

          D.22843 = &domain->lock.mutex;
          ret = pthread_mutex_unlock (D.22843);
          if (ret != 0) goto <D.22854>; else goto <D.22855>;
          <D.22854>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.22855>:
          D.22856 = ret != 0;
          D.22857 = (long int) D.22856;
          D.22858 = __builtin_expect (D.22857, 0);
          if (D.22858 != 0) goto <D.22859>; else goto <D.22860>;
          <D.22859>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4153, "ret == 0");
          <D.22860>:
        }
        if (addr == 0B) goto <D.22861>; else goto <D.22862>;
        <D.22861>:
        return;
        <D.22862>:
        addr.119 = (long int) addr;
        D.22864 = (unsigned int) addr.119;
        sid.offset = D.22864;
        D.22865 = sid.offset;
        D.22866 = D.22865 & 2147483647;
        sid.offset = D.22866;
        D.22865 = sid.offset;
        D.22867 = D.22865 >> 24;
        D.22868 = D.22867 + 4294967295;
        D.22869 = (int) D.22868;
        sid.idx = D.22869;
        {
          int ret;

          ret = pthread_mutex_lock (&threads_mutex.mutex);
          if (ret != 0) goto <D.22870>; else goto <D.22871>;
          <D.22870>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.22871>:
          D.22872 = ret != 0;
          D.22873 = (long int) D.22872;
          D.22874 = __builtin_expect (D.22873, 0);
          if (D.22874 != 0) goto <D.22875>; else goto <D.22876>;
          <D.22875>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4160, "ret == 0");
          <D.22876>:
        }
        threads.120 = threads;
        mono_g_hash_table_foreach (threads.120, clear_local_slot, &sid);
        {
          int ret;

          ret = pthread_mutex_unlock (&threads_mutex.mutex);
          if (ret != 0) goto <D.22878>; else goto <D.22879>;
          <D.22878>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.22879>:
          D.22880 = ret != 0;
          D.22881 = (long int) D.22880;
          D.22882 = __builtin_expect (D.22881, 0);
          if (D.22882 != 0) goto <D.22883>; else goto <D.22884>;
          <D.22883>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4162, "ret == 0");
          <D.22884>:
        }
      }
      goto <D.22885>;
      <D.22835>:
      <D.22885>:
    }
  finally
    {
      sid = {CLOBBER};
    }
}


clear_local_slot (void * key, void * value, void * user_data)
{
  void * * D.22891;
  int D.22893;
  long unsigned int D.22894;
  long unsigned int D.22895;
  void * * D.22896;
  void * D.22897;
  unsigned int D.22898;
  sizetype D.22899;
  sizetype D.22900;
  struct MonoArray * * D.22901;
  int D.22905;
  long unsigned int D.22906;
  long unsigned int D.22907;
  struct LocalSlotID * sid;
  struct MonoInternalThread * thread;
  struct MonoArray * slots_array;

  sid = user_data;
  thread = value;
  D.22891 = thread->static_data;
  if (D.22891 == 0B) goto <D.22889>; else goto <D.22892>;
  <D.22892>:
  D.22891 = thread->static_data;
  D.22893 = sid->idx;
  D.22894 = (long unsigned int) D.22893;
  D.22895 = D.22894 * 8;
  D.22896 = D.22891 + D.22895;
  D.22897 = *D.22896;
  if (D.22897 == 0B) goto <D.22889>; else goto <D.22890>;
  <D.22889>:
  return;
  <D.22890>:
  D.22891 = thread->static_data;
  D.22893 = sid->idx;
  D.22894 = (long unsigned int) D.22893;
  D.22895 = D.22894 * 8;
  D.22896 = D.22891 + D.22895;
  D.22897 = *D.22896;
  D.22898 = sid->offset;
  D.22899 = (sizetype) D.22898;
  D.22900 = D.22899 & 16777215;
  D.22901 = D.22897 + D.22900;
  slots_array = *D.22901;
  if (slots_array == 0B) goto <D.22902>; else goto <D.22904>;
  <D.22904>:
  D.22905 = sid->slot;
  D.22906 = (long unsigned int) D.22905;
  D.22907 = mono_array_length (slots_array);
  if (D.22906 >= D.22907) goto <D.22902>; else goto <D.22903>;
  <D.22902>:
  return;
  <D.22903>:
  {
    struct MonoObject * * __p;

    D.22905 = sid->slot;
    D.22906 = (long unsigned int) D.22905;
    __p = mono_array_addr_with_size (slots_array, 8, D.22906);
    *__p = 0B;
  }
}


__attribute__((visibility ("hidden")))
mono_thread_request_interruption (gboolean running_managed)
{
  struct MonoException * D.22911;
  gint32 * D.22912;
  int D.22913;
  int D.22919;
  void (*<T5d6>) (void) mono_thread_notify_pending_exc_fn.121;
  void * D.22925;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22909>; else goto <D.22910>;
  <D.22909>:
  D.22911 = 0B;
  return D.22911;
  <D.22910>:
  D.22912 = &thread->interruption_requested;
  D.22913 = InterlockedCompareExchange (D.22912, 1, 0);
  if (D.22913 == 1) goto <D.22914>; else goto <D.22915>;
  <D.22914>:
  D.22911 = 0B;
  return D.22911;
  <D.22915>:
  InterlockedIncrement (&thread_interruption_requested);
  if (running_managed == 0) goto <D.22916>; else goto <D.22918>;
  <D.22918>:
  D.22919 = is_running_protected_wrapper ();
  if (D.22919 != 0) goto <D.22916>; else goto <D.22917>;
  <D.22916>:
  mono_thread_notify_pending_exc_fn.121 = mono_thread_notify_pending_exc_fn;
  if (mono_thread_notify_pending_exc_fn.121 != 0B) goto <D.22921>; else goto <D.22922>;
  <D.22921>:
  if (running_managed == 0) goto <D.22923>; else goto <D.22924>;
  <D.22923>:
  mono_thread_notify_pending_exc_fn.121 = mono_thread_notify_pending_exc_fn;
  mono_thread_notify_pending_exc_fn.121 ();
  <D.22924>:
  <D.22922>:
  D.22925 = thread->handle;
  QueueUserAPC (dummy_apc, D.22925, 0B);
  D.22911 = 0B;
  return D.22911;
  <D.22917>:
  D.22911 = mono_thread_execute_interruption (thread);
  return D.22911;
}


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

  D.22927 = 0;
  return D.22927;
}


__attribute__((visibility ("hidden")))
mono_thread_resume_interruption ()
{
  struct MonoException * D.22931;
  unsigned int D.22932;
  unsigned int D.22933;
  _Bool D.22934;
  gint32 * D.22937;
  int D.22938;
  struct MonoInternalThread * thread;
  gboolean still_aborting;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22929>; else goto <D.22930>;
  <D.22929>:
  D.22931 = 0B;
  return D.22931;
  <D.22930>:
  lock_thread (thread);
  D.22932 = thread->state;
  D.22933 = D.22932 & 128;
  D.22934 = D.22933 != 0;
  still_aborting = (gboolean) D.22934;
  unlock_thread (thread);
  if (still_aborting == 0) goto <D.22935>; else goto <D.22936>;
  <D.22935>:
  D.22931 = 0B;
  return D.22931;
  <D.22936>:
  D.22937 = &thread->interruption_requested;
  D.22938 = InterlockedCompareExchange (D.22937, 1, 0);
  if (D.22938 == 1) goto <D.22939>; else goto <D.22940>;
  <D.22939>:
  D.22931 = 0B;
  return D.22931;
  <D.22940>:
  InterlockedIncrement (&thread_interruption_requested);
  wapi_self_interrupt ();
  D.22931 = mono_thread_execute_interruption (thread);
  return D.22931;
}


__attribute__((visibility ("hidden")))
mono_thread_interruption_requested ()
{
  int thread_interruption_requested.122;
  gboolean D.22947;

  thread_interruption_requested.122 = thread_interruption_requested;
  if (thread_interruption_requested.122 != 0) goto <D.22943>; else goto <D.22944>;
  <D.22943>:
  {
    struct MonoInternalThread * thread;

    thread = mono_thread_internal_current ();
    if (thread != 0B) goto <D.22945>; else goto <D.22946>;
    <D.22945>:
    D.22947 = thread->interruption_requested;
    return D.22947;
    <D.22946>:
  }
  <D.22944>:
  D.22947 = 0;
  return D.22947;
}


__attribute__((visibility ("hidden")))
mono_thread_interruption_checkpoint ()
{
  mono_thread_interruption_checkpoint_request (0);
}


mono_thread_interruption_checkpoint_request (gboolean bypass_abort_protection)
{
  int D.22953;
  int D.22957;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22949>; else goto <D.22950>;
  <D.22949>:
  return;
  <D.22950>:
  D.22953 = thread->interruption_requested;
  if (D.22953 != 0) goto <D.22954>; else goto <D.22955>;
  <D.22954>:
  if (bypass_abort_protection != 0) goto <D.22951>; else goto <D.22956>;
  <D.22956>:
  D.22957 = is_running_protected_wrapper ();
  if (D.22957 == 0) goto <D.22951>; else goto <D.22952>;
  <D.22951>:
  {
    struct MonoException * exc;

    exc = mono_thread_execute_interruption (thread);
    if (exc != 0B) goto <D.22958>; else goto <D.22959>;
    <D.22958>:
    mono_raise_exception (exc);
    <D.22959>:
  }
  <D.22952>:
  <D.22955>:
}


__attribute__((visibility ("hidden")))
mono_thread_force_interruption_checkpoint ()
{
  mono_thread_interruption_checkpoint_request (1);
}


__attribute__((visibility ("hidden")))
mono_thread_get_and_clear_pending_exception ()
{
  struct MonoException * D.22963;
  int D.22964;
  int D.22967;
  struct MonoException * D.22970;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22961>; else goto <D.22962>;
  <D.22961>:
  D.22963 = 0B;
  return D.22963;
  <D.22962>:
  D.22964 = thread->interruption_requested;
  if (D.22964 != 0) goto <D.22965>; else goto <D.22966>;
  <D.22965>:
  D.22967 = is_running_protected_wrapper ();
  if (D.22967 == 0) goto <D.22968>; else goto <D.22969>;
  <D.22968>:
  D.22963 = mono_thread_execute_interruption (thread);
  return D.22963;
  <D.22969>:
  <D.22966>:
  D.22970 = thread->pending_exception;
  if (D.22970 != 0B) goto <D.22971>; else goto <D.22972>;
  <D.22971>:
  {
    struct MonoException * exc;

    exc = thread->pending_exception;
    thread->pending_exception = 0B;
    D.22963 = exc;
    return D.22963;
  }
  <D.22972>:
  D.22963 = 0B;
  return D.22963;
}


__attribute__((visibility ("hidden")))
mono_set_pending_exception (struct MonoException * exc)
{
  struct MonoException * * D.22976;
  struct MonoInternalThread * thread;

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


__attribute__((visibility ("hidden")))
mono_thread_interruption_request_flag ()
{
  gint32 * D.22978;

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


__attribute__((visibility ("hidden")))
mono_thread_init_apartment_state ()
{

}


__attribute__((visibility ("hidden")))
mono_thread_cleanup_apartment_state ()
{

}


__attribute__((visibility ("hidden")))
mono_thread_set_state (struct MonoInternalThread * thread, MonoThreadState state)
{
  unsigned int D.22980;
  unsigned int D.22981;

  lock_thread (thread);
  D.22980 = thread->state;
  D.22981 = D.22980 | state;
  thread->state = D.22981;
  unlock_thread (thread);
}


__attribute__((visibility ("hidden")))
mono_thread_clr_state (struct MonoInternalThread * thread, MonoThreadState state)
{
  unsigned int D.22982;
  unsigned int D.22983;
  unsigned int D.22984;

  lock_thread (thread);
  D.22982 = thread->state;
  D.22983 = ~state;
  D.22984 = D.22982 & D.22983;
  thread->state = D.22984;
  unlock_thread (thread);
}


__attribute__((visibility ("hidden")))
mono_thread_test_state (struct MonoInternalThread * thread, MonoThreadState test)
{
  unsigned int D.22985;
  unsigned int D.22986;
  gboolean D.22989;
  gboolean ret;

  ret = 0;
  lock_thread (thread);
  D.22985 = thread->state;
  D.22986 = D.22985 & test;
  if (D.22986 != 0) goto <D.22987>; else goto <D.22988>;
  <D.22987>:
  ret = 1;
  <D.22988>:
  unlock_thread (thread);
  D.22989 = ret;
  return D.22989;
}


__attribute__((visibility ("hidden")))
mono_thread_get_execution_context ()
{
  struct MonoObject * D.22991;
  struct MonoObject * * D.22992;

  D.22992 = get_execution_context_addr ();
  D.22991 = *D.22992;
  return D.22991;
}


get_execution_context_addr ()
{
  struct MonoClass * D.22996;
  _Bool D.22997;
  long int D.22998;
  long int D.22999;
  struct MonoClass * D.23002;
  struct MonoVTable * D.23003;
  _Bool D.23004;
  long int D.23005;
  long int D.23006;
  union mono_mutex_t * D.23009;
  _Bool D.23012;
  long int D.23013;
  long int D.23014;
  struct GHashTable * D.23017;
  void * D.23018;
  long int D.23019;
  _Bool D.23022;
  long int D.23023;
  long int D.23024;
  _Bool D.23027;
  long int D.23028;
  long int D.23029;
  struct MonoObject * * D.23032;
  struct MonoDomain * domain;
  guint32 offset;

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

    D.22996 = mono_defaults.thread_class;
    field = mono_class_get_field_from_name (D.22996, "_ec");
    D.22997 = field == 0B;
    D.22998 = (long int) D.22997;
    D.22999 = __builtin_expect (D.22998, 0);
    if (D.22999 != 0) goto <D.23000>; else goto <D.23001>;
    <D.23000>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4501, "field");
    <D.23001>:
    D.23002 = mono_defaults.appdomain_class;
    D.23003 = mono_class_try_get_vtable (domain, D.23002);
    D.23004 = D.23003 == 0B;
    D.23005 = (long int) D.23004;
    D.23006 = __builtin_expect (D.23005, 0);
    if (D.23006 != 0) goto <D.23007>; else goto <D.23008>;
    <D.23007>:
    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.23008>:
    {
      int ret;

      D.23009 = &domain->lock.mutex;
      ret = pthread_mutex_lock (D.23009);
      if (ret != 0) goto <D.23010>; else goto <D.23011>;
      <D.23010>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.23011>:
      D.23012 = ret != 0;
      D.23013 = (long int) D.23012;
      D.23014 = __builtin_expect (D.23013, 0);
      if (D.23014 != 0) goto <D.23015>; else goto <D.23016>;
      <D.23015>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4505, "ret == 0");
      <D.23016>:
    }
    D.23017 = domain->special_static_fields;
    D.23018 = monoeg_g_hash_table_lookup (D.23017, field);
    D.23019 = (long int) D.23018;
    offset = (guint32) D.23019;
    {
      int ret;

      D.23009 = &domain->lock.mutex;
      ret = pthread_mutex_unlock (D.23009);
      if (ret != 0) goto <D.23020>; else goto <D.23021>;
      <D.23020>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.23021>:
      D.23022 = ret != 0;
      D.23023 = (long int) D.23022;
      D.23024 = __builtin_expect (D.23023, 0);
      if (D.23024 != 0) goto <D.23025>; else goto <D.23026>;
      <D.23025>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4507, "ret == 0");
      <D.23026>:
    }
    D.23027 = offset == 0;
    D.23028 = (long int) D.23027;
    D.23029 = __builtin_expect (D.23028, 0);
    if (D.23029 != 0) goto <D.23030>; else goto <D.23031>;
    <D.23030>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4508, "offset");
    <D.23031>:
    domain->execution_context_field_offset = offset;
  }
  <D.22995>:
  D.23032 = mono_get_special_static_data (offset);
  return D.23032;
}


__attribute__((visibility ("hidden")))
mono_thread_set_execution_context (struct MonoObject * ec)
{
  struct MonoObject * * D.23034;

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


__attribute__((visibility ("hidden")))
mono_runtime_set_has_tls_get (gboolean val)
{
  has_tls_get = val;
}


__attribute__((visibility ("hidden")))
mono_runtime_has_tls_get ()
{
  gboolean D.23035;

  D.23035 = has_tls_get;
  return D.23035;
}


__attribute__((visibility ("hidden")))
mono_thread_kill (struct MonoInternalThread * thread, int signal)
{
  int D.23037;
  long unsigned int D.23038;
  int D.23039;

  D.23038 = thread->tid;
  D.23039 = mono_thread_get_abort_signal ();
  D.23037 = pthread_kill (D.23038, D.23039);
  return D.23037;
}


mono_thread_is_foreign (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.23041;
  mono_bool D.23042;
  int D.23043;
  _Bool D.23044;
  struct MonoThreadInfo * info;

  D.23041 = thread->internal_thread;
  info = D.23041->thread_info;
  D.23043 = info->runtime_thread;
  D.23044 = D.23043 == 0;
  D.23042 = (mono_bool) D.23044;
  return D.23042;
}


