mono_thread_get_tls_key ()
{
  pthread_key_t D.19957;

  D.19957 = current_object_key;
  return D.19957;
}


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

  offset = -1;
  D.19959 = offset;
  return D.19959;
}


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


mono_threads_set_default_stacksize (guint32 stacksize)
{
  default_stacksize = stacksize;
}


mono_threads_get_default_stacksize ()
{
  uint32_t D.19964;

  D.19964 = default_stacksize;
  return D.19964;
}


mono_thread_create_internal (struct MonoDomain * domain, void * func, void * arg, gboolean threadpool_thread, gboolean no_detach, guint32 stack_size)
{
  struct _MonoInternalThread * * D.19966;
  guint32 (*<T3155>) (void *) func.1;
  struct MonoInternalThread * D.19970;
  const char * D.19971;
  struct MonoClass * D.19974;
  struct MonoClassField * D.19975;
  unsigned int D.19976;
  sizetype D.19977;
  sizetype D.19978;
  struct MonoClassField * D.19979;
  int D.19980;
  _Bool D.19981;
  long int D.19982;
  long int D.19983;
  struct MonoThread * thread;
  struct MonoInternalThread * internal;
  struct StartInfo * start_info;
  gboolean res;

  thread = create_thread_object (domain);
  internal = create_internal_thread ();
  D.19966 = &thread->internal_thread;
  mono_gc_wbarrier_set_field (thread, D.19966, internal);
  start_info = monoeg_malloc0 (16);
  func.1 = (guint32 (*<T3155>) (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.19968>; else goto <D.19969>;
  <D.19968>:
  D.19970 = 0B;
  return D.19970;
  <D.19969>:
  D.19971 = mono_check_corlib_version ();
  if (D.19971 == 0B) goto <D.19972>; else goto <D.19973>;
  <D.19972>:
  D.19974 = mono_defaults.internal_thread_class;
  D.19975 = D.19974->fields;
  D.19974 = mono_defaults.internal_thread_class;
  D.19976 = D.19974->field.count;
  D.19977 = D.19976 + 268435455;
  D.19978 = D.19977 * 16;
  D.19979 = D.19975 + D.19978;
  D.19980 = D.19979->offset;
  D.19981 = D.19980 != 172;
  D.19982 = (long int) D.19981;
  D.19983 = __builtin_expect (D.19982, 0);
  if (D.19983 != 0) goto <D.19984>; else goto <D.19985>;
  <D.19984>:
  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.19985>:
  <D.19973>:
  D.19970 = internal;
  return D.19970;
}


create_thread_object (struct MonoDomain * domain)
{
  struct MonoClass * D.19987;
  struct MonoThread * D.19988;
  struct MonoVTable * vt;

  D.19987 = mono_defaults.thread_class;
  vt = mono_class_vtable (domain, D.19987);
  D.19988 = mono_gc_alloc_mature (vt);
  return D.19988;
}


create_internal_thread ()
{
  struct MonoDomain * D.19990;
  struct MonoClass * D.19991;
  void * D.19992;
  struct CRITICAL_SECTION * D.19993;
  unsigned int D.19994;
  int D.19995;
  int D.19996;
  void * * D.19999;
  struct MonoInternalThread * D.20000;
  struct MonoInternalThread * thread;
  struct MonoVTable * vt;

  D.19990 = mono_get_root_domain ();
  D.19991 = mono_defaults.internal_thread_class;
  vt = mono_class_vtable (D.19990, D.19991);
  thread = mono_gc_alloc_mature (vt);
  D.19992 = monoeg_malloc0 (28);
  thread->synch_cs = D.19992;
  D.19993 = thread->synch_cs;
  InitializeCriticalSection (D.19993);
  thread->apartment_state = 2;
  D.19994 = get_next_managed_thread_id ();
  D.19995 = (int) D.19994;
  thread->managed_id = D.19995;
  D.19996 = mono_gc_is_moving ();
  if (D.19996 != 0) goto <D.19997>; else goto <D.19998>;
  <D.19997>:
  thread->thread_pinning_ref = thread;
  D.19999 = &thread->thread_pinning_ref;
  mono_gc_register_root (D.19999, 4, 0B);
  <D.19998>:
  D.20000 = thread;
  return D.20000;
}


get_next_managed_thread_id ()
{
  guint32 D.20002;
  int D.20003;

  D.20003 = InterlockedIncrement (&managed_thread_id_counter);
  D.20002 = (guint32) D.20003;
  return D.20002;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.20005;
  unsigned int D.20006;

  D.20006 = __sync_add_and_fetch_4 (val, 1);
  D.20005 = (gint32) D.20006;
  return D.20005;
}


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.20010;
  long int D.20011;
  long int D.20012;
  int shutting_down.2;
  _Bool D.20020;
  long int D.20021;
  long int D.20022;
  gboolean D.20025;
  struct MonoGHashTable * thread_start_args.3;
  int D.20029;
  struct MonoGHashTable * thread_start_args.4;
  void * D.20033;
  struct MonoGHashTable * threads_starting_up.5;
  int D.20037;
  struct MonoGHashTable * threads_starting_up.6;
  _Bool D.20043;
  long int D.20044;
  long int D.20045;
  void * D.20048;
  void * D.20049;
  _Bool D.20054;
  long int D.20055;
  long int D.20056;
  _Bool D.20061;
  long int D.20062;
  long int D.20063;
  unsigned int D.20066;
  guint32 iftmp.7;
  int D.20070;
  _Bool D.20080;
  long int D.20081;
  long int D.20082;
  _Bool D.20087;
  long int D.20088;
  long int D.20089;
  struct MonoException * D.20094;
  unsigned int D.20096;
  long unsigned int tid.8;
  long long unsigned int D.20098;
  unsigned char D.20099;
  int D.20102;
  void * D.20105;
  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.20008>; else goto <D.20009>;
        <D.20008>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20009>:
        D.20010 = ret != 0;
        D.20011 = (long int) D.20010;
        D.20012 = __builtin_expect (D.20011, 0);
        if (D.20012 != 0) goto <D.20013>; else goto <D.20014>;
        <D.20013>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 705, "ret == 0");
        <D.20014>:
      }
      shutting_down.2 = shutting_down;
      if (shutting_down.2 != 0) goto <D.20016>; else goto <D.20017>;
      <D.20016>:
      monoeg_g_free (start_info);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20018>; else goto <D.20019>;
        <D.20018>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20019>:
        D.20020 = ret != 0;
        D.20021 = (long int) D.20020;
        D.20022 = __builtin_expect (D.20021, 0);
        if (D.20022 != 0) goto <D.20023>; else goto <D.20024>;
        <D.20023>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 708, "ret == 0");
        <D.20024>:
      }
      D.20025 = 0;
      return D.20025;
      <D.20017>:
      thread_start_args.3 = thread_start_args;
      if (thread_start_args.3 == 0B) goto <D.20027>; else goto <D.20028>;
      <D.20027>:
      D.20029 = mono_gc_is_moving ();
      if (D.20029 == 0) goto <D.20030>; else goto <D.20031>;
      <D.20030>:
      mono_gc_register_root (&thread_start_args, 4, 0B);
      <D.20031>:
      thread_start_args.4 = mono_g_hash_table_new (0B, 0B);
      thread_start_args = thread_start_args.4;
      <D.20028>:
      thread_start_args.3 = thread_start_args;
      D.20033 = start_info->start_arg;
      mono_g_hash_table_insert (thread_start_args.3, thread, D.20033);
      threads_starting_up.5 = threads_starting_up;
      if (threads_starting_up.5 == 0B) goto <D.20035>; else goto <D.20036>;
      <D.20035>:
      D.20037 = mono_gc_is_moving ();
      if (D.20037 == 0) goto <D.20038>; else goto <D.20039>;
      <D.20038>:
      mono_gc_register_root (&threads_starting_up, 4, 0B);
      <D.20039>:
      threads_starting_up.6 = mono_g_hash_table_new_type (0B, 0B, 3);
      threads_starting_up = threads_starting_up.6;
      <D.20036>:
      threads_starting_up.5 = threads_starting_up;
      mono_g_hash_table_insert (threads_starting_up.5, thread, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20041>; else goto <D.20042>;
        <D.20041>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20042>:
        D.20043 = ret != 0;
        D.20044 = (long int) D.20043;
        D.20045 = __builtin_expect (D.20044, 0);
        if (D.20045 != 0) goto <D.20046>; else goto <D.20047>;
        <D.20046>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 727, "ret == 0");
        <D.20047>:
      }
      D.20048 = CreateSemaphore (0B, 0, 2147483647, 0B);
      internal->start_notify = D.20048;
      D.20049 = internal->start_notify;
      if (D.20049 == 0B) goto <D.20050>; else goto <D.20051>;
      <D.20050>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20052>; else goto <D.20053>;
        <D.20052>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20053>:
        D.20054 = ret != 0;
        D.20055 = (long int) D.20054;
        D.20056 = __builtin_expect (D.20055, 0);
        if (D.20056 != 0) goto <D.20057>; else goto <D.20058>;
        <D.20057>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 731, "ret == 0");
        <D.20058>:
      }
      threads_starting_up.5 = threads_starting_up;
      mono_g_hash_table_remove (threads_starting_up.5, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20059>; else goto <D.20060>;
        <D.20059>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20060>:
        D.20061 = ret != 0;
        D.20062 = (long int) D.20061;
        D.20063 = __builtin_expect (D.20062, 0);
        if (D.20063 != 0) goto <D.20064>; else goto <D.20065>;
        <D.20064>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 733, "ret == 0");
        <D.20065>:
      }
      D.20066 = GetLastError ();
      monoeg_g_log (0B, 16, "%s: CreateSemaphore error 0x%x", &__func__, D.20066);
      monoeg_g_free (start_info);
      D.20025 = 0;
      return D.20025;
      <D.20051>:
      if (stack_size == 0) goto <D.20067>; else goto <D.20068>;
      <D.20067>:
      D.20070 = internal->stack_size;
      if (D.20070 != 0) goto <D.20071>; else goto <D.20072>;
      <D.20071>:
      D.20070 = internal->stack_size;
      iftmp.7 = (guint32) D.20070;
      goto <D.20073>;
      <D.20072>:
      iftmp.7 = default_stacksize;
      <D.20073>:
      stack_size = iftmp.7;
      <D.20068>:
      create_flags = 4;
      if (no_detach != 0) goto <D.20074>; else goto <D.20075>;
      <D.20074>:
      create_flags = create_flags | 268435456;
      <D.20075>:
      thread_handle = mono_threads_create_thread (start_wrapper, start_info, stack_size, create_flags, &tid);
      if (thread_handle == 0B) goto <D.20076>; else goto <D.20077>;
      <D.20076>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20078>; else goto <D.20079>;
        <D.20078>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20079>:
        D.20080 = ret != 0;
        D.20081 = (long int) D.20080;
        D.20082 = __builtin_expect (D.20081, 0);
        if (D.20082 != 0) goto <D.20083>; else goto <D.20084>;
        <D.20083>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 754, "ret == 0");
        <D.20084>:
      }
      threads_starting_up.5 = threads_starting_up;
      mono_g_hash_table_remove (threads_starting_up.5, thread);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20085>; else goto <D.20086>;
        <D.20085>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20086>:
        D.20087 = ret != 0;
        D.20088 = (long int) D.20087;
        D.20089 = __builtin_expect (D.20088, 0);
        if (D.20089 != 0) goto <D.20090>; else goto <D.20091>;
        <D.20090>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 756, "ret == 0");
        <D.20091>:
      }
      monoeg_g_free (start_info);
      if (throw_on_failure != 0) goto <D.20092>; else goto <D.20093>;
      <D.20092>:
      D.20094 = mono_get_exception_execution_engine ("Couldn\'t create thread");
      mono_raise_exception (D.20094);
      goto <D.20095>;
      <D.20093>:
      D.20096 = GetLastError ();
      monoeg_g_log (0B, 16, "%s: CreateThread error 0x%x", &__func__, D.20096);
      <D.20095>:
      D.20025 = 0;
      return D.20025;
      <D.20077>:
      internal->handle = thread_handle;
      tid.8 = tid;
      D.20098 = (long long unsigned int) tid.8;
      internal->tid = D.20098;
      D.20099 = (unsigned char) threadpool_thread;
      internal->threadpool_thread = D.20099;
      if (threadpool_thread != 0) goto <D.20100>; else goto <D.20101>;
      <D.20100>:
      mono_thread_set_state (internal, 4);
      <D.20101>:
      D.20102 = handle_store (thread, 0);
      if (D.20102 == 0) goto <D.20103>; else goto <D.20104>;
      <D.20103>:
      D.20025 = 0;
      return D.20025;
      <D.20104>:
      D.20105 = internal->handle;
      ResumeThread (D.20105);
      D.20049 = internal->start_notify;
      if (D.20049 != 0B) goto <D.20106>; else goto <D.20107>;
      <D.20106>:
      D.20049 = internal->start_notify;
      WaitForSingleObjectEx (D.20049, 4294967295, 0);
      D.20049 = internal->start_notify;
      CloseHandle (D.20049);
      internal->start_notify = 0B;
      <D.20107>:
      D.20025 = 1;
      return D.20025;
    }
  finally
    {
      tid = {CLOBBER};
    }
}


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

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


start_wrapper_internal (void * data)
{
  struct MonoThread * D.20112;
  struct MonoVTable * D.20113;
  _Bool D.20114;
  long int D.20115;
  long int D.20116;
  long long unsigned int D.20119;
  unsigned int tid.9;
  unsigned int current_object_key.10;
  int D.20122;
  guint32 D.20125;
  unsigned int tid.11;
  int tid.12;
  unsigned char D.20128;
  void * D.20131;
  _Bool D.20136;
  long int D.20137;
  long int D.20138;
  struct MonoGHashTable * thread_start_args.13;
  _Bool D.20144;
  long int D.20145;
  long int D.20146;
  struct MonoObject * D.20149;
  _Bool D.20153;
  long int D.20154;
  long int D.20155;
  struct MonoThreadInfo * info;
  struct StartInfo * start_info;
  guint32 (*<T3155>) (void *) start_func;
  void * start_arg;
  gsize tid;
  struct MonoInternalThread * internal;
  struct MonoObject * start_delegate;
  struct MonoDomain * domain;

  try
    {
      start_info = data;
      D.20112 = start_info->obj;
      internal = D.20112->internal_thread;
      start_delegate = start_info->delegate;
      D.20112 = start_info->obj;
      D.20113 = D.20112->obj.vtable;
      domain = D.20113->domain;
      info = mono_thread_info_current ();
      D.20114 = info == 0B;
      D.20115 = (long int) D.20114;
      D.20116 = __builtin_expect (D.20115, 0);
      if (D.20116 != 0) goto <D.20117>; else goto <D.20118>;
      <D.20117>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 570, "info");
      <D.20118>:
      internal->thread_info = info;
      D.20119 = internal->tid;
      tid.9 = (unsigned int) D.20119;
      tid = tid.9;
      tls_current_object = internal;
      current_object_key.10 = current_object_key;
      mono_native_tls_set_value (current_object_key.10, internal);
      mono_monitor_init_tls ();
      mono_thread_push_appdomain_ref (domain);
      D.20122 = mono_domain_set (domain, 0);
      if (D.20122 == 0) goto <D.20123>; else goto <D.20124>;
      <D.20123>:
      mono_thread_pop_appdomain_ref ();
      D.20125 = 0;
      return D.20125;
      <D.20124>:
      start_func = start_info->func;
      start_arg = start_info->start_arg;
      thread_adjust_static_data (internal);
      D.20112 = start_info->obj;
      init_root_domain_thread (internal, D.20112);
      tid.11 = tid;
      tid.12 = (int) tid.11;
      mono_thread_new_init (tid.12, &tid, start_func);
      internal->stack_ptr = &tid;
      D.20128 = internal->apartment_state;
      if (D.20128 == 2) goto <D.20129>; else goto <D.20130>;
      <D.20129>:
      internal->apartment_state = 1;
      <D.20130>:
      mono_thread_init_apartment_state ();
      D.20131 = internal->start_notify;
      if (D.20131 != 0B) goto <D.20132>; else goto <D.20133>;
      <D.20132>:
      D.20131 = internal->start_notify;
      ReleaseSemaphore (D.20131, 1, 0B);
      <D.20133>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20134>; else goto <D.20135>;
        <D.20134>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20135>:
        D.20136 = ret != 0;
        D.20137 = (long int) D.20136;
        D.20138 = __builtin_expect (D.20137, 0);
        if (D.20138 != 0) goto <D.20139>; else goto <D.20140>;
        <D.20139>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 623, "ret == 0");
        <D.20140>:
      }
      thread_start_args.13 = thread_start_args;
      D.20112 = start_info->obj;
      mono_g_hash_table_remove (thread_start_args.13, D.20112);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.20142>; else goto <D.20143>;
        <D.20142>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20143>:
        D.20144 = ret != 0;
        D.20145 = (long int) D.20144;
        D.20146 = __builtin_expect (D.20145, 0);
        if (D.20146 != 0) goto <D.20147>; else goto <D.20148>;
        <D.20147>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 625, "ret == 0");
        <D.20148>:
      }
      D.20112 = start_info->obj;
      D.20149 = D.20112->ec_to_set;
      mono_thread_set_execution_context (D.20149);
      D.20112 = start_info->obj;
      D.20112->ec_to_set = 0B;
      monoeg_g_free (start_info);
      tid.11 = tid;
      mono_profiler_thread_start (tid.11);
      if (start_func != 0B) goto <D.20150>; else goto <D.20151>;
      <D.20150>:
      start_func (start_arg);
      goto <D.20152>;
      <D.20151>:
      {
        void * args[1];

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


thread_adjust_static_data (struct MonoInternalThread * thread)
{
  _Bool D.20162;
  long int D.20163;
  long int D.20164;
  int D.20169;
  int D.20171;
  int D.20172;
  int D.20173;
  int D.20174;
  void * * * D.20175;
  _Bool D.20178;
  long int D.20179;
  long int D.20180;
  guint32 offset;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20160>; else goto <D.20161>;
    <D.20160>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20161>:
    D.20162 = ret != 0;
    D.20163 = (long int) D.20162;
    D.20164 = __builtin_expect (D.20163, 0);
    if (D.20164 != 0) goto <D.20165>; else goto <D.20166>;
    <D.20165>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3819, "ret == 0");
    <D.20166>:
  }
  D.20169 = thread_static_info.offset;
  if (D.20169 != 0) goto <D.20167>; else goto <D.20170>;
  <D.20170>:
  D.20171 = thread_static_info.idx;
  if (D.20171 > 0) goto <D.20167>; else goto <D.20168>;
  <D.20167>:
  D.20169 = thread_static_info.offset;
  D.20171 = thread_static_info.idx;
  D.20172 = D.20171 + 1;
  D.20173 = D.20172 << 24;
  D.20174 = D.20169 | D.20173;
  offset = (guint32) D.20174;
  D.20175 = &thread->static_data;
  mono_alloc_static_data (D.20175, offset, 1);
  <D.20168>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20176>; else goto <D.20177>;
    <D.20176>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20177>:
    D.20178 = ret != 0;
    D.20179 = (long int) D.20178;
    D.20180 = __builtin_expect (D.20179, 0);
    if (D.20180 != 0) goto <D.20181>; else goto <D.20182>;
    <D.20181>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3825, "ret == 0");
    <D.20182>:
  }
}


mono_alloc_static_data (void * * * static_data_ptr, guint32 offset, gboolean threadlocal)
{
  unsigned int D.20183;
  int D.20186;
  void * tls_desc.14;
  void * tls_desc.15;
  int D.20193;
  unsigned int D.20194;
  void * iftmp.16;
  unsigned int i.17;
  unsigned int D.20200;
  void * * D.20201;
  void * D.20202;
  int D.20207;
  int D.20210;
  unsigned int D.20211;
  void * D.20212;
  unsigned int D.20213;
  void * D.20214;
  unsigned int i.18;
  guint idx;
  int i;
  void * * static_data;

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

    D.20186 = mono_gc_user_markers_supported ();
    if (D.20186 != 0) goto <D.20187>; else goto <D.20188>;
    <D.20187>:
    tls_desc.14 = tls_desc;
    if (tls_desc.14 == 0B) goto <D.20190>; else goto <D.20191>;
    <D.20190>:
    tls_desc.15 = mono_gc_make_root_descr_user (mark_tls_slots);
    tls_desc = tls_desc.15;
    <D.20191>:
    <D.20188>:
    D.20193 = 1024;
    D.20194 = (unsigned int) D.20193;
    if (threadlocal != 0) goto <D.20196>; else goto <D.20197>;
    <D.20196>:
    iftmp.16 = tls_desc;
    goto <D.20198>;
    <D.20197>:
    iftmp.16 = 0B;
    <D.20198>:
    static_data = mono_gc_alloc_fixed (D.20194, iftmp.16);
    *static_data_ptr = static_data;
    *static_data = static_data;
  }
  <D.20185>:
  i = 1;
  goto <D.19633>;
  <D.19632>:
  i.17 = (unsigned int) i;
  D.20200 = i.17 * 4;
  D.20201 = static_data + D.20200;
  D.20202 = *D.20201;
  if (D.20202 != 0B) goto <D.20203>; else goto <D.20204>;
  <D.20203>:
  // predicted unlikely by continue predictor.
  goto <D.19631>;
  <D.20204>:
  D.20207 = mono_gc_user_markers_supported ();
  if (D.20207 != 0) goto <D.20208>; else goto <D.20205>;
  <D.20208>:
  if (threadlocal != 0) goto <D.20209>; else goto <D.20205>;
  <D.20209>:
  i.17 = (unsigned int) i;
  D.20200 = i.17 * 4;
  D.20201 = static_data + D.20200;
  D.20210 = static_data_size[i];
  D.20211 = (unsigned int) D.20210;
  D.20212 = monoeg_malloc0 (D.20211);
  *D.20201 = D.20212;
  goto <D.20206>;
  <D.20205>:
  i.17 = (unsigned int) i;
  D.20200 = i.17 * 4;
  D.20201 = static_data + D.20200;
  D.20210 = static_data_size[i];
  D.20213 = (unsigned int) D.20210;
  D.20214 = mono_gc_alloc_fixed (D.20213, 0B);
  *D.20201 = D.20214;
  <D.20206>:
  <D.19631>:
  i = i + 1;
  <D.19633>:
  i.18 = (unsigned int) i;
  if (i.18 <= idx) goto <D.19632>; else goto <D.19634>;
  <D.19634>:
}


mark_tls_slots (void * addr, void (*MonoGCMarkFunc) (void * *) mark_func)
{
  unsigned int i.19;
  unsigned int D.20217;
  void * * D.20218;
  void * D.20219;
  int D.20222;
  unsigned int D.20223;
  unsigned int D.20224;
  unsigned int D.20225;
  uintptr_t * D.20226;
  unsigned int j.20;
  unsigned int D.20228;
  uintptr_t * D.20229;
  unsigned int D.20230;
  void * D.20233;
  int i;
  void * * static_data;

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

    i.19 = (unsigned int) i;
    D.20217 = i.19 * 4;
    D.20218 = static_data + D.20217;
    D.20219 = *D.20218;
    if (D.20219 == 0B) goto <D.20220>; else goto <D.20221>;
    <D.20220>:
    // predicted unlikely by continue predictor.
    goto <D.19610>;
    <D.20221>:
    D.20222 = static_data_size[i];
    D.20223 = (unsigned int) D.20222;
    D.20224 = D.20223 / 128;
    D.20225 = D.20224 + 1;
    numwords = (int) D.20225;
    i.19 = (unsigned int) i;
    D.20217 = i.19 * 4;
    D.20218 = static_data + D.20217;
    ptr = *D.20218;
    j = 0;
    goto <D.19617>;
    <D.19616>:
    {
      uintptr_t bmap;
      void * * p;

      D.20226 = static_reference_bitmaps[i];
      j.20 = (unsigned int) j;
      D.20228 = j.20 * 4;
      D.20229 = D.20226 + D.20228;
      bmap = *D.20229;
      p = ptr;
      goto <D.19614>;
      <D.19613>:
      D.20230 = bmap & 1;
      if (D.20230 != 0) goto <D.20231>; else goto <D.20232>;
      <D.20231>:
      D.20233 = *p;
      if (D.20233 != 0B) goto <D.20234>; else goto <D.20235>;
      <D.20234>:
      mark_func (p);
      <D.20235>:
      <D.20232>:
      p = p + 4;
      bmap = bmap >> 1;
      <D.19614>:
      if (bmap != 0) goto <D.19613>; else goto <D.19615>;
      <D.19615>:
    }
    j = j + 1;
    ptr = ptr + 128;
    <D.19617>:
    if (j < numwords) goto <D.19616>; else goto <D.19618>;
    <D.19618>:
  }
  <D.19610>:
  i = i + 1;
  <D.19620>:
  if (i <= 7) goto <D.19619>; else goto <D.19621>;
  <D.19621>:
}


init_root_domain_thread (struct MonoInternalThread * thread, struct MonoThread * candidate)
{
  struct MonoVTable * D.20239;
  struct MonoDomain * D.20240;
  struct MonoThread * D.20241;
  _Bool D.20242;
  long int D.20243;
  long int D.20244;
  struct MonoThread * * D.20247;
  struct MonoDomain * domain;

  domain = mono_get_root_domain ();
  if (candidate == 0B) goto <D.20236>; else goto <D.20238>;
  <D.20238>:
  D.20239 = candidate->obj.vtable;
  D.20240 = D.20239->domain;
  if (D.20240 != domain) goto <D.20236>; else goto <D.20237>;
  <D.20236>:
  candidate = new_thread_with_internal (domain, thread);
  <D.20237>:
  set_current_thread_for_domain (domain, thread, candidate);
  D.20241 = thread->root_domain_thread;
  D.20242 = D.20241 != 0B;
  D.20243 = (long int) D.20242;
  D.20244 = __builtin_expect (D.20243, 0);
  if (D.20244 != 0) goto <D.20245>; else goto <D.20246>;
  <D.20245>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 542, "!thread->root_domain_thread");
  <D.20246>:
  D.20247 = &thread->root_domain_thread;
  mono_gc_wbarrier_set_field (thread, D.20247, candidate);
}


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

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


set_current_thread_for_domain (struct MonoDomain * domain, struct MonoInternalThread * thread, struct MonoThread * current)
{
  struct MonoVTable * D.20251;
  struct MonoDomain * D.20252;
  _Bool D.20253;
  long int D.20254;
  long int D.20255;
  struct MonoThread * D.20258;
  _Bool D.20259;
  long int D.20260;
  long int D.20261;
  struct MonoThread * * current_thread_ptr;

  current_thread_ptr = get_current_thread_ptr_for_domain (domain, thread);
  D.20251 = current->obj.vtable;
  D.20252 = D.20251->domain;
  D.20253 = D.20252 != domain;
  D.20254 = (long int) D.20253;
  D.20255 = __builtin_expect (D.20254, 0);
  if (D.20255 != 0) goto <D.20256>; else goto <D.20257>;
  <D.20256>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 491, "current->obj.vtable->domain == domain");
  <D.20257>:
  D.20258 = *current_thread_ptr;
  D.20259 = D.20258 != 0B;
  D.20260 = (long int) D.20259;
  D.20261 = __builtin_expect (D.20260, 0);
  if (D.20261 != 0) goto <D.20262>; else goto <D.20263>;
  <D.20262>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 493, "!*current_thread_ptr");
  <D.20263>:
  *current_thread_ptr = current;
}


get_current_thread_ptr_for_domain (struct MonoDomain * domain, struct MonoInternalThread * thread)
{
  struct MonoClassField * current_thread_field.21;
  struct MonoClass * D.20267;
  struct MonoClassField * current_thread_field.22;
  _Bool D.20269;
  long int D.20270;
  long int D.20271;
  union mono_mutex_t * D.20274;
  _Bool D.20277;
  long int D.20278;
  long int D.20279;
  struct GHashTable * D.20282;
  void * D.20283;
  _Bool D.20286;
  long int D.20287;
  long int D.20288;
  _Bool D.20291;
  long int D.20292;
  long int D.20293;
  struct MonoThread * * D.20296;
  static struct MonoClassField * current_thread_field = 0B;
  guint32 offset;

  current_thread_field.21 = current_thread_field;
  if (current_thread_field.21 == 0B) goto <D.20265>; else goto <D.20266>;
  <D.20265>:
  D.20267 = mono_defaults.thread_class;
  current_thread_field.22 = mono_class_get_field_from_name (D.20267, "current_thread");
  current_thread_field = current_thread_field.22;
  current_thread_field.21 = current_thread_field;
  D.20269 = current_thread_field.21 == 0B;
  D.20270 = (long int) D.20269;
  D.20271 = __builtin_expect (D.20270, 0);
  if (D.20271 != 0) goto <D.20272>; else goto <D.20273>;
  <D.20272>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 474, "current_thread_field");
  <D.20273>:
  <D.20266>:
  D.20267 = mono_defaults.thread_class;
  mono_class_vtable (domain, D.20267);
  {
    int ret;

    D.20274 = &domain->lock.mutex;
    ret = pthread_mutex_lock (D.20274);
    if (ret != 0) goto <D.20275>; else goto <D.20276>;
    <D.20275>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20276>:
    D.20277 = ret != 0;
    D.20278 = (long int) D.20277;
    D.20279 = __builtin_expect (D.20278, 0);
    if (D.20279 != 0) goto <D.20280>; else goto <D.20281>;
    <D.20280>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 478, "ret == 0");
    <D.20281>:
  }
  D.20282 = domain->special_static_fields;
  current_thread_field.21 = current_thread_field;
  D.20283 = monoeg_g_hash_table_lookup (D.20282, current_thread_field.21);
  offset = (guint32) D.20283;
  {
    int ret;

    D.20274 = &domain->lock.mutex;
    ret = pthread_mutex_unlock (D.20274);
    if (ret != 0) goto <D.20284>; else goto <D.20285>;
    <D.20284>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20285>:
    D.20286 = ret != 0;
    D.20287 = (long int) D.20286;
    D.20288 = __builtin_expect (D.20287, 0);
    if (D.20288 != 0) goto <D.20289>; else goto <D.20290>;
    <D.20289>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 480, "ret == 0");
    <D.20290>:
  }
  D.20291 = offset == 0;
  D.20292 = (long int) D.20291;
  D.20293 = __builtin_expect (D.20292, 0);
  if (D.20293 != 0) goto <D.20294>; else goto <D.20295>;
  <D.20294>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 481, "offset");
  <D.20295>:
  D.20296 = get_thread_static_data (thread, offset);
  return D.20296;
}


get_thread_static_data (struct MonoInternalThread * thread, guint32 offset)
{
  signed int offset.23;
  _Bool D.20299;
  long int D.20300;
  long int D.20301;
  unsigned int D.20304;
  unsigned int D.20305;
  void * D.20306;
  void * * D.20307;
  unsigned int idx.24;
  unsigned int D.20309;
  void * * D.20310;
  void * D.20311;
  sizetype D.20312;
  int idx;

  offset.23 = (signed int) offset;
  D.20299 = offset.23 < 0;
  D.20300 = (long int) D.20299;
  D.20301 = __builtin_expect (D.20300, 0);
  if (D.20301 != 0) goto <D.20302>; else goto <D.20303>;
  <D.20302>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 459, "(offset & 0x80000000) == 0");
  <D.20303>:
  offset = offset & 2147483647;
  D.20304 = offset >> 24;
  D.20305 = D.20304 + 4294967295;
  idx = (int) D.20305;
  D.20307 = thread->static_data;
  idx.24 = (unsigned int) idx;
  D.20309 = idx.24 * 4;
  D.20310 = D.20307 + D.20309;
  D.20311 = *D.20310;
  D.20312 = offset & 16777215;
  D.20306 = D.20311 + D.20312;
  return D.20306;
}


thread_cleanup (struct MonoInternalThread * thread)
{
  _Bool D.20314;
  long int D.20315;
  long int D.20316;
  int D.20319;
  unsigned int D.20322;
  struct MonoArray * D.20323;
  unsigned int i.25;
  struct CRITICAL_SECTION * D.20327;
  int shutting_down.26;
  _Bool D.20332;
  long int D.20333;
  long int D.20334;
  unsigned int D.20337;
  unsigned int D.20338;
  unsigned int D.20339;
  gint32 * D.20342;
  int D.20343;
  int D.20346;
  struct MonoInternalThread * D.20349;
  void (*<T20d7>) (struct MonoInternalThread *) mono_thread_cleanup_fn.27;
  long long unsigned int D.20355;
  unsigned int D.20356;
  struct MonoInternalThread * D.20357;
  struct MonoInternalThread * D.20360;
  void * * D.20363;
  void * D.20364;
  int D.20367;
  void * * D.20370;

  D.20314 = thread == 0B;
  D.20315 = (long int) D.20314;
  D.20316 = __builtin_expect (D.20315, 0);
  if (D.20316 != 0) goto <D.20317>; else goto <D.20318>;
  <D.20317>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 368, "thread != NULL");
  <D.20318>:
  D.20319 = thread->abort_state_handle;
  if (D.20319 != 0) goto <D.20320>; else goto <D.20321>;
  <D.20320>:
  D.20319 = thread->abort_state_handle;
  D.20322 = (unsigned int) D.20319;
  mono_gchandle_free (D.20322);
  thread->abort_state_handle = 0;
  <D.20321>:
  thread->abort_exc = 0B;
  thread->current_appcontext = 0B;
  D.20323 = thread->cached_culture_info;
  if (D.20323 != 0B) goto <D.20324>; else goto <D.20325>;
  <D.20324>:
  {
    int i;

    i = 0;
    goto <D.18614>;
    <D.18613>:
    {
      struct MonoObject * * __p;

      D.20323 = thread->cached_culture_info;
      i.25 = (unsigned int) i;
      __p = mono_array_addr_with_size (D.20323, 4, i.25);
      *__p = 0B;
    }
    i = i + 1;
    <D.18614>:
    if (i <= 7) goto <D.18613>; else goto <D.18615>;
    <D.18615>:
  }
  <D.20325>:
  D.20327 = thread->synch_cs;
  if (D.20327 != 0B) goto <D.20328>; else goto <D.20329>;
  <D.20328>:
  lock_thread (thread);
  goto <D.20330>;
  <D.20329>:
  shutting_down.26 = shutting_down;
  D.20332 = shutting_down.26 == 0;
  D.20333 = (long int) D.20332;
  D.20334 = __builtin_expect (D.20333, 0);
  if (D.20334 != 0) goto <D.20335>; else goto <D.20336>;
  <D.20335>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 391, "shutting_down");
  <D.20336>:
  <D.20330>:
  D.20337 = thread->state;
  D.20338 = D.20337 | 16;
  thread->state = D.20338;
  D.20337 = thread->state;
  D.20339 = D.20337 & 4294967291;
  thread->state = D.20339;
  D.20327 = thread->synch_cs;
  if (D.20327 != 0B) goto <D.20340>; else goto <D.20341>;
  <D.20340>:
  unlock_thread (thread);
  <D.20341>:
  D.20342 = &thread->interruption_requested;
  D.20343 = InterlockedExchange (D.20342, 0);
  if (D.20343 != 0) goto <D.20344>; else goto <D.20345>;
  <D.20344>:
  InterlockedDecrement (&thread_interruption_requested);
  <D.20345>:
  D.20346 = handle_remove (thread);
  if (D.20346 == 0) goto <D.20347>; else goto <D.20348>;
  <D.20347>:
  D.20349 = mono_thread_internal_current ();
  if (D.20349 == thread) goto <D.20350>; else goto <D.20351>;
  <D.20350>:
  mono_domain_unset ();
  mono_memory_barrier ();
  <D.20351>:
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  if (mono_thread_cleanup_fn.27 != 0B) goto <D.20353>; else goto <D.20354>;
  <D.20353>:
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  mono_thread_cleanup_fn.27 (thread);
  <D.20354>:
  return;
  <D.20348>:
  mono_release_type_locks (thread);
  D.20355 = thread->tid;
  D.20356 = (unsigned int) D.20355;
  mono_profiler_thread_end (D.20356);
  D.20357 = mono_thread_internal_current ();
  if (D.20357 == thread) goto <D.20358>; else goto <D.20359>;
  <D.20358>:
  mono_domain_unset ();
  mono_memory_barrier ();
  <D.20359>:
  D.20360 = mono_thread_internal_current ();
  if (D.20360 == thread) goto <D.20361>; else goto <D.20362>;
  <D.20361>:
  mono_thread_pop_appdomain_ref ();
  <D.20362>:
  thread->cached_culture_info = 0B;
  D.20363 = thread->static_data;
  mono_free_static_data (D.20363, 1);
  thread->static_data = 0B;
  D.20364 = thread->appdomain_refs;
  ref_stack_destroy (D.20364);
  thread->appdomain_refs = 0B;
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  if (mono_thread_cleanup_fn.27 != 0B) goto <D.20365>; else goto <D.20366>;
  <D.20365>:
  mono_thread_cleanup_fn.27 = mono_thread_cleanup_fn;
  mono_thread_cleanup_fn.27 (thread);
  <D.20366>:
  D.20367 = mono_gc_is_moving ();
  if (D.20367 != 0) goto <D.20368>; else goto <D.20369>;
  <D.20368>:
  D.20370 = &thread->thread_pinning_ref;
  mono_gc_deregister_root (D.20370);
  thread->thread_pinning_ref = 0B;
  <D.20369>:
}


lock_thread (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.20372;
  _Bool D.20375;
  long int D.20376;
  long int D.20377;
  union mono_mutex_t * D.20380;
  _Bool D.20383;
  long int D.20384;
  long int D.20385;

  D.20372 = thread->synch_cs;
  if (D.20372 == 0B) goto <D.20373>; else goto <D.20374>;
  <D.20373>:
  ensure_synch_cs_set (thread);
  <D.20374>:
  D.20372 = thread->synch_cs;
  D.20375 = D.20372 == 0B;
  D.20376 = (long int) D.20375;
  D.20377 = __builtin_expect (D.20376, 0);
  if (D.20377 != 0) goto <D.20378>; else goto <D.20379>;
  <D.20378>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 351, "thread->synch_cs");
  <D.20379>:
  {
    int ret;

    D.20372 = thread->synch_cs;
    D.20380 = &D.20372->mutex;
    ret = pthread_mutex_lock (D.20380);
    if (ret != 0) goto <D.20381>; else goto <D.20382>;
    <D.20381>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20382>:
    D.20383 = ret != 0;
    D.20384 = (long int) D.20383;
    D.20385 = __builtin_expect (D.20384, 0);
    if (D.20385 != 0) goto <D.20386>; else goto <D.20387>;
    <D.20386>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 352, "ret == 0");
    <D.20387>:
  }
}


ensure_synch_cs_set (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.20388;
  struct CRITICAL_SECTION * * D.20391;
  void * D.20392;
  struct CRITICAL_SECTION * synch_cs;

  D.20388 = thread->synch_cs;
  if (D.20388 != 0B) goto <D.20389>; else goto <D.20390>;
  <D.20389>:
  return;
  <D.20390>:
  synch_cs = monoeg_malloc0 (28);
  InitializeCriticalSection (synch_cs);
  D.20391 = &thread->synch_cs;
  D.20392 = InterlockedCompareExchangePointer (D.20391, synch_cs, 0B);
  if (D.20392 != 0B) goto <D.20393>; else goto <D.20394>;
  <D.20393>:
  DeleteCriticalSection (synch_cs);
  monoeg_g_free (synch_cs);
  <D.20394>:
}


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

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


unlock_thread (struct MonoInternalThread * thread)
{
  struct CRITICAL_SECTION * D.20401;
  union mono_mutex_t * D.20402;
  _Bool D.20405;
  long int D.20406;
  long int D.20407;

  {
    int ret;

    D.20401 = thread->synch_cs;
    D.20402 = &D.20401->mutex;
    ret = pthread_mutex_unlock (D.20402);
    if (ret != 0) goto <D.20403>; else goto <D.20404>;
    <D.20403>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20404>:
    D.20405 = ret != 0;
    D.20406 = (long int) D.20405;
    D.20407 = __builtin_expect (D.20406, 0);
    if (D.20407 != 0) goto <D.20408>; else goto <D.20409>;
    <D.20408>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 358, "ret == 0");
    <D.20409>:
  }
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int old_val.30;
  unsigned int new_val.31;
  unsigned int D.20412;
  int D.20413;
  gint32 D.20414;
  gint32 old_val;

  <D.18395>:
  old_val = *val;
  old_val.30 = (unsigned int) old_val;
  new_val.31 = (unsigned int) new_val;
  D.20412 = __sync_val_compare_and_swap_4 (val, old_val.30, new_val.31);
  D.20413 = (int) D.20412;
  if (D.20413 != old_val) goto <D.18395>; else goto <D.18396>;
  <D.18396>:
  D.20414 = old_val;
  return D.20414;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.20416;
  unsigned int D.20417;

  D.20417 = __sync_sub_and_fetch_4 (val, 1);
  D.20416 = (gint32) D.20417;
  return D.20416;
}


handle_remove (struct MonoInternalThread * thread)
{
  long long unsigned int D.20419;
  _Bool D.20422;
  long int D.20423;
  long int D.20424;
  struct MonoGHashTable * threads.32;
  const void * tid.33;
  void * D.20431;
  _Bool D.20438;
  long int D.20439;
  long int D.20440;
  gboolean D.20443;
  gboolean ret;
  gsize tid;

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

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20420>; else goto <D.20421>;
    <D.20420>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20421>:
    D.20422 = ret != 0;
    D.20423 = (long int) D.20422;
    D.20424 = __builtin_expect (D.20423, 0);
    if (D.20424 != 0) goto <D.20425>; else goto <D.20426>;
    <D.20425>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 289, "ret == 0");
    <D.20426>:
  }
  threads.32 = threads;
  if (threads.32 != 0B) goto <D.20428>; else goto <D.20429>;
  <D.20428>:
  threads.32 = threads;
  tid.33 = (const void *) tid;
  D.20431 = mono_g_hash_table_lookup (threads.32, tid.33);
  if (D.20431 == thread) goto <D.20432>; else goto <D.20433>;
  <D.20432>:
  threads.32 = threads;
  tid.33 = (const void *) tid;
  mono_g_hash_table_remove (threads.32, tid.33);
  ret = 1;
  goto <D.20434>;
  <D.20433>:
  ret = 0;
  <D.20434>:
  goto <D.20435>;
  <D.20429>:
  ret = 0;
  <D.20435>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20436>; else goto <D.20437>;
    <D.20436>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20437>:
    D.20438 = ret != 0;
    D.20439 = (long int) D.20438;
    D.20440 = __builtin_expect (D.20439, 0);
    if (D.20440 != 0) goto <D.20441>; else goto <D.20442>;
    <D.20441>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 308, "ret == 0");
    <D.20442>:
  }
  D.20443 = ret;
  return D.20443;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_free_static_data (void * * static_data, gboolean threadlocal)
{
  unsigned int i.34;
  unsigned int D.20446;
  void * * D.20447;
  int D.20452;
  int i;

  i = 1;
  goto <D.19643>;
  <D.19642>:
  {
    void * p;

    i.34 = (unsigned int) i;
    D.20446 = i.34 * 4;
    D.20447 = static_data + D.20446;
    p = *D.20447;
    if (p == 0B) goto <D.20448>; else goto <D.20449>;
    <D.20448>:
    // predicted unlikely by continue predictor.
    goto <D.19641>;
    <D.20449>:
    i.34 = (unsigned int) i;
    D.20446 = i.34 * 4;
    D.20447 = static_data + D.20446;
    *D.20447 = 0B;
    mono_memory_write_barrier ();
    D.20452 = mono_gc_user_markers_supported ();
    if (D.20452 != 0) goto <D.20453>; else goto <D.20450>;
    <D.20453>:
    if (threadlocal != 0) goto <D.20454>; else goto <D.20450>;
    <D.20454>:
    monoeg_g_free (p);
    goto <D.20451>;
    <D.20450>:
    mono_gc_free_fixed (p);
    <D.20451>:
  }
  <D.19641>:
  i = i + 1;
  <D.19643>:
  if (i <= 7) goto <D.19642>; else goto <D.19644>;
  <D.19644>:
  mono_gc_free_fixed (static_data);
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


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

  rs = ptr;
  if (rs != 0B) goto <D.20455>; else goto <D.20456>;
  <D.20455>:
  D.20457 = rs->refs;
  monoeg_g_free (D.20457);
  monoeg_g_free (rs);
  <D.20456>:
}


mono_native_tls_set_value (pthread_key_t key, void * value)
{
  int D.20458;
  int D.20459;
  _Bool D.20460;

  D.20459 = pthread_setspecific (key, value);
  D.20460 = D.20459 == 0;
  D.20458 = (int) D.20460;
  return D.20458;
}


handle_store (struct MonoThread * thread, gboolean force_attach)
{
  _Bool D.20464;
  long int D.20465;
  long int D.20466;
  struct MonoGHashTable * threads_starting_up.35;
  int shutting_down.36;
  _Bool D.20479;
  long int D.20480;
  long int D.20481;
  gboolean D.20484;
  struct MonoGHashTable * threads.37;
  int D.20488;
  struct MonoGHashTable * threads.38;
  struct _MonoInternalThread * D.20492;
  _Bool D.20493;
  long int D.20494;
  long int D.20495;
  long long unsigned int D.20498;
  unsigned int D.20499;
  void * D.20500;
  _Bool D.20503;
  long int D.20504;
  long int D.20505;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20462>; else goto <D.20463>;
    <D.20462>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20463>:
    D.20464 = ret != 0;
    D.20465 = (long int) D.20464;
    D.20466 = __builtin_expect (D.20465, 0);
    if (D.20466 != 0) goto <D.20467>; else goto <D.20468>;
    <D.20467>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 253, "ret == 0");
    <D.20468>:
  }
  threads_starting_up.35 = threads_starting_up;
  if (threads_starting_up.35 != 0B) goto <D.20470>; else goto <D.20471>;
  <D.20470>:
  threads_starting_up.35 = threads_starting_up;
  mono_g_hash_table_remove (threads_starting_up.35, thread);
  <D.20471>:
  shutting_down.36 = shutting_down;
  if (shutting_down.36 != 0) goto <D.20473>; else goto <D.20474>;
  <D.20473>:
  if (force_attach == 0) goto <D.20475>; else goto <D.20476>;
  <D.20475>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20477>; else goto <D.20478>;
    <D.20477>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20478>:
    D.20479 = ret != 0;
    D.20480 = (long int) D.20479;
    D.20481 = __builtin_expect (D.20480, 0);
    if (D.20481 != 0) goto <D.20482>; else goto <D.20483>;
    <D.20482>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 261, "ret == 0");
    <D.20483>:
  }
  D.20484 = 0;
  return D.20484;
  <D.20476>:
  <D.20474>:
  threads.37 = threads;
  if (threads.37 == 0B) goto <D.20486>; else goto <D.20487>;
  <D.20486>:
  D.20488 = mono_gc_is_moving ();
  if (D.20488 == 0) goto <D.20489>; else goto <D.20490>;
  <D.20489>:
  mono_gc_register_root (&threads, 4, 0B);
  <D.20490>:
  threads.38 = mono_g_hash_table_new_type (0B, 0B, 2);
  threads = threads.38;
  <D.20487>:
  D.20492 = thread->internal_thread;
  D.20493 = D.20492 == 0B;
  D.20494 = (long int) D.20493;
  D.20495 = __builtin_expect (D.20494, 0);
  if (D.20495 != 0) goto <D.20496>; else goto <D.20497>;
  <D.20496>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 273, "thread->internal_thread");
  <D.20497>:
  threads.37 = threads;
  D.20492 = thread->internal_thread;
  D.20498 = D.20492->tid;
  D.20499 = (unsigned int) D.20498;
  D.20500 = (void *) D.20499;
  D.20492 = thread->internal_thread;
  mono_g_hash_table_insert (threads.37, D.20500, D.20492);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.20501>; else goto <D.20502>;
    <D.20501>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20502>:
    D.20503 = ret != 0;
    D.20504 = (long int) D.20503;
    D.20505 = __builtin_expect (D.20504, 0);
    if (D.20505 != 0) goto <D.20506>; else goto <D.20507>;
    <D.20506>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 277, "ret == 0");
    <D.20507>:
  }
  D.20484 = 1;
  return D.20484;
}


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


mono_thread_get_stack_bounds (guint8 * * staddr, size_t * stsize)
{
  long unsigned int D.20509;
  guint8 * D.20510;
  int iftmp.39;
  unsigned int D.20518;
  guint8 * D.20519;
  _Bool D.20520;
  long int D.20521;
  long int D.20522;
  int D.20525;
  int D.20526;
  int D.20527;
  int D.20528;
  guint8 * D.20529;
  union pthread_attr_t attr;
  guint8 * current;

  try
    {
      current = &attr;
      *staddr = 0B;
      *stsize = 4294967295;
      pthread_attr_init (&attr);
      D.20509 = pthread_self ();
      pthread_getattr_np (D.20509, &attr);
      pthread_attr_getstack (&attr, staddr, stsize);
      pthread_attr_destroy (&attr);
      D.20510 = *staddr;
      if (D.20510 != 0B) goto <D.20511>; else goto <D.20512>;
      <D.20511>:
      D.20510 = *staddr;
      if (D.20510 >= current) goto <D.20514>; else goto <D.20517>;
      <D.20517>:
      D.20510 = *staddr;
      D.20518 = *stsize;
      D.20519 = D.20510 + D.20518;
      if (D.20519 <= current) goto <D.20514>; else goto <D.20515>;
      <D.20514>:
      iftmp.39 = 1;
      goto <D.20516>;
      <D.20515>:
      iftmp.39 = 0;
      <D.20516>:
      D.20520 = iftmp.39 != 0;
      D.20521 = (long int) D.20520;
      D.20522 = __builtin_expect (D.20521, 0);
      if (D.20522 != 0) goto <D.20523>; else goto <D.20524>;
      <D.20523>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 944, "(current > *staddr) && (current < *staddr + *stsize)");
      <D.20524>:
      <D.20512>:
      D.20510 = *staddr;
      D.20525 = (int) D.20510;
      D.20526 = mono_pagesize ();
      D.20527 = -D.20526;
      D.20528 = D.20525 & D.20527;
      D.20529 = (guint8 *) D.20528;
      *staddr = D.20529;
      return;
    }
  finally
    {
      attr = {CLOBBER};
    }
}


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

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


mono_thread_attach_full (struct MonoDomain * domain, gboolean force_attach)
{
  struct MonoDomain * D.20536;
  struct MonoDomain * domain.40;
  struct MonoThread * D.20540;
  int D.20541;
  unsigned int D.20544;
  void * thread_handle.41;
  void * thread_handle.42;
  _Bool D.20547;
  long int D.20548;
  long int D.20549;
  unsigned int tid.43;
  void * D.20553;
  void * D.20554;
  unsigned int tid.44;
  long long unsigned int D.20556;
  _Bool D.20557;
  long int D.20558;
  long int D.20559;
  int D.20562;
  unsigned int current_object_key.45;
  struct MonoDomain * D.20566;
  void (*<T12f5>) (intptr_t, void *) mono_thread_attach_cb.46;
  guint8 * staddr.47;
  int tid.48;
  unsigned int stsize.49;
  void * D.20578;
  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.20534>; else goto <D.20535>;
      <D.20534>:
      D.20536 = mono_domain_get ();
      domain.40 = domain;
      if (D.20536 != domain.40) goto <D.20538>; else goto <D.20539>;
      <D.20538>:
      domain.40 = domain;
      mono_domain_set (domain.40, 1);
      <D.20539>:
      D.20540 = mono_thread_current ();
      return D.20540;
      <D.20535>:
      D.20541 = mono_gc_register_thread (&domain);
      if (D.20541 == 0) goto <D.20542>; else goto <D.20543>;
      <D.20542>:
      D.20544 = GetCurrentThreadId ();
      monoeg_g_log (0B, 4, "Thread %u calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", D.20544);
      <D.18739>:
      goto <D.18739>;
      <D.20543>:
      thread = create_internal_thread ();
      thread_handle.41 = GetCurrentThread ();
      thread_handle = thread_handle.41;
      thread_handle.42 = thread_handle;
      D.20547 = thread_handle.42 == 0B;
      D.20548 = (long int) D.20547;
      D.20549 = __builtin_expect (D.20548, 0);
      if (D.20549 != 0) goto <D.20550>; else goto <D.20551>;
      <D.20550>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1028, "thread_handle");
      <D.20551>:
      tid.43 = GetCurrentThreadId ();
      tid = tid.43;
      D.20553 = GetCurrentProcess ();
      thread_handle.42 = thread_handle;
      D.20554 = GetCurrentProcess ();
      DuplicateHandle (D.20553, thread_handle.42, D.20554, &thread_handle, 2032639, 1, 0);
      thread_handle.42 = thread_handle;
      thread->handle = thread_handle.42;
      tid.44 = tid;
      D.20556 = (long long unsigned int) tid.44;
      thread->tid = D.20556;
      thread->stack_ptr = &tid;
      info = mono_thread_info_current ();
      D.20557 = info == 0B;
      D.20558 = (long int) D.20557;
      D.20559 = __builtin_expect (D.20558, 0);
      if (D.20559 != 0) goto <D.20560>; else goto <D.20561>;
      <D.20560>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1049, "info");
      <D.20561>:
      thread->thread_info = info;
      domain.40 = domain;
      current_thread = new_thread_with_internal (domain.40, thread);
      D.20562 = handle_store (current_thread, force_attach);
      if (D.20562 == 0) goto <D.20563>; else goto <D.20564>;
      <D.20563>:
      <D.18740>:
      Sleep (10000);
      goto <D.18740>;
      <D.20564>:
      tls_current_object = thread;
      current_object_key.45 = current_object_key;
      mono_native_tls_set_value (current_object_key.45, thread);
      domain.40 = domain;
      mono_domain_set (domain.40, 1);
      mono_monitor_init_tls ();
      thread_adjust_static_data (thread);
      init_root_domain_thread (thread, current_thread);
      D.20566 = mono_get_root_domain ();
      domain.40 = domain;
      if (D.20566 != domain.40) goto <D.20567>; else goto <D.20568>;
      <D.20567>:
      domain.40 = domain;
      set_current_thread_for_domain (domain.40, thread, current_thread);
      <D.20568>:
      mono_thread_attach_cb.46 = mono_thread_attach_cb;
      if (mono_thread_attach_cb.46 != 0B) goto <D.20570>; else goto <D.20571>;
      <D.20570>:
      {
        guint8 * staddr;
        size_t stsize;

        try
          {
            mono_thread_get_stack_bounds (&staddr, &stsize);
            staddr.47 = staddr;
            if (staddr.47 == 0B) goto <D.20573>; else goto <D.20574>;
            <D.20573>:
            mono_thread_attach_cb.46 = mono_thread_attach_cb;
            tid.44 = tid;
            tid.48 = (int) tid.44;
            mono_thread_attach_cb.46 (tid.48, &tid);
            goto <D.20576>;
            <D.20574>:
            mono_thread_attach_cb.46 = mono_thread_attach_cb;
            tid.44 = tid;
            tid.48 = (int) tid.44;
            staddr.47 = staddr;
            stsize.49 = stsize;
            D.20578 = staddr.47 + stsize.49;
            mono_thread_attach_cb.46 (tid.48, D.20578);
            <D.20576>:
          }
        finally
          {
            staddr = {CLOBBER};
            stsize = {CLOBBER};
          }
      }
      <D.20571>:
      tid.44 = tid;
      mono_profiler_thread_start (tid.44);
      D.20540 = current_thread;
      return D.20540;
    }
  finally
    {
      thread_handle = {CLOBBER};
      tid = {CLOBBER};
    }
}


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

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


mono_thread_exit ()
{
  unsigned int current_object_key.51;
  struct MonoThread * D.20587;
  struct MonoThread * D.20590;
  struct _MonoInternalThread * D.20591;
  int D.20594;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  thread_cleanup (thread);
  tls_current_object = 0B;
  current_object_key.51 = current_object_key;
  mono_native_tls_set_value (current_object_key.51, 0B);
  mono_domain_unset ();
  D.20587 = mono_thread_get_main ();
  if (D.20587 != 0B) goto <D.20588>; else goto <D.20589>;
  <D.20588>:
  D.20590 = mono_thread_get_main ();
  D.20591 = D.20590->internal_thread;
  if (D.20591 == thread) goto <D.20592>; else goto <D.20593>;
  <D.20592>:
  D.20594 = mono_environment_exitcode_get ();
  exit (D.20594);
  <D.20593>:
  <D.20589>:
  ExitThread (4294967295);
}


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

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


ves_icall_System_Threading_Thread_Thread_internal (struct MonoThread * this, struct MonoObject * start)
{
  struct _MonoInternalThread * D.20596;
  unsigned int D.20599;
  unsigned int D.20600;
  struct MonoException * D.20603;
  void * D.20604;
  unsigned int D.20605;
  struct MonoObject * D.20608;
  struct MonoVTable * D.20609;
  struct MonoDomain * D.20610;
  struct MonoDomain * D.20611;
  _Bool D.20612;
  long int D.20613;
  long int D.20614;
  unsigned int D.20619;
  struct StartInfo * start_info;
  struct MonoInternalThread * internal;
  gboolean res;

  D.20596 = this->internal_thread;
  if (D.20596 == 0B) goto <D.20597>; else goto <D.20598>;
  <D.20597>:
  ves_icall_System_Threading_Thread_ConstructInternalThread (this);
  <D.20598>:
  internal = this->internal_thread;
  lock_thread (internal);
  D.20599 = internal->state;
  D.20600 = D.20599 & 8;
  if (D.20600 == 0) goto <D.20601>; else goto <D.20602>;
  <D.20601>:
  unlock_thread (internal);
  D.20603 = mono_get_exception_thread_state ("Thread has already been started.");
  mono_raise_exception (D.20603);
  D.20604 = 0B;
  return D.20604;
  <D.20602>:
  D.20599 = internal->state;
  D.20605 = D.20599 & 256;
  if (D.20605 != 0) goto <D.20606>; else goto <D.20607>;
  <D.20606>:
  unlock_thread (internal);
  D.20604 = this;
  return D.20604;
  <D.20607>:
  start_info = monoeg_malloc0 (16);
  start_info->func = 0B;
  D.20608 = this->start_obj;
  start_info->start_arg = D.20608;
  start_info->delegate = start;
  start_info->obj = this;
  D.20609 = this->obj.vtable;
  D.20610 = D.20609->domain;
  D.20611 = mono_domain_get ();
  D.20612 = D.20610 != D.20611;
  D.20613 = (long int) D.20612;
  D.20614 = __builtin_expect (D.20613, 0);
  if (D.20614 != 0) goto <D.20615>; else goto <D.20616>;
  <D.20615>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1169, "this->obj.vtable->domain == mono_domain_get ()");
  <D.20616>:
  res = create_thread (this, internal, start_info, 0, 0, 0, 0);
  if (res == 0) goto <D.20617>; else goto <D.20618>;
  <D.20617>:
  unlock_thread (internal);
  D.20604 = 0B;
  return D.20604;
  <D.20618>:
  D.20599 = internal->state;
  D.20619 = D.20599 & 4294967287;
  internal->state = D.20619;
  unlock_thread (internal);
  D.20604 = internal->handle;
  return D.20604;
}


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

  if (thread != 0B) goto <D.20621>; else goto <D.20622>;
  <D.20621>:
  CloseHandle (thread);
  <D.20622>:
  D.20623 = this->synch_cs;
  if (D.20623 != 0B) goto <D.20624>; else goto <D.20625>;
  <D.20624>:
  {
    struct CRITICAL_SECTION * synch_cs;

    synch_cs = this->synch_cs;
    this->synch_cs = 0B;
    DeleteCriticalSection (synch_cs);
    monoeg_g_free (synch_cs);
  }
  <D.20625>:
  D.20626 = this->name;
  if (D.20626 != 0B) goto <D.20627>; else goto <D.20628>;
  <D.20627>:
  {
    void * name;

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


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

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

    exc = mono_thread_execute_interruption (thread);
    if (exc != 0B) goto <D.20631>; else goto <D.20632>;
    <D.20631>:
    mono_raise_exception (exc);
    goto <D.20633>;
    <D.20632>:
    if (ms != -1) goto <D.18772>; else goto <D.20634>;
    <D.20634>:
    <D.20633>:
  }
  goto <D.18773>;
  <D.18772>:
}


mono_thread_execute_interruption (struct MonoInternalThread * thread)
{
  gint32 * D.20635;
  int D.20636;
  void * D.20639;
  unsigned int D.20640;
  unsigned int D.20641;
  struct MonoException * D.20644;
  struct MonoException * * D.20647;
  struct MonoException * D.20648;
  struct MonoException * D.20649;
  unsigned int D.20650;
  unsigned int D.20653;
  struct MonoException * D.20656;
  unsigned char D.20659;

  lock_thread (thread);
  D.20635 = &thread->interruption_requested;
  D.20636 = InterlockedCompareExchange (D.20635, 0, 1);
  if (D.20636 != 0) goto <D.20637>; else goto <D.20638>;
  <D.20637>:
  D.20639 = GetCurrentThread ();
  WaitForSingleObjectEx (D.20639, 0, 1);
  InterlockedDecrement (&thread_interruption_requested);
  wapi_clear_interruption ();
  <D.20638>:
  D.20640 = thread->state;
  D.20641 = D.20640 & 128;
  if (D.20641 != 0) goto <D.20642>; else goto <D.20643>;
  <D.20642>:
  unlock_thread (thread);
  D.20644 = thread->abort_exc;
  if (D.20644 == 0B) goto <D.20645>; else goto <D.20646>;
  <D.20645>:
  D.20647 = &thread->abort_exc;
  D.20648 = mono_get_exception_thread_abort ();
  mono_gc_wbarrier_set_field (thread, D.20647, D.20648);
  <D.20646>:
  D.20649 = thread->abort_exc;
  return D.20649;
  <D.20643>:
  D.20640 = thread->state;
  D.20650 = D.20640 & 2;
  if (D.20650 != 0) goto <D.20651>; else goto <D.20652>;
  <D.20651>:
  self_suspend_internal (thread);
  D.20649 = 0B;
  return D.20649;
  <D.20652>:
  D.20640 = thread->state;
  D.20653 = D.20640 & 1;
  if (D.20653 != 0) goto <D.20654>; else goto <D.20655>;
  <D.20654>:
  unlock_thread (thread);
  mono_thread_exit ();
  D.20649 = 0B;
  return D.20649;
  <D.20655>:
  D.20656 = thread->pending_exception;
  if (D.20656 != 0B) goto <D.20657>; else goto <D.20658>;
  <D.20657>:
  {
    struct MonoException * exc;

    exc = thread->pending_exception;
    thread->pending_exception = 0B;
    unlock_thread (thread);
    D.20649 = exc;
    return D.20649;
  }
  <D.20658>:
  D.20659 = thread->thread_interrupt_requested;
  if (D.20659 != 0) goto <D.20660>; else goto <D.20661>;
  <D.20660>:
  thread->thread_interrupt_requested = 0;
  unlock_thread (thread);
  D.20649 = mono_get_exception_thread_interrupted ();
  return D.20649;
  <D.20661>:
  unlock_thread (thread);
  D.20649 = 0B;
  return D.20649;
}


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

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


self_suspend_internal (struct MonoInternalThread * thread)
{
  int D.20668;
  unsigned int D.20671;
  unsigned int D.20672;
  unsigned int D.20673;
  void * D.20674;
  void * D.20675;
  void * D.20678;
  int shutting_down.55;
  unsigned int D.20684;
  void * D.20685;

  D.20668 = mono_thread_info_new_interrupt_enabled ();
  if (D.20668 == 0) goto <D.20669>; else goto <D.20670>;
  <D.20669>:
  D.20671 = thread->state;
  D.20672 = D.20671 & 4294967293;
  thread->state = D.20672;
  D.20671 = thread->state;
  D.20673 = D.20671 | 64;
  thread->state = D.20673;
  D.20674 = CreateEvent (0B, 1, 0, 0B);
  thread->suspend_event = D.20674;
  D.20675 = thread->suspend_event;
  if (D.20675 == 0B) goto <D.20676>; else goto <D.20677>;
  <D.20676>:
  unlock_thread (thread);
  return;
  <D.20677>:
  D.20678 = thread->suspended_event;
  if (D.20678 != 0B) goto <D.20679>; else goto <D.20680>;
  <D.20679>:
  D.20678 = thread->suspended_event;
  SetEvent (D.20678);
  <D.20680>:
  unlock_thread (thread);
  shutting_down.55 = shutting_down;
  if (shutting_down.55 != 0) goto <D.20682>; else goto <D.20683>;
  <D.20682>:
  <D.19948>:
  Sleep (1000);
  goto <D.19948>;
  <D.20683>:
  D.20675 = thread->suspend_event;
  WaitForSingleObject (D.20675, 4294967295);
  lock_thread (thread);
  D.20675 = thread->suspend_event;
  CloseHandle (D.20675);
  thread->suspend_event = 0B;
  D.20671 = thread->state;
  D.20684 = D.20671 & 4294967231;
  thread->state = D.20684;
  D.20685 = thread->resume_event;
  SetEvent (D.20685);
  unlock_thread (thread);
  return;
  <D.20670>:
  transition_to_suspended (thread);
  mono_thread_info_self_suspend ();
}


transition_to_suspended (struct MonoInternalThread * thread)
{
  unsigned int D.20687;
  unsigned int D.20688;
  long long unsigned int D.20693;
  long unsigned int D.20694;
  unsigned int D.20696;
  unsigned int D.20697;

  D.20687 = thread->state;
  D.20688 = D.20687 & 2;
  if (D.20688 == 0) goto <D.20689>; else goto <D.20690>;
  <D.20689>:
  if (1 != 0) goto <D.20691>; else goto <D.20692>;
  <D.20691>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4693, "0");
  <D.20692>:
  D.20693 = thread->tid;
  D.20694 = (long unsigned int) D.20693;
  mono_thread_info_resume (D.20694);
  goto <D.20695>;
  <D.20690>:
  D.20687 = thread->state;
  D.20696 = D.20687 & 4294967293;
  thread->state = D.20696;
  D.20687 = thread->state;
  D.20697 = D.20687 | 64;
  thread->state = D.20697;
  mono_thread_info_finish_suspend ();
  <D.20695>:
  unlock_thread (thread);
}


ves_icall_System_Threading_Thread_SpinWait_nop ()
{

}


ves_icall_System_Threading_Thread_GetDomainID ()
{
  gint32 D.20698;
  struct MonoDomain * D.20699;

  D.20699 = mono_domain_get ();
  D.20698 = D.20699->domain_id;
  return D.20698;
}


ves_icall_System_Threading_Thread_Yield ()
{
  gboolean D.20701;
  int D.20702;
  _Bool D.20703;

  D.20702 = sched_yield ();
  D.20703 = D.20702 == 0;
  D.20701 = (gboolean) D.20703;
  return D.20701;
}


mono_thread_get_name (struct MonoInternalThread * this_obj, guint32 * name_len)
{
  gunichar2 * D.20705;
  unsigned int D.20709;
  unsigned int D.20710;
  gunichar2 * D.20711;
  gunichar2 * res;

  lock_thread (this_obj);
  D.20705 = this_obj->name;
  if (D.20705 == 0B) goto <D.20706>; else goto <D.20707>;
  <D.20706>:
  *name_len = 0;
  res = 0B;
  goto <D.20708>;
  <D.20707>:
  D.20709 = this_obj->name_len;
  *name_len = D.20709;
  D.20709 = this_obj->name_len;
  D.20710 = D.20709 * 2;
  res = monoeg_malloc (D.20710);
  D.20705 = this_obj->name;
  D.20709 = this_obj->name_len;
  D.20710 = D.20709 * 2;
  memcpy (res, D.20705, D.20710);
  <D.20708>:
  unlock_thread (this_obj);
  D.20711 = res;
  return D.20711;
}


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

  D.20714 = __builtin_object_size (__dest, 0);
  D.20713 = __builtin___memcpy_chk (__dest, __src, __len, D.20714);
  return D.20713;
}


ves_icall_System_Threading_Thread_GetName_internal (struct MonoInternalThread * this_obj)
{
  gunichar2 * D.20716;
  struct MonoDomain * D.20720;
  unsigned int D.20721;
  int D.20722;
  struct MonoString * D.20723;
  struct MonoString * str;

  lock_thread (this_obj);
  D.20716 = this_obj->name;
  if (D.20716 == 0B) goto <D.20717>; else goto <D.20718>;
  <D.20717>:
  str = 0B;
  goto <D.20719>;
  <D.20718>:
  D.20720 = mono_domain_get ();
  D.20716 = this_obj->name;
  D.20721 = this_obj->name_len;
  D.20722 = (int) D.20721;
  str = mono_string_new_utf16 (D.20720, D.20716, D.20722);
  <D.20719>:
  unlock_thread (this_obj);
  D.20723 = str;
  return D.20723;
}


mono_thread_set_name_internal (struct MonoInternalThread * this_obj, struct MonoString * name, gboolean managed)
{
  unsigned int D.20725;
  unsigned int D.20726;
  struct MonoException * D.20729;
  int D.20732;
  unsigned int D.20733;
  unsigned int D.20734;
  void * D.20735;
  gunichar2 * D.20736;
  mono_unichar2 * D.20737;
  int D.20738;
  int D.20739;
  unsigned int D.20740;
  int D.20741;
  unsigned int D.20742;
  unsigned int D.20746;
  long long unsigned int D.20749;
  unsigned int D.20750;

  lock_thread (this_obj);
  D.20725 = this_obj->flags;
  D.20726 = D.20725 & 2;
  if (D.20726 != 0) goto <D.20727>; else goto <D.20728>;
  <D.20727>:
  unlock_thread (this_obj);
  D.20729 = mono_get_exception_invalid_operation ("Thread.Name can only be set once.");
  mono_raise_exception (D.20729);
  return;
  <D.20728>:
  if (name != 0B) goto <D.20730>; else goto <D.20731>;
  <D.20730>:
  D.20732 = mono_string_length (name);
  D.20733 = (unsigned int) D.20732;
  D.20734 = D.20733 * 2;
  D.20735 = monoeg_malloc (D.20734);
  this_obj->name = D.20735;
  D.20736 = this_obj->name;
  D.20737 = mono_string_chars (name);
  D.20738 = mono_string_length (name);
  D.20739 = D.20738 * 2;
  D.20740 = (unsigned int) D.20739;
  memcpy (D.20736, D.20737, D.20740);
  D.20741 = mono_string_length (name);
  D.20742 = (unsigned int) D.20741;
  this_obj->name_len = D.20742;
  goto <D.20743>;
  <D.20731>:
  this_obj->name = 0B;
  <D.20743>:
  if (managed != 0) goto <D.20744>; else goto <D.20745>;
  <D.20744>:
  D.20725 = this_obj->flags;
  D.20746 = D.20725 | 2;
  this_obj->flags = D.20746;
  <D.20745>:
  unlock_thread (this_obj);
  D.20736 = this_obj->name;
  if (D.20736 != 0B) goto <D.20747>; else goto <D.20748>;
  <D.20747>:
  {
    char * tname;

    tname = mono_string_to_utf8 (name);
    D.20749 = this_obj->tid;
    D.20750 = (unsigned int) D.20749;
    mono_profiler_thread_name (D.20750, tname);
    mono_free (tname);
  }
  <D.20748>:
}


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


ves_icall_System_Threading_Thread_ByteArrayToRootDomain (struct MonoArray * arr)
{
  struct MonoArray * D.20752;
  struct MonoDomain * D.20753;

  D.20753 = mono_get_root_domain ();
  D.20752 = byte_array_to_domain (arr, D.20753);
  return D.20752;
}


byte_array_to_domain (struct MonoArray * arr, struct MonoDomain * domain)
{
  struct MonoArray * D.20757;
  struct MonoVTable * D.20758;
  struct MonoDomain * D.20759;
  struct MonoClass * D.20762;
  unsigned int D.20763;
  char * D.20764;
  char * D.20765;
  struct MonoArray * copy;

  if (arr == 0B) goto <D.20755>; else goto <D.20756>;
  <D.20755>:
  D.20757 = 0B;
  return D.20757;
  <D.20756>:
  D.20758 = MEM[(struct MonoObject *)arr].vtable;
  D.20759 = D.20758->domain;
  if (D.20759 == domain) goto <D.20760>; else goto <D.20761>;
  <D.20760>:
  D.20757 = arr;
  return D.20757;
  <D.20761>:
  D.20762 = mono_defaults.byte_class;
  D.20763 = arr->max_length;
  copy = mono_array_new (domain, D.20762, D.20763);
  D.20764 = mono_array_addr_with_size (copy, 1, 0);
  D.20765 = mono_array_addr_with_size (arr, 1, 0);
  D.20763 = arr->max_length;
  memmove (D.20764, D.20765, D.20763);
  D.20757 = copy;
  return D.20757;
}


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

  D.20768 = __builtin_object_size (__dest, 0);
  D.20767 = __builtin___memmove_chk (__dest, __src, __len, D.20768);
  return D.20767;
}


ves_icall_System_Threading_Thread_ByteArrayToCurrentDomain (struct MonoArray * arr)
{
  struct MonoArray * D.20770;
  struct MonoDomain * D.20771;

  D.20771 = mono_domain_get ();
  D.20770 = byte_array_to_domain (arr, D.20771);
  return D.20770;
}


mono_thread_current ()
{
  _Bool D.20773;
  long int D.20774;
  long int D.20775;
  struct MonoThread * D.20778;
  struct MonoDomain * D.20781;
  _Bool D.20782;
  long int D.20783;
  long int D.20784;
  struct MonoThread * D.20787;
  struct MonoThread * D.20788;
  struct MonoDomain * domain;
  struct MonoInternalThread * internal;
  struct MonoThread * * current_thread_ptr;

  domain = mono_domain_get ();
  internal = mono_thread_internal_current ();
  D.20773 = internal == 0B;
  D.20774 = (long int) D.20773;
  D.20775 = __builtin_expect (D.20774, 0);
  if (D.20775 != 0) goto <D.20776>; else goto <D.20777>;
  <D.20776>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1382, "internal");
  <D.20777>:
  current_thread_ptr = get_current_thread_ptr_for_domain (domain, internal);
  D.20778 = *current_thread_ptr;
  if (D.20778 == 0B) goto <D.20779>; else goto <D.20780>;
  <D.20779>:
  D.20781 = mono_get_root_domain ();
  D.20782 = D.20781 == domain;
  D.20783 = (long int) D.20782;
  D.20784 = __builtin_expect (D.20783, 0);
  if (D.20784 != 0) goto <D.20785>; else goto <D.20786>;
  <D.20785>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1386, "domain != mono_get_root_domain ()");
  <D.20786>:
  D.20787 = new_thread_with_internal (domain, internal);
  *current_thread_ptr = D.20787;
  <D.20780>:
  D.20788 = *current_thread_ptr;
  return D.20788;
}


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

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


ves_icall_System_Threading_Thread_Join_internal (struct MonoInternalThread * this, int ms, void * thread)
{
  unsigned int D.20792;
  unsigned int D.20793;
  struct MonoException * D.20796;
  gboolean D.20797;
  unsigned int ms.56;
  unsigned int D.20801;
  struct MonoInternalThread * cur_thread;
  gboolean ret;

  cur_thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  lock_thread (this);
  D.20792 = this->state;
  D.20793 = D.20792 & 8;
  if (D.20793 != 0) goto <D.20794>; else goto <D.20795>;
  <D.20794>:
  unlock_thread (this);
  D.20796 = mono_get_exception_thread_state ("Thread has not been started.");
  mono_raise_exception (D.20796);
  D.20797 = 0;
  return D.20797;
  <D.20795>:
  unlock_thread (this);
  if (ms == -1) goto <D.20798>; else goto <D.20799>;
  <D.20798>:
  ms = -1;
  <D.20799>:
  mono_thread_set_state (cur_thread, 32);
  ms.56 = (unsigned int) ms;
  D.20801 = WaitForSingleObjectEx (thread, ms.56, 1);
  ret = (gboolean) D.20801;
  mono_thread_clr_state (cur_thread, 32);
  if (ret == 0) goto <D.20802>; else goto <D.20803>;
  <D.20802>:
  D.20797 = 1;
  return D.20797;
  <D.20803>:
  D.20797 = 0;
  return D.20797;
}


ves_icall_System_Threading_WaitHandle_WaitAll_internal (struct MonoArray * mono_handles, gint32 ms, gboolean exitContext)
{
  unsigned int D.20805;
  char * D.20806;
  unsigned int D.20807;
  void * * D.20808;
  void * D.20809;
  int D.20812;
  gboolean D.20815;
  void * * handles;
  guint32 numhandles;
  guint32 ret;
  guint32 i;
  struct MonoObject * waitHandle;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  mono_thread_current_check_pending_interrupt ();
  numhandles = mono_array_length (mono_handles);
  D.20805 = numhandles * 4;
  handles = monoeg_malloc0 (D.20805);
  i = 0;
  goto <D.18859>;
  <D.18858>:
  D.20806 = mono_array_addr_with_size (mono_handles, 4, i);
  waitHandle = MEM[(struct MonoObject * *)D.20806];
  D.20807 = i * 4;
  D.20808 = handles + D.20807;
  D.20809 = mono_wait_handle_get_handle (waitHandle);
  *D.20808 = D.20809;
  i = i + 1;
  <D.18859>:
  if (i < numhandles) goto <D.18858>; else goto <D.18860>;
  <D.18860>:
  if (ms == -1) goto <D.20810>; else goto <D.20811>;
  <D.20810>:
  ms = -1;
  <D.20811>:
  mono_thread_set_state (thread, 32);
  D.20812 = mono_wait_uninterrupted (thread, 1, numhandles, handles, 1, ms, 1);
  ret = (guint32) D.20812;
  mono_thread_clr_state (thread, 32);
  monoeg_g_free (handles);
  if (ret == 4294967295) goto <D.20813>; else goto <D.20814>;
  <D.20813>:
  D.20815 = 0;
  return D.20815;
  <D.20814>:
  if (ret == 258) goto <D.20816>; else goto <D.20817>;
  <D.20816>:
  D.20815 = 0;
  return D.20815;
  <D.20817>:
  D.20815 = 1;
  return D.20815;
}


mono_wait_uninterrupted (struct MonoInternalThread * thread, gboolean multiple, guint32 numhandles, void * * handles, gboolean waitall, gint32 ms, gboolean alertable)
{
  gint64 iftmp.57;
  unsigned int wait.58;
  void * D.20827;
  unsigned int ms.59;
  long long int D.20834;
  long long int D.20835;
  long long int D.20836;
  gint32 D.20839;
  struct MonoException * exc;
  guint32 ret;
  gint64 start;
  gint32 diff_ms;
  gint32 wait;

  wait = ms;
  if (ms != -1) goto <D.20820>; else goto <D.20821>;
  <D.20820>:
  iftmp.57 = mono_100ns_ticks ();
  goto <D.20822>;
  <D.20821>:
  iftmp.57 = 0;
  <D.20822>:
  start = iftmp.57;
  <D.18846>:
  if (multiple != 0) goto <D.20823>; else goto <D.20824>;
  <D.20823>:
  wait.58 = (unsigned int) wait;
  ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait.58, alertable);
  goto <D.20826>;
  <D.20824>:
  D.20827 = *handles;
  ms.59 = (unsigned int) ms;
  ret = WaitForSingleObjectEx (D.20827, ms.59, alertable);
  <D.20826>:
  if (ret != 192) goto <D.18844>; else goto <D.20829>;
  <D.20829>:
  exc = mono_thread_execute_interruption (thread);
  if (exc != 0B) goto <D.20830>; else goto <D.20831>;
  <D.20830>:
  mono_raise_exception (exc);
  <D.20831>:
  if (ms == -1) goto <D.20832>; else goto <D.20833>;
  <D.20832>:
  // predicted unlikely by continue predictor.
  goto <D.18845>;
  <D.20833>:
  D.20834 = mono_100ns_ticks ();
  D.20835 = D.20834 - start;
  D.20836 = D.20835 / 10000;
  diff_ms = (gint32) D.20836;
  if (diff_ms >= ms) goto <D.20837>; else goto <D.20838>;
  <D.20837>:
  ret = 258;
  goto <D.18844>;
  <D.20838>:
  wait = ms - diff_ms;
  <D.18845>:
  goto <D.18846>;
  <D.18844>:
  D.20839 = (gint32) ret;
  return D.20839;
}


ves_icall_System_Threading_WaitHandle_WaitAny_internal (struct MonoArray * mono_handles, gint32 ms, gboolean exitContext)
{
  gint32 D.20843;
  char * D.20844;
  void * D.20845;
  int D.20848;
  unsigned int D.20849;
  unsigned int D.20854;
  unsigned int D.20856;
  void * handles[64];
  guint32 numhandles;
  guint32 ret;
  guint32 i;
  struct MonoObject * waitHandle;
  struct MonoInternalThread * thread;

  try
    {
      thread = mono_thread_internal_current ();
      mono_thread_current_check_pending_interrupt ();
      numhandles = mono_array_length (mono_handles);
      if (numhandles > 64) goto <D.20841>; else goto <D.20842>;
      <D.20841>:
      D.20843 = -1;
      return D.20843;
      <D.20842>:
      i = 0;
      goto <D.18873>;
      <D.18872>:
      D.20844 = mono_array_addr_with_size (mono_handles, 4, i);
      waitHandle = MEM[(struct MonoObject * *)D.20844];
      D.20845 = mono_wait_handle_get_handle (waitHandle);
      handles[i] = D.20845;
      i = i + 1;
      <D.18873>:
      if (i < numhandles) goto <D.18872>; else goto <D.18874>;
      <D.18874>:
      if (ms == -1) goto <D.20846>; else goto <D.20847>;
      <D.20846>:
      ms = -1;
      <D.20847>:
      mono_thread_set_state (thread, 32);
      D.20848 = mono_wait_uninterrupted (thread, 1, numhandles, &handles, 0, ms, 1);
      ret = (guint32) D.20848;
      mono_thread_clr_state (thread, 32);
      D.20849 = numhandles + 4294967295;
      if (D.20849 >= ret) goto <D.20850>; else goto <D.20851>;
      <D.20850>:
      D.20843 = (gint32) ret;
      return D.20843;
      <D.20851>:
      if (ret > 127) goto <D.20853>; else goto <D.20852>;
      <D.20853>:
      D.20854 = numhandles + 127;
      if (D.20854 >= ret) goto <D.20855>; else goto <D.20852>;
      <D.20855>:
      D.20856 = ret + 4294967168;
      D.20843 = (gint32) D.20856;
      return D.20843;
      <D.20852>:
      D.20843 = (gint32) ret;
      return D.20843;
    }
  finally
    {
      handles = {CLOBBER};
    }
}


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

  thread = mono_thread_internal_current ();
  if (ms == -1) goto <D.20859>; else goto <D.20860>;
  <D.20859>:
  ms = -1;
  <D.20860>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.20861 = mono_wait_uninterrupted (thread, 0, 1, &handle, 0, ms, 1);
  ret = (guint32) D.20861;
  mono_thread_clr_state (thread, 32);
  if (ret == 4294967295) goto <D.20862>; else goto <D.20863>;
  <D.20862>:
  D.20864 = 0;
  return D.20864;
  <D.20863>:
  if (ret == 258) goto <D.20865>; else goto <D.20866>;
  <D.20865>:
  D.20864 = 0;
  return D.20864;
  <D.20866>:
  D.20864 = 1;
  return D.20864;
}


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

  thread = mono_thread_internal_current ();
  if (ms == -1) goto <D.20868>; else goto <D.20869>;
  <D.20868>:
  ms = -1;
  <D.20869>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  ms.60 = (unsigned int) ms;
  ret = SignalObjectAndWait (toSignal, toWait, ms.60, 1);
  mono_thread_clr_state (thread, 32);
  if (ret != 258) goto <D.20875>; else goto <D.20873>;
  <D.20875>:
  if (ret != 192) goto <D.20876>; else goto <D.20873>;
  <D.20876>:
  if (ret != 4294967295) goto <D.20877>; else goto <D.20873>;
  <D.20877>:
  iftmp.61 = 1;
  goto <D.20874>;
  <D.20873>:
  iftmp.61 = 0;
  <D.20874>:
  D.20871 = iftmp.61;
  return D.20871;
}


ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, struct MonoString * name, MonoBoolean * created)
{
  int D.20881;
  mono_unichar2 * D.20883;
  unsigned int D.20884;
  void * D.20887;
  void * mutex;

  *created = 1;
  if (name == 0B) goto <D.20879>; else goto <D.20880>;
  <D.20879>:
  D.20881 = (int) owned;
  mutex = CreateMutex (0B, D.20881, 0B);
  goto <D.20882>;
  <D.20880>:
  D.20881 = (int) owned;
  D.20883 = mono_string_chars (name);
  mutex = CreateMutex (0B, D.20881, D.20883);
  D.20884 = GetLastError ();
  if (D.20884 == 183) goto <D.20885>; else goto <D.20886>;
  <D.20885>:
  *created = 0;
  <D.20886>:
  <D.20882>:
  D.20887 = mutex;
  return D.20887;
}


ves_icall_System_Threading_Mutex_ReleaseMutex_internal (void * handle)
{
  MonoBoolean D.20889;
  int D.20890;

  D.20890 = ReleaseMutex (handle);
  D.20889 = (MonoBoolean) D.20890;
  return D.20889;
}


ves_icall_System_Threading_Mutex_OpenMutex_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.62;
  mono_unichar2 * D.20893;
  unsigned int D.20896;
  int D.20897;
  void * D.20898;
  void * ret;

  *error = 0;
  rights.62 = (unsigned int) rights;
  D.20893 = mono_string_chars (name);
  ret = OpenMutex (rights.62, 0, D.20893);
  if (ret == 0B) goto <D.20894>; else goto <D.20895>;
  <D.20894>:
  D.20896 = GetLastError ();
  D.20897 = (int) D.20896;
  *error = D.20897;
  <D.20895>:
  D.20898 = ret;
  return D.20898;
}


ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, struct MonoString * name, MonoBoolean * created)
{
  mono_unichar2 * D.20903;
  unsigned int D.20904;
  void * D.20907;
  void * sem;

  *created = 1;
  if (name == 0B) goto <D.20900>; else goto <D.20901>;
  <D.20900>:
  sem = CreateSemaphore (0B, initialCount, maximumCount, 0B);
  goto <D.20902>;
  <D.20901>:
  D.20903 = mono_string_chars (name);
  sem = CreateSemaphore (0B, initialCount, maximumCount, D.20903);
  D.20904 = GetLastError ();
  if (D.20904 == 183) goto <D.20905>; else goto <D.20906>;
  <D.20905>:
  *created = 0;
  <D.20906>:
  <D.20902>:
  D.20907 = sem;
  return D.20907;
}


ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (void * handle, gint32 releaseCount, MonoBoolean * fail)
{
  int D.20909;
  _Bool D.20910;
  unsigned char D.20911;
  gint32 D.20912;
  gint32 prevcount;

  try
    {
      D.20909 = ReleaseSemaphore (handle, releaseCount, &prevcount);
      D.20910 = D.20909 == 0;
      D.20911 = (unsigned char) D.20910;
      *fail = D.20911;
      D.20912 = prevcount;
      return D.20912;
    }
  finally
    {
      prevcount = {CLOBBER};
    }
}


ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.63;
  mono_unichar2 * D.20916;
  unsigned int D.20919;
  int D.20920;
  void * D.20921;
  void * ret;

  *error = 0;
  rights.63 = (unsigned int) rights;
  D.20916 = mono_string_chars (name);
  ret = OpenSemaphore (rights.63, 0, D.20916);
  if (ret == 0B) goto <D.20917>; else goto <D.20918>;
  <D.20917>:
  D.20919 = GetLastError ();
  D.20920 = (int) D.20919;
  *error = D.20920;
  <D.20918>:
  D.20921 = ret;
  return D.20921;
}


ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, struct MonoString * name, MonoBoolean * created)
{
  int D.20925;
  int D.20926;
  mono_unichar2 * D.20928;
  unsigned int D.20929;
  void * D.20932;
  void * event;

  *created = 1;
  if (name == 0B) goto <D.20923>; else goto <D.20924>;
  <D.20923>:
  D.20925 = (int) manual;
  D.20926 = (int) initial;
  event = CreateEvent (0B, D.20925, D.20926, 0B);
  goto <D.20927>;
  <D.20924>:
  D.20925 = (int) manual;
  D.20926 = (int) initial;
  D.20928 = mono_string_chars (name);
  event = CreateEvent (0B, D.20925, D.20926, D.20928);
  D.20929 = GetLastError ();
  if (D.20929 == 183) goto <D.20930>; else goto <D.20931>;
  <D.20930>:
  *created = 0;
  <D.20931>:
  <D.20927>:
  D.20932 = event;
  return D.20932;
}


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

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


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

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


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


ves_icall_System_Threading_Events_OpenEvent_internal (struct MonoString * name, gint32 rights, gint32 * error)
{
  unsigned int rights.64;
  mono_unichar2 * D.20939;
  unsigned int D.20942;
  int D.20943;
  void * D.20944;
  void * ret;

  *error = 0;
  rights.64 = (unsigned int) rights;
  D.20939 = mono_string_chars (name);
  ret = OpenEvent (rights.64, 0, D.20939);
  if (ret == 0B) goto <D.20940>; else goto <D.20941>;
  <D.20940>:
  D.20942 = GetLastError ();
  D.20943 = (int) D.20942;
  *error = D.20943;
  <D.20941>:
  D.20944 = ret;
  return D.20944;
}


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

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


ves_icall_System_Threading_Interlocked_Increment_Long (gint64 * location)
{
  unsigned int location.65;
  unsigned int D.20949;
  _Bool D.20950;
  long int D.20951;
  long int D.20952;
  _Bool D.20957;
  long int D.20958;
  long int D.20959;
  long long int D.20962;
  long long int D.20963;
  _Bool D.20966;
  long int D.20967;
  long int D.20968;
  gint64 D.20971;

  location.65 = (unsigned int) location;
  D.20949 = location.65 & 7;
  D.20950 = D.20949 != 0;
  D.20951 = (long int) D.20950;
  D.20952 = __builtin_expect (D.20951, 0);
  if (D.20952 != 0) goto <D.20953>; else goto <D.20954>;
  <D.20953>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.20955>; else goto <D.20956>;
      <D.20955>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.20956>:
      D.20957 = ret != 0;
      D.20958 = (long int) D.20957;
      D.20959 = __builtin_expect (D.20958, 0);
      if (D.20959 != 0) goto <D.20960>; else goto <D.20961>;
      <D.20960>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1764, "ret == 0");
      <D.20961>:
    }
    D.20962 = *location;
    D.20963 = D.20962 + 1;
    *location = D.20963;
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.20964>; else goto <D.20965>;
      <D.20964>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.20965>:
      D.20966 = ret != 0;
      D.20967 = (long int) D.20966;
      D.20968 = __builtin_expect (D.20967, 0);
      if (D.20968 != 0) goto <D.20969>; else goto <D.20970>;
      <D.20969>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1767, "ret == 0");
      <D.20970>:
    }
    D.20971 = ret;
    return D.20971;
  }
  <D.20954>:
  D.20971 = InterlockedIncrement64 (location);
  return D.20971;
}


InterlockedIncrement64 (volatile gint64 * val)
{
  long long int D.20973;
  gint64 D.20974;
  gint64 get;
  gint64 set;

  <D.18454>:
  get = *val;
  set = get + 1;
  D.20973 = InterlockedCompareExchange64 (val, set, get);
  if (D.20973 != get) goto <D.18454>; else goto <D.18455>;
  <D.18455>:
  D.20974 = set;
  return D.20974;
}


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

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


ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
{
  unsigned int location.66;
  unsigned int D.20979;
  _Bool D.20980;
  long int D.20981;
  long int D.20982;
  _Bool D.20987;
  long int D.20988;
  long int D.20989;
  long long int D.20992;
  long long int D.20993;
  _Bool D.20996;
  long int D.20997;
  long int D.20998;
  gint64 D.21001;

  location.66 = (unsigned int) location;
  D.20979 = location.66 & 7;
  D.20980 = D.20979 != 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>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.20985>; else goto <D.20986>;
      <D.20985>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.20986>:
      D.20987 = ret != 0;
      D.20988 = (long int) D.20987;
      D.20989 = __builtin_expect (D.20988, 0);
      if (D.20989 != 0) goto <D.20990>; else goto <D.20991>;
      <D.20990>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1784, "ret == 0");
      <D.20991>:
    }
    D.20992 = *location;
    D.20993 = D.20992 + -1;
    *location = D.20993;
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.20994>; else goto <D.20995>;
      <D.20994>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.20995>:
      D.20996 = ret != 0;
      D.20997 = (long int) D.20996;
      D.20998 = __builtin_expect (D.20997, 0);
      if (D.20998 != 0) goto <D.20999>; else goto <D.21000>;
      <D.20999>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1787, "ret == 0");
      <D.21000>:
    }
    D.21001 = ret;
    return D.21001;
  }
  <D.20984>:
  D.21001 = InterlockedDecrement64 (location);
  return D.21001;
}


InterlockedDecrement64 (volatile gint64 * val)
{
  long long int D.21003;
  gint64 D.21004;
  gint64 get;
  gint64 set;

  <D.18461>:
  get = *val;
  set = get + -1;
  D.21003 = InterlockedCompareExchange64 (val, set, get);
  if (D.21003 != get) goto <D.18461>; else goto <D.18462>;
  <D.18462>:
  D.21004 = set;
  return D.21004;
}


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

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


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

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


InterlockedExchangePointer (void * volatile * val, void * new_val)
{
  unsigned int old_val.67;
  unsigned int new_val.68;
  unsigned int D.21012;
  void * D.21013;
  void * D.21014;
  void * old_val;

  <D.18402>:
  old_val = *val;
  old_val.67 = (unsigned int) old_val;
  new_val.68 = (unsigned int) new_val;
  D.21012 = __sync_val_compare_and_swap_4 (val, old_val.67, new_val.68);
  D.21013 = (void *) D.21012;
  if (D.21013 != old_val) goto <D.18402>; else goto <D.18403>;
  <D.18403>:
  D.21014 = old_val;
  return D.21014;
}


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

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


ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat * location, gfloat value)
{
  int D.21018;
  int D.21019;
  gfloat D.21020;
  union IntFloatUnion val;
  union IntFloatUnion ret;

  try
    {
      val.fval = value;
      D.21018 = val.ival;
      D.21019 = InterlockedExchange (location, D.21018);
      ret.ival = D.21019;
      D.21020 = ret.fval;
      return D.21020;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
    }
}


ves_icall_System_Threading_Interlocked_Exchange_Long (gint64 * location, gint64 value)
{
  unsigned int location.69;
  unsigned int D.21024;
  _Bool D.21025;
  long int D.21026;
  long int D.21027;
  _Bool D.21032;
  long int D.21033;
  long int D.21034;
  _Bool D.21039;
  long int D.21040;
  long int D.21041;
  gint64 D.21044;

  location.69 = (unsigned int) location;
  D.21024 = location.69 & 7;
  D.21025 = D.21024 != 0;
  D.21026 = (long int) D.21025;
  D.21027 = __builtin_expect (D.21026, 0);
  if (D.21027 != 0) goto <D.21028>; else goto <D.21029>;
  <D.21028>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21030>; else goto <D.21031>;
      <D.21030>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.21031>:
      D.21032 = ret != 0;
      D.21033 = (long int) D.21032;
      D.21034 = __builtin_expect (D.21033, 0);
      if (D.21034 != 0) goto <D.21035>; else goto <D.21036>;
      <D.21035>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1828, "ret == 0");
      <D.21036>:
    }
    ret = *location;
    *location = value;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21037>; else goto <D.21038>;
      <D.21037>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21038>:
      D.21039 = ret != 0;
      D.21040 = (long int) D.21039;
      D.21041 = __builtin_expect (D.21040, 0);
      if (D.21041 != 0) goto <D.21042>; else goto <D.21043>;
      <D.21042>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1831, "ret == 0");
      <D.21043>:
    }
    D.21044 = ret;
    return D.21044;
  }
  <D.21029>:
  D.21044 = InterlockedExchange64 (location, value);
  return D.21044;
}


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

  <D.18486>:
  old_val = *val;
  D.21046 = InterlockedCompareExchange64 (val, new_val, old_val);
  if (D.21046 != old_val) goto <D.18486>; else goto <D.18487>;
  <D.18487>:
  D.21047 = old_val;
  return D.21047;
}


ves_icall_System_Threading_Interlocked_Exchange_Double (gdouble * location, gdouble value)
{
  long long int D.21049;
  long long int D.21050;
  gdouble D.21051;
  union LongDoubleUnion val;
  union LongDoubleUnion ret;

  try
    {
      val.fval = value;
      D.21049 = val.ival;
      D.21050 = InterlockedExchange64 (location, D.21049);
      ret.ival = D.21050;
      D.21051 = ret.fval;
      return D.21051;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
    }
}


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

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


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

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


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

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


ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat * location, gfloat value, gfloat comparand)
{
  int D.21060;
  int D.21061;
  int D.21062;
  gfloat D.21063;
  union IntFloatUnion val;
  union IntFloatUnion ret;
  union IntFloatUnion cmp;

  try
    {
      val.fval = value;
      cmp.fval = comparand;
      D.21060 = val.ival;
      D.21061 = cmp.ival;
      D.21062 = InterlockedCompareExchange (location, D.21060, D.21061);
      ret.ival = D.21062;
      D.21063 = ret.fval;
      return D.21063;
    }
  finally
    {
      val = {CLOBBER};
      ret = {CLOBBER};
      cmp = {CLOBBER};
    }
}


ves_icall_System_Threading_Interlocked_CompareExchange_Double (gdouble * location, gdouble value, gdouble comparand)
{
  _Bool D.21068;
  long int D.21069;
  long int D.21070;
  _Bool D.21077;
  long int D.21078;
  long int D.21079;
  gdouble D.21082;
  gdouble old;

  {
    int ret;

    ret = pthread_mutex_lock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.21066>; else goto <D.21067>;
    <D.21066>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.21067>:
    D.21068 = ret != 0;
    D.21069 = (long int) D.21068;
    D.21070 = __builtin_expect (D.21069, 0);
    if (D.21070 != 0) goto <D.21071>; else goto <D.21072>;
    <D.21071>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1892, "ret == 0");
    <D.21072>:
  }
  old = *location;
  if (old == comparand) goto <D.21073>; else goto <D.21074>;
  <D.21073>:
  *location = value;
  <D.21074>:
  {
    int ret;

    ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.21075>; else goto <D.21076>;
    <D.21075>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21076>:
    D.21077 = ret != 0;
    D.21078 = (long int) D.21077;
    D.21079 = __builtin_expect (D.21078, 0);
    if (D.21079 != 0) goto <D.21080>; else goto <D.21081>;
    <D.21080>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1896, "ret == 0");
    <D.21081>:
  }
  D.21082 = old;
  return D.21082;
}


ves_icall_System_Threading_Interlocked_CompareExchange_Long (gint64 * location, gint64 value, gint64 comparand)
{
  unsigned int location.70;
  unsigned int D.21085;
  _Bool D.21086;
  long int D.21087;
  long int D.21088;
  _Bool D.21093;
  long int D.21094;
  long int D.21095;
  _Bool D.21102;
  long int D.21103;
  long int D.21104;
  gint64 D.21107;

  location.70 = (unsigned int) location;
  D.21085 = location.70 & 7;
  D.21086 = D.21085 != 0;
  D.21087 = (long int) D.21086;
  D.21088 = __builtin_expect (D.21087, 0);
  if (D.21088 != 0) goto <D.21089>; else goto <D.21090>;
  <D.21089>:
  {
    gint64 old;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21091>; else goto <D.21092>;
      <D.21091>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.21092>:
      D.21093 = ret != 0;
      D.21094 = (long int) D.21093;
      D.21095 = __builtin_expect (D.21094, 0);
      if (D.21095 != 0) goto <D.21096>; else goto <D.21097>;
      <D.21096>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1908, "ret == 0");
      <D.21097>:
    }
    old = *location;
    if (old == comparand) goto <D.21098>; else goto <D.21099>;
    <D.21098>:
    *location = value;
    <D.21099>:
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21100>; else goto <D.21101>;
      <D.21100>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21101>:
      D.21102 = ret != 0;
      D.21103 = (long int) D.21102;
      D.21104 = __builtin_expect (D.21103, 0);
      if (D.21104 != 0) goto <D.21105>; else goto <D.21106>;
      <D.21105>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1912, "ret == 0");
      <D.21106>:
    }
    D.21107 = old;
    return D.21107;
  }
  <D.21090>:
  D.21107 = InterlockedCompareExchange64 (location, value, comparand);
  return D.21107;
}


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

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


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

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


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

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


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

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


ves_icall_System_Threading_Interlocked_Add_Long (gint64 * location, gint64 value)
{
  unsigned int location.72;
  unsigned int D.21120;
  _Bool D.21121;
  long int D.21122;
  long int D.21123;
  _Bool D.21128;
  long int D.21129;
  long int D.21130;
  long long int D.21133;
  long long int D.21134;
  _Bool D.21137;
  long int D.21138;
  long int D.21139;
  gint64 D.21142;

  location.72 = (unsigned int) location;
  D.21120 = location.72 & 7;
  D.21121 = D.21120 != 0;
  D.21122 = (long int) D.21121;
  D.21123 = __builtin_expect (D.21122, 0);
  if (D.21123 != 0) goto <D.21124>; else goto <D.21125>;
  <D.21124>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21126>; else goto <D.21127>;
      <D.21126>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.21127>:
      D.21128 = ret != 0;
      D.21129 = (long int) D.21128;
      D.21130 = __builtin_expect (D.21129, 0);
      if (D.21130 != 0) goto <D.21131>; else goto <D.21132>;
      <D.21131>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1949, "ret == 0");
      <D.21132>:
    }
    D.21133 = *location;
    D.21134 = D.21133 + value;
    *location = D.21134;
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21135>; else goto <D.21136>;
      <D.21135>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21136>:
      D.21137 = ret != 0;
      D.21138 = (long int) D.21137;
      D.21139 = __builtin_expect (D.21138, 0);
      if (D.21139 != 0) goto <D.21140>; else goto <D.21141>;
      <D.21140>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1952, "ret == 0");
      <D.21141>:
    }
    D.21142 = ret;
    return D.21142;
  }
  <D.21125>:
  D.21142 = InterlockedAdd64 (location, value);
  return D.21142;
}


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

  <D.18469>:
  get = *dest;
  set = get + add;
  D.21144 = InterlockedCompareExchange64 (dest, set, get);
  if (D.21144 != get) goto <D.18469>; else goto <D.18470>;
  <D.18470>:
  D.21145 = set;
  return D.21145;
}


ves_icall_System_Threading_Interlocked_Read_Long (gint64 * location)
{
  unsigned int location.73;
  unsigned int D.21148;
  _Bool D.21149;
  long int D.21150;
  long int D.21151;
  _Bool D.21156;
  long int D.21157;
  long int D.21158;
  _Bool D.21163;
  long int D.21164;
  long int D.21165;
  gint64 D.21168;

  location.73 = (unsigned int) location;
  D.21148 = location.73 & 7;
  D.21149 = D.21148 != 0;
  D.21150 = (long int) D.21149;
  D.21151 = __builtin_expect (D.21150, 0);
  if (D.21151 != 0) goto <D.21152>; else goto <D.21153>;
  <D.21152>:
  {
    gint64 ret;

    {
      int ret;

      ret = pthread_mutex_lock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21154>; else goto <D.21155>;
      <D.21154>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.21155>:
      D.21156 = ret != 0;
      D.21157 = (long int) D.21156;
      D.21158 = __builtin_expect (D.21157, 0);
      if (D.21158 != 0) goto <D.21159>; else goto <D.21160>;
      <D.21159>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1965, "ret == 0");
      <D.21160>:
    }
    ret = *location;
    {
      int ret;

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21161>; else goto <D.21162>;
      <D.21161>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21162>:
      D.21163 = ret != 0;
      D.21164 = (long int) D.21163;
      D.21165 = __builtin_expect (D.21164, 0);
      if (D.21165 != 0) goto <D.21166>; else goto <D.21167>;
      <D.21166>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 1967, "ret == 0");
      <D.21167>:
    }
    D.21168 = ret;
    return D.21168;
  }
  <D.21153>:
  D.21168 = InterlockedRead64 (location);
  return D.21168;
}


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

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


ves_icall_System_Threading_Thread_MemoryBarrier ()
{
  mono_memory_barrier ();
}


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

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


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

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


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

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


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

  lock_thread (this);
  current = mono_thread_internal_current ();
  this->thread_interrupt_requested = 1;
  if (current != this) goto <D.21185>; else goto <D.21183>;
  <D.21185>:
  D.21186 = this->state;
  D.21187 = D.21186 & 32;
  if (D.21187 != 0) goto <D.21188>; else goto <D.21183>;
  <D.21188>:
  iftmp.76 = 1;
  goto <D.21184>;
  <D.21183>:
  iftmp.76 = 0;
  <D.21184>:
  throw = iftmp.76;
  unlock_thread (this);
  if (throw != 0) goto <D.21189>; else goto <D.21190>;
  <D.21189>:
  abort_thread_internal (this, 1, 0);
  <D.21190>:
}


abort_thread_internal (struct MonoInternalThread * thread, gboolean can_raise_exception, gboolean install_async_abort)
{
  int D.21191;
  struct MonoInternalThread * D.21194;
  void * D.21199;
  long long unsigned int D.21200;
  long unsigned int D.21201;
  struct MonoRuntimeExceptionHandlingCallbacks * D.21204;
  gboolean (*<T266a>) (struct MonoThreadUnwindState *) D.21205;
  struct MonoThreadUnwindState * D.21206;
  int D.21207;
  unsigned int D.21210;
  gint32 * D.21211;
  int D.21212;
  int iftmp.77;
  struct MonoMethod * D.21219;
  int D.21220;
  int D.21222;
  void * D.21223;
  struct MonoJitInfo * ji;
  struct MonoThreadInfo * info;
  gboolean protected_wrapper;
  gboolean running_managed;

  info = 0B;
  D.21191 = mono_thread_info_new_interrupt_enabled ();
  if (D.21191 == 0) goto <D.21192>; else goto <D.21193>;
  <D.21192>:
  signal_thread_state_change (thread);
  return;
  <D.21193>:
  D.21194 = mono_thread_internal_current ();
  if (D.21194 == thread) goto <D.21195>; else goto <D.21196>;
  <D.21195>:
  {
    struct MonoException * exc;

    exc = mono_thread_request_interruption (can_raise_exception);
    if (exc != 0B) goto <D.21197>; else goto <D.21198>;
    <D.21197>:
    mono_raise_exception (exc);
    <D.21198>:
    D.21199 = thread->handle;
    wapi_interrupt_thread (D.21199);
    return;
  }
  <D.21196>:
  D.21200 = thread->tid;
  D.21201 = (long unsigned int) D.21200;
  info = mono_thread_info_safe_suspend_sync (D.21201, 1);
  if (info == 0B) goto <D.21202>; else goto <D.21203>;
  <D.21202>:
  return;
  <D.21203>:
  D.21204 = mono_get_eh_callbacks ();
  D.21205 = D.21204->mono_install_handler_block_guard;
  D.21206 = &info->suspend_state;
  D.21207 = D.21205 (D.21206);
  if (D.21207 != 0) goto <D.21208>; else goto <D.21209>;
  <D.21208>:
  D.21210 = info->node.key;
  mono_thread_info_resume (D.21210);
  return;
  <D.21209>:
  D.21211 = &thread->interruption_requested;
  D.21212 = InterlockedCompareExchange (D.21211, 1, 0);
  if (D.21212 == 1) goto <D.21213>; else goto <D.21214>;
  <D.21213>:
  D.21210 = info->node.key;
  mono_thread_info_resume (D.21210);
  return;
  <D.21214>:
  InterlockedIncrement (&thread_interruption_requested);
  ji = mono_thread_info_get_last_managed (info);
  if (ji != 0B) goto <D.21218>; else goto <D.21216>;
  <D.21218>:
  D.21219 = mono_jit_info_get_method (ji);
  D.21220 = mono_threads_is_critical_method (D.21219);
  if (D.21220 != 0) goto <D.21221>; else goto <D.21216>;
  <D.21221>:
  iftmp.77 = 1;
  goto <D.21217>;
  <D.21216>:
  iftmp.77 = 0;
  <D.21217>:
  protected_wrapper = iftmp.77;
  D.21222 = info->suspend_state.ctx.sc_pc;
  D.21223 = (void *) D.21222;
  running_managed = mono_jit_info_match (ji, D.21223);
  if (protected_wrapper == 0) goto <D.21226>; else goto <D.21224>;
  <D.21226>:
  if (running_managed != 0) goto <D.21227>; else goto <D.21224>;
  <D.21227>:
  if (install_async_abort != 0) goto <D.21228>; else goto <D.21229>;
  <D.21228>:
  mono_thread_info_setup_async_call (info, self_interrupt_thread, 0B);
  <D.21229>:
  D.21210 = info->node.key;
  mono_thread_info_resume (D.21210);
  goto <D.21225>;
  <D.21224>:
  {
    void * interrupt_handle;

    D.21199 = thread->handle;
    interrupt_handle = wapi_prepare_interrupt_thread (D.21199);
    D.21210 = info->node.key;
    mono_thread_info_resume (D.21210);
    wapi_finish_interrupt_thread (interrupt_handle);
  }
  <D.21225>:
}


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

  info = mono_thread_info_current ();
  D.21231 = mono_thread_internal_current ();
  exc = mono_thread_execute_interruption (D.21231);
  if (exc != 0B) goto <D.21232>; else goto <D.21233>;
  <D.21232>:
  D.21234 = &info->suspend_state.ctx;
  mono_raise_exception_with_context (exc, D.21234);
  <D.21233>:
  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.21235;
  int D.21240;
  void * D.21241;

  D.21235 = mono_thread_internal_current ();
  if (D.21235 == thread) goto <D.21236>; else goto <D.21237>;
  <D.21236>:
  {
    struct MonoException * exc;

    exc = mono_thread_request_interruption (0);
    if (exc != 0B) goto <D.21238>; else goto <D.21239>;
    <D.21238>:
    mono_raise_exception (exc);
    <D.21239>:
  }
  <D.21237>:
  D.21240 = mono_thread_get_abort_signal ();
  mono_thread_kill (thread, D.21240);
  D.21241 = thread->handle;
  wapi_interrupt_thread (D.21241);
}


mono_thread_info_get_last_managed (struct MonoThreadInfo * info)
{
  struct MonoJitInfo * D.21244;
  struct MonoRuntimeExceptionHandlingCallbacks * D.21245;
  void (*<T265a>) (gboolean (*MonoInternalStackWalk) (struct MonoStackFrameInfo *, struct MonoContext *, void *), struct MonoThreadUnwindState *, MonoUnwindOptions, void *) D.21246;
  struct MonoThreadUnwindState * D.21247;
  struct MonoJitInfo * ji;

  try
    {
      ji = 0B;
      if (info == 0B) goto <D.21242>; else goto <D.21243>;
      <D.21242>:
      D.21244 = 0B;
      return D.21244;
      <D.21243>:
      D.21245 = mono_get_eh_callbacks ();
      D.21246 = D.21245->mono_walk_stack_with_state;
      D.21247 = &info->suspend_state;
      D.21246 (last_managed, D.21247, 0, &ji);
      D.21244 = ji;
      return D.21244;
    }
  finally
    {
      ji = {CLOBBER};
    }
}


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

  dest = data;
  D.21250 = frame->ji;
  *dest = D.21250;
  D.21251 = 1;
  return D.21251;
}


mono_threads_is_critical_method (struct MonoMethod * method)
{
  <unnamed-unsigned:5> D.21253;
  int D.21254;
  gboolean D.21255;

  D.21253 = method->wrapper_type;
  D.21254 = (int) D.21253;
  switch (D.21254) <default: <D.21256>, case 4: <D.19139>, case 10: <D.19140>, case 11: <D.19141>>
  <D.19139>:
  <D.19140>:
  <D.19141>:
  D.21255 = 1;
  return D.21255;
  <D.21256>:
  D.21255 = 0;
  return D.21255;
}


mono_jit_info_match (struct MonoJitInfo * ji, void * ip)
{
  gboolean D.21260;
  int iftmp.78;
  void * D.21264;
  int D.21266;
  sizetype D.21267;
  char * D.21268;

  if (ji == 0B) goto <D.21258>; else goto <D.21259>;
  <D.21258>:
  D.21260 = 0;
  return D.21260;
  <D.21259>:
  D.21264 = ji->code_start;
  if (D.21264 <= ip) goto <D.21265>; else goto <D.21262>;
  <D.21265>:
  D.21264 = ji->code_start;
  D.21266 = ji->code_size;
  D.21267 = (sizetype) D.21266;
  D.21268 = D.21264 + D.21267;
  if (D.21268 > ip) goto <D.21269>; else goto <D.21262>;
  <D.21269>:
  iftmp.78 = 1;
  goto <D.21263>;
  <D.21262>:
  iftmp.78 = 0;
  <D.21263>:
  D.21260 = iftmp.78;
  return D.21260;
}


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

  thread = mono_thread_internal_current ();
  throw = 0;
  lock_thread (thread);
  D.21271 = thread->thread_interrupt_requested;
  if (D.21271 != 0) goto <D.21272>; else goto <D.21273>;
  <D.21272>:
  throw = 1;
  thread->thread_interrupt_requested = 0;
  <D.21273>:
  unlock_thread (thread);
  if (throw != 0) goto <D.21274>; else goto <D.21275>;
  <D.21274>:
  D.21276 = mono_get_exception_thread_interrupted ();
  mono_raise_exception (D.21276);
  <D.21275>:
}


mono_thread_get_abort_signal ()
{
  int abort_signum.79;
  int D.21280;
  int D.21281;
  void (*<Te17>) (int) D.21282;
  void (*<Te5a>) (int, struct siginfo_t *, void *) D.21285;
  int D.21288;
  static int abort_signum = -1;
  int i;

  abort_signum.79 = abort_signum;
  if (abort_signum.79 != -1) goto <D.21278>; else goto <D.21279>;
  <D.21278>:
  D.21280 = abort_signum;
  return D.21280;
  <D.21279>:
  D.21281 = __libc_current_sigrtmin ();
  i = D.21281 + 1;
  goto <D.19096>;
  <D.19095>:
  {
    struct sigaction sinfo;

    try
      {
        sigaction (i, 0B, &sinfo);
        D.21282 = sinfo.__sigaction_handler.sa_handler;
        if (D.21282 == 0B) goto <D.21283>; else goto <D.21284>;
        <D.21283>:
        D.21285 = sinfo.__sigaction_handler.sa_sigaction;
        if (D.21285 == 0B) goto <D.21286>; else goto <D.21287>;
        <D.21286>:
        abort_signum = i;
        D.21280 = i;
        return D.21280;
        <D.21287>:
        <D.21284>:
      }
    finally
      {
        sinfo = {CLOBBER};
      }
  }
  i = i + 1;
  <D.19096>:
  D.21288 = __libc_current_sigrtmax ();
  if (D.21288 > i) goto <D.19095>; else goto <D.19097>;
  <D.19097>:
  D.21280 = __libc_current_sigrtmin ();
  return D.21280;
}


ves_icall_System_Threading_Thread_Abort (struct MonoInternalThread * thread, struct MonoObject * state)
{
  unsigned int D.21292;
  unsigned int D.21293;
  unsigned int D.21296;
  unsigned int D.21297;
  unsigned int D.21300;
  unsigned int D.21301;
  int D.21302;
  unsigned int D.21305;
  unsigned int D.21308;
  int D.21309;
  _Bool D.21310;
  long int D.21311;
  long int D.21312;
  int shutting_down.80;

  lock_thread (thread);
  D.21292 = BIT_FIELD_REF <*thread, 32, 224>;
  D.21293 = D.21292 & 145;
  if (D.21293 != 0) goto <D.21294>; else goto <D.21295>;
  <D.21294>:
  unlock_thread (thread);
  return;
  <D.21295>:
  D.21296 = thread->state;
  D.21297 = D.21296 & 8;
  if (D.21297 != 0) goto <D.21298>; else goto <D.21299>;
  <D.21298>:
  D.21296 = thread->state;
  D.21300 = D.21296 | 256;
  thread->state = D.21300;
  unlock_thread (thread);
  return;
  <D.21299>:
  D.21296 = thread->state;
  D.21301 = D.21296 | 128;
  thread->state = D.21301;
  D.21302 = thread->abort_state_handle;
  if (D.21302 != 0) goto <D.21303>; else goto <D.21304>;
  <D.21303>:
  D.21302 = thread->abort_state_handle;
  D.21305 = (unsigned int) D.21302;
  mono_gchandle_free (D.21305);
  <D.21304>:
  if (state != 0B) goto <D.21306>; else goto <D.21307>;
  <D.21306>:
  D.21308 = mono_gchandle_new (state, 0);
  D.21309 = (int) D.21308;
  thread->abort_state_handle = D.21309;
  D.21302 = thread->abort_state_handle;
  D.21310 = D.21302 == 0;
  D.21311 = (long int) D.21310;
  D.21312 = __builtin_expect (D.21311, 0);
  if (D.21312 != 0) goto <D.21313>; else goto <D.21314>;
  <D.21313>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2156, "thread->abort_state_handle");
  <D.21314>:
  goto <D.21315>;
  <D.21307>:
  thread->abort_state_handle = 0;
  <D.21315>:
  thread->abort_exc = 0B;
  unlock_thread (thread);
  shutting_down.80 = shutting_down;
  if (shutting_down.80 == 0) goto <D.21317>; else goto <D.21318>;
  <D.21317>:
  mono_thread_resume (thread);
  <D.21318>:
  abort_thread_internal (thread, 1, 1);
}


mono_thread_resume (struct MonoInternalThread * thread)
{
  unsigned int D.21320;
  unsigned int D.21321;
  unsigned int D.21324;
  gboolean D.21325;
  unsigned int D.21326;
  unsigned int D.21327;

  lock_thread (thread);
  D.21320 = thread->state;
  D.21321 = D.21320 & 2;
  if (D.21321 != 0) goto <D.21322>; else goto <D.21323>;
  <D.21322>:
  D.21320 = thread->state;
  D.21324 = D.21320 & 4294967293;
  thread->state = D.21324;
  unlock_thread (thread);
  D.21325 = 1;
  return D.21325;
  <D.21323>:
  D.21326 = BIT_FIELD_REF <*thread, 32, 224>;
  D.21327 = D.21326 & 344;
  if (D.21327 != 64) goto <D.21328>; else goto <D.21329>;
  <D.21328>:
  unlock_thread (thread);
  D.21325 = 0;
  return D.21325;
  <D.21329>:
  D.21325 = resume_thread_internal (thread);
  return D.21325;
}


resume_thread_internal (struct MonoInternalThread * thread)
{
  int D.21331;
  void * D.21334;
  void * D.21335;
  gboolean D.21338;
  void * D.21339;
  long long unsigned int D.21340;
  long unsigned int D.21341;
  int D.21342;
  unsigned int D.21345;
  unsigned int D.21346;

  D.21331 = mono_thread_info_new_interrupt_enabled ();
  if (D.21331 == 0) goto <D.21332>; else goto <D.21333>;
  <D.21332>:
  D.21334 = CreateEvent (0B, 1, 0, 0B);
  thread->resume_event = D.21334;
  D.21335 = thread->resume_event;
  if (D.21335 == 0B) goto <D.21336>; else goto <D.21337>;
  <D.21336>:
  unlock_thread (thread);
  D.21338 = 0;
  return D.21338;
  <D.21337>:
  D.21339 = thread->suspend_event;
  SetEvent (D.21339);
  unlock_thread (thread);
  D.21335 = thread->resume_event;
  WaitForSingleObject (D.21335, 4294967295);
  D.21335 = thread->resume_event;
  CloseHandle (D.21335);
  thread->resume_event = 0B;
  D.21338 = 1;
  return D.21338;
  <D.21333>:
  unlock_thread (thread);
  D.21340 = thread->tid;
  D.21341 = (long unsigned int) D.21340;
  D.21342 = mono_thread_info_resume (D.21341);
  if (D.21342 == 0) goto <D.21343>; else goto <D.21344>;
  <D.21343>:
  D.21338 = 0;
  return D.21338;
  <D.21344>:
  lock_thread (thread);
  D.21345 = thread->state;
  D.21346 = D.21345 & 4294967231;
  thread->state = D.21346;
  unlock_thread (thread);
  D.21338 = 1;
  return D.21338;
}


ves_icall_System_Threading_Thread_ResetAbort ()
{
  unsigned int D.21348;
  int D.21349;
  unsigned int D.21350;
  struct MonoException * D.21353;
  int D.21354;
  unsigned int D.21357;
  struct MonoInternalThread * thread;
  gboolean was_aborting;

  thread = mono_thread_internal_current ();
  lock_thread (thread);
  D.21348 = thread->state;
  D.21349 = (int) D.21348;
  was_aborting = D.21349 & 128;
  D.21348 = thread->state;
  D.21350 = D.21348 & 4294967167;
  thread->state = D.21350;
  unlock_thread (thread);
  if (was_aborting == 0) goto <D.21351>; else goto <D.21352>;
  <D.21351>:
  {
    const char * msg;

    msg = "Unable to reset abort because no abort was requested";
    D.21353 = mono_get_exception_thread_state (msg);
    mono_raise_exception (D.21353);
  }
  <D.21352>:
  thread->abort_exc = 0B;
  D.21354 = thread->abort_state_handle;
  if (D.21354 != 0) goto <D.21355>; else goto <D.21356>;
  <D.21355>:
  D.21354 = thread->abort_state_handle;
  D.21357 = (unsigned int) D.21354;
  mono_gchandle_free (D.21357);
  thread->abort_state_handle = 0;
  <D.21356>:
}


mono_thread_internal_reset_abort (struct MonoInternalThread * thread)
{
  unsigned int D.21358;
  unsigned int D.21359;
  struct MonoException * D.21360;
  int D.21363;
  unsigned int D.21366;

  lock_thread (thread);
  D.21358 = thread->state;
  D.21359 = D.21358 & 4294967167;
  thread->state = D.21359;
  D.21360 = thread->abort_exc;
  if (D.21360 != 0B) goto <D.21361>; else goto <D.21362>;
  <D.21361>:
  thread->abort_exc = 0B;
  D.21363 = thread->abort_state_handle;
  if (D.21363 != 0) goto <D.21364>; else goto <D.21365>;
  <D.21364>:
  D.21363 = thread->abort_state_handle;
  D.21366 = (unsigned int) D.21363;
  mono_gchandle_free (D.21366);
  thread->abort_state_handle = 0;
  <D.21365>:
  <D.21362>:
  unlock_thread (thread);
}


ves_icall_System_Threading_Thread_GetAbortExceptionState (struct MonoThread * this)
{
  int D.21367;
  struct MonoObject * D.21370;
  unsigned int D.21371;
  _Bool D.21372;
  long int D.21373;
  long int D.21374;
  struct MonoVTable * D.21377;
  struct MonoDomain * D.21378;
  struct MonoObject * exc.81;
  struct MonoObject * * D.21386;
  struct MonoInternalThread * thread;
  struct MonoObject * state;
  struct MonoObject * deserialized;
  struct MonoObject * exc;
  struct MonoDomain * domain;

  try
    {
      thread = this->internal_thread;
      deserialized = 0B;
      D.21367 = thread->abort_state_handle;
      if (D.21367 == 0) goto <D.21368>; else goto <D.21369>;
      <D.21368>:
      D.21370 = 0B;
      return D.21370;
      <D.21369>:
      D.21367 = thread->abort_state_handle;
      D.21371 = (unsigned int) D.21367;
      state = mono_gchandle_get_target (D.21371);
      D.21372 = state == 0B;
      D.21373 = (long int) D.21372;
      D.21374 = __builtin_expect (D.21373, 0);
      if (D.21374 != 0) goto <D.21375>; else goto <D.21376>;
      <D.21375>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2237, "state");
      <D.21376>:
      domain = mono_domain_get ();
      D.21377 = state->vtable;
      D.21378 = D.21377->domain;
      if (D.21378 == domain) goto <D.21379>; else goto <D.21380>;
      <D.21379>:
      D.21370 = state;
      return D.21370;
      <D.21380>:
      deserialized = mono_object_xdomain_representation (state, domain, &exc);
      if (deserialized == 0B) goto <D.21381>; else goto <D.21382>;
      <D.21381>:
      {
        struct MonoException * invalid_op_exc;

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


ves_icall_System_Threading_Thread_Suspend (struct MonoInternalThread * thread)
{
  int D.21389;
  struct MonoException * D.21392;

  D.21389 = mono_thread_suspend (thread);
  if (D.21389 == 0) goto <D.21390>; else goto <D.21391>;
  <D.21390>:
  D.21392 = mono_get_exception_thread_state ("Thread has not been started, or is dead.");
  mono_raise_exception (D.21392);
  <D.21391>:
}


mono_thread_suspend (struct MonoInternalThread * thread)
{
  unsigned int D.21393;
  unsigned int D.21394;
  gboolean D.21397;
  unsigned int D.21398;
  unsigned int D.21401;
  unsigned int D.21402;

  lock_thread (thread);
  D.21393 = BIT_FIELD_REF <*thread, 32, 224>;
  D.21394 = D.21393 & 280;
  if (D.21394 != 0) goto <D.21395>; else goto <D.21396>;
  <D.21395>:
  unlock_thread (thread);
  D.21397 = 0;
  return D.21397;
  <D.21396>:
  D.21393 = BIT_FIELD_REF <*thread, 32, 224>;
  D.21398 = D.21393 & 67;
  if (D.21398 != 0) goto <D.21399>; else goto <D.21400>;
  <D.21399>:
  unlock_thread (thread);
  D.21397 = 1;
  return D.21397;
  <D.21400>:
  D.21401 = thread->state;
  D.21402 = D.21401 | 2;
  thread->state = D.21402;
  unlock_thread (thread);
  suspend_thread_internal (thread, 0);
  D.21397 = 1;
  return D.21397;
}


suspend_thread_internal (struct MonoInternalThread * thread, gboolean interrupt)
{
  int D.21404;
  struct MonoInternalThread * D.21407;
  long long unsigned int D.21411;
  long unsigned int D.21412;
  int iftmp.82;
  struct MonoMethod * D.21419;
  int D.21420;
  int D.21422;
  void * D.21423;
  gint32 * D.21428;
  int D.21429;
  void * D.21434;
  unsigned int D.21435;

  D.21404 = mono_thread_info_new_interrupt_enabled ();
  if (D.21404 == 0) goto <D.21405>; else goto <D.21406>;
  <D.21405>:
  signal_thread_state_change (thread);
  return;
  <D.21406>:
  lock_thread (thread);
  D.21407 = mono_thread_internal_current ();
  if (D.21407 == thread) goto <D.21408>; else goto <D.21409>;
  <D.21408>:
  transition_to_suspended (thread);
  mono_thread_info_self_suspend ();
  goto <D.21410>;
  <D.21409>:
  {
    struct MonoThreadInfo * info;
    struct MonoJitInfo * ji;
    gboolean protected_wrapper;
    gboolean running_managed;

    D.21411 = thread->tid;
    D.21412 = (long unsigned int) D.21411;
    info = mono_thread_info_safe_suspend_sync (D.21412, interrupt);
    if (info == 0B) goto <D.21413>; else goto <D.21414>;
    <D.21413>:
    unlock_thread (thread);
    return;
    <D.21414>:
    ji = mono_thread_info_get_last_managed (info);
    if (ji != 0B) goto <D.21418>; else goto <D.21416>;
    <D.21418>:
    D.21419 = mono_jit_info_get_method (ji);
    D.21420 = mono_threads_is_critical_method (D.21419);
    if (D.21420 != 0) goto <D.21421>; else goto <D.21416>;
    <D.21421>:
    iftmp.82 = 1;
    goto <D.21417>;
    <D.21416>:
    iftmp.82 = 0;
    <D.21417>:
    protected_wrapper = iftmp.82;
    D.21422 = info->suspend_state.ctx.sc_pc;
    D.21423 = (void *) D.21422;
    running_managed = mono_jit_info_match (ji, D.21423);
    if (running_managed != 0) goto <D.21426>; else goto <D.21424>;
    <D.21426>:
    if (protected_wrapper == 0) goto <D.21427>; else goto <D.21424>;
    <D.21427>:
    transition_to_suspended (thread);
    goto <D.21425>;
    <D.21424>:
    {
      void * interrupt_handle;

      D.21428 = &thread->interruption_requested;
      D.21429 = InterlockedCompareExchange (D.21428, 1, 0);
      if (D.21429 == 0) goto <D.21430>; else goto <D.21431>;
      <D.21430>:
      InterlockedIncrement (&thread_interruption_requested);
      <D.21431>:
      if (interrupt != 0) goto <D.21432>; else goto <D.21433>;
      <D.21432>:
      D.21434 = thread->handle;
      interrupt_handle = wapi_prepare_interrupt_thread (D.21434);
      <D.21433>:
      D.21435 = info->node.key;
      mono_thread_info_resume (D.21435);
      if (interrupt != 0) goto <D.21436>; else goto <D.21437>;
      <D.21436>:
      wapi_finish_interrupt_thread (interrupt_handle);
      <D.21437>:
      unlock_thread (thread);
    }
    <D.21425>:
  }
  <D.21410>:
}


ves_icall_System_Threading_Thread_Resume (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.21441;
  int D.21443;
  struct MonoException * D.21444;

  D.21441 = thread->internal_thread;
  if (D.21441 == 0B) goto <D.21439>; else goto <D.21442>;
  <D.21442>:
  D.21441 = thread->internal_thread;
  D.21443 = mono_thread_resume (D.21441);
  if (D.21443 == 0) goto <D.21439>; else goto <D.21440>;
  <D.21439>:
  D.21444 = mono_get_exception_thread_state ("Thread has not been started, or is dead.");
  mono_raise_exception (D.21444);
  <D.21440>:
}


mono_thread_internal_stop (struct MonoInternalThread * thread)
{
  unsigned int D.21445;
  unsigned int D.21446;
  unsigned int D.21449;
  unsigned int D.21450;
  unsigned int D.21451;

  lock_thread (thread);
  D.21445 = BIT_FIELD_REF <*thread, 32, 224>;
  D.21446 = D.21445 & 17;
  if (D.21446 != 0) goto <D.21447>; else goto <D.21448>;
  <D.21447>:
  unlock_thread (thread);
  return;
  <D.21448>:
  mono_thread_resume (thread);
  D.21449 = thread->state;
  D.21450 = D.21449 | 1;
  thread->state = D.21450;
  D.21449 = thread->state;
  D.21451 = D.21449 & 4294967167;
  thread->state = D.21451;
  unlock_thread (thread);
  abort_thread_internal (thread, 1, 1);
}


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

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


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

  {
    gint8 __tmp;

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


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

  {
    gint16 __tmp;

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


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

  {
    gint32 __tmp;

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


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

  {
    gint64 __tmp;

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


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

  {
    volatile void * __tmp;

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


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

  {
    volatile struct MonoObject * __tmp;

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


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

  {
    double __tmp;

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


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

  {
    float __tmp;

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


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

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


InterlockedRead8 (volatile gint8 * src)
{
  gint8 D.21472;
  unsigned char D.21473;

  D.21473 = __sync_fetch_and_add_1 (src, 0);
  D.21472 = (gint8) D.21473;
  return D.21472;
}


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

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


InterlockedRead16 (volatile gint16 * src)
{
  gint16 D.21477;
  short unsigned int D.21478;

  D.21478 = __sync_fetch_and_add_2 (src, 0);
  D.21477 = (gint16) D.21478;
  return D.21477;
}


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

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


InterlockedRead (volatile gint32 * src)
{
  gint32 D.21482;
  unsigned int D.21483;

  D.21483 = __sync_fetch_and_add_4 (src, 0);
  D.21482 = (gint32) D.21483;
  return D.21482;
}


ves_icall_System_Threading_Volatile_Read8 (void * ptr)
{
  unsigned int ptr.83;
  unsigned int D.21486;
  _Bool D.21487;
  long int D.21488;
  long int D.21489;
  _Bool D.21494;
  long int D.21495;
  long int D.21496;
  _Bool D.21501;
  long int D.21502;
  long int D.21503;
  gint64 D.21506;

  ptr.83 = (unsigned int) ptr;
  D.21486 = ptr.83 & 7;
  D.21487 = D.21486 != 0;
  D.21488 = (long int) D.21487;
  D.21489 = __builtin_expect (D.21488, 0);
  if (D.21489 != 0) goto <D.21490>; else goto <D.21491>;
  <D.21490>:
  {
    gint64 val;

    {
      int ret;

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

      ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
      if (ret != 0) goto <D.21499>; else goto <D.21500>;
      <D.21499>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21500>:
      D.21501 = ret != 0;
      D.21502 = (long int) D.21501;
      D.21503 = __builtin_expect (D.21502, 0);
      if (D.21503 != 0) goto <D.21504>; else goto <D.21505>;
      <D.21504>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2471, "ret == 0");
      <D.21505>:
    }
    D.21506 = val;
    return D.21506;
  }
  <D.21491>:
  D.21506 = InterlockedRead64 (ptr);
  return D.21506;
}


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

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


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

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


ves_icall_System_Threading_Volatile_ReadDouble (void * ptr)
{
  unsigned int ptr.84;
  unsigned int D.21513;
  _Bool D.21514;
  long int D.21515;
  long int D.21516;
  _Bool D.21521;
  long int D.21522;
  long int D.21523;
  _Bool D.21528;
  long int D.21529;
  long int D.21530;
  double D.21533;
  long long int D.21534;
  union LongDoubleUnion u;

  try
    {
      ptr.84 = (unsigned int) ptr;
      D.21513 = ptr.84 & 7;
      D.21514 = D.21513 != 0;
      D.21515 = (long int) D.21514;
      D.21516 = __builtin_expect (D.21515, 0);
      if (D.21516 != 0) goto <D.21517>; else goto <D.21518>;
      <D.21517>:
      {
        double val;

        {
          int ret;

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

          ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
          if (ret != 0) goto <D.21526>; else goto <D.21527>;
          <D.21526>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.21527>:
          D.21528 = ret != 0;
          D.21529 = (long int) D.21528;
          D.21530 = __builtin_expect (D.21529, 0);
          if (D.21530 != 0) goto <D.21531>; else goto <D.21532>;
          <D.21531>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2494, "ret == 0");
          <D.21532>:
        }
        D.21533 = val;
        return D.21533;
      }
      <D.21518>:
      D.21534 = InterlockedRead64 (ptr);
      u.ival = D.21534;
      D.21533 = u.fval;
      return D.21533;
    }
  finally
    {
      u = {CLOBBER};
    }
}


ves_icall_System_Threading_Volatile_ReadFloat (void * ptr)
{
  int D.21537;
  float D.21538;
  union IntFloatUnion u;

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


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

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


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


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


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


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


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


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


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


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


ves_icall_System_Threading_Volatile_Write1 (void * ptr, gint8 value)
{
  int D.21543;

  D.21543 = (int) value;
  InterlockedWrite8 (ptr, D.21543);
}


InterlockedWrite8 (volatile gint8 * dst, gint8 val)
{
  unsigned char old_val.85;
  int D.21545;
  unsigned char val.86;
  int D.21547;
  unsigned char D.21548;
  signed char D.21549;
  gint8 old_val;

  <D.18422>:
  old_val = *dst;
  old_val.85 = (unsigned char) old_val;
  D.21545 = (int) old_val.85;
  val.86 = (unsigned char) val;
  D.21547 = (int) val.86;
  D.21548 = __sync_val_compare_and_swap_1 (dst, D.21545, D.21547);
  D.21549 = (signed char) D.21548;
  if (D.21549 != old_val) goto <D.18422>; else goto <D.18423>;
  <D.18423>:
}


ves_icall_System_Threading_Volatile_Write2 (void * ptr, gint16 value)
{
  int D.21550;

  D.21550 = (int) value;
  InterlockedWrite16 (ptr, D.21550);
}


InterlockedWrite16 (volatile gint16 * dst, gint16 val)
{
  short unsigned int old_val.87;
  int D.21552;
  short unsigned int val.88;
  int D.21554;
  short unsigned int D.21555;
  short int D.21556;
  gint16 old_val;

  <D.18429>:
  old_val = *dst;
  old_val.87 = (short unsigned int) old_val;
  D.21552 = (int) old_val.87;
  val.88 = (short unsigned int) val;
  D.21554 = (int) val.88;
  D.21555 = __sync_val_compare_and_swap_2 (dst, D.21552, D.21554);
  D.21556 = (short int) D.21555;
  if (D.21556 != old_val) goto <D.18429>; else goto <D.18430>;
  <D.18430>:
}


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


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

  <D.18436>:
  old_val = *dst;
  old_val.89 = (unsigned int) old_val;
  val.90 = (unsigned int) val;
  D.21559 = __sync_val_compare_and_swap_4 (dst, old_val.89, val.90);
  D.21560 = (int) D.21559;
  if (D.21560 != old_val) goto <D.18436>; else goto <D.18437>;
  <D.18437>:
}


ves_icall_System_Threading_Volatile_Write8 (void * ptr, gint64 value)
{
  unsigned int ptr.91;
  unsigned int D.21562;
  _Bool D.21563;
  long int D.21564;
  long int D.21565;
  _Bool D.21570;
  long int D.21571;
  long int D.21572;
  _Bool D.21577;
  long int D.21578;
  long int D.21579;

  ptr.91 = (unsigned int) ptr;
  D.21562 = ptr.91 & 7;
  D.21563 = D.21562 != 0;
  D.21564 = (long int) D.21563;
  D.21565 = __builtin_expect (D.21564, 0);
  if (D.21565 != 0) goto <D.21566>; else goto <D.21567>;
  <D.21566>:
  {
    int ret;

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

    ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
    if (ret != 0) goto <D.21575>; else goto <D.21576>;
    <D.21575>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21576>:
    D.21577 = ret != 0;
    D.21578 = (long int) D.21577;
    D.21579 = __builtin_expect (D.21578, 0);
    if (D.21579 != 0) goto <D.21580>; else goto <D.21581>;
    <D.21580>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2593, "ret == 0");
    <D.21581>:
  }
  return;
  <D.21567>:
  InterlockedWrite64 (ptr, value);
}


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


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


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


ves_icall_System_Threading_Volatile_WriteDouble (void * ptr, double value)
{
  unsigned int ptr.92;
  unsigned int D.21584;
  _Bool D.21585;
  long int D.21586;
  long int D.21587;
  _Bool D.21592;
  long int D.21593;
  long int D.21594;
  _Bool D.21599;
  long int D.21600;
  long int D.21601;
  long long int D.21604;
  union LongDoubleUnion u;

  try
    {
      ptr.92 = (unsigned int) ptr;
      D.21584 = ptr.92 & 7;
      D.21585 = D.21584 != 0;
      D.21586 = (long int) D.21585;
      D.21587 = __builtin_expect (D.21586, 0);
      if (D.21587 != 0) goto <D.21588>; else goto <D.21589>;
      <D.21588>:
      {
        int ret;

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

        ret = pthread_mutex_unlock (&interlocked_mutex.mutex);
        if (ret != 0) goto <D.21597>; else goto <D.21598>;
        <D.21597>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21598>:
        D.21599 = ret != 0;
        D.21600 = (long int) D.21599;
        D.21601 = __builtin_expect (D.21600, 0);
        if (D.21601 != 0) goto <D.21602>; else goto <D.21603>;
        <D.21602>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2616, "ret == 0");
        <D.21603>:
      }
      return;
      <D.21589>:
      u.fval = value;
      D.21604 = u.ival;
      InterlockedWrite64 (ptr, D.21604);
    }
  finally
    {
      u = {CLOBBER};
    }
}


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

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


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


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


mono_native_tls_alloc (pthread_key_t * key, void * destructor)
{
  int D.21609;
  void (*<Tc3>) (void *) destructor.93;
  int D.21611;
  _Bool D.21612;

  destructor.93 = (void (*<Tc3>) (void *)) destructor;
  D.21611 = pthread_key_create (key, destructor.93);
  D.21612 = D.21611 == 0;
  D.21609 = (int) D.21612;
  return D.21609;
}


mono_thread_init (void (*MonoThreadStartCB) (intptr_t, void *, void *) start_cb, void (*MonoThreadAttachCB) (intptr_t, void *) attach_cb)
{
  void * background_change_event.94;
  void * background_change_event.95;
  _Bool D.21616;
  long int D.21617;
  long int D.21618;

  InitializeCriticalSection (&threads_mutex);
  InitializeCriticalSection (&interlocked_mutex);
  InitializeCriticalSection (&contexts_mutex);
  background_change_event.94 = CreateEvent (0B, 1, 0, 0B);
  background_change_event = background_change_event.94;
  background_change_event.95 = background_change_event;
  D.21616 = background_change_event.95 == 0B;
  D.21617 = (long int) D.21616;
  D.21618 = __builtin_expect (D.21617, 0);
  if (D.21618 != 0) goto <D.21619>; else goto <D.21620>;
  <D.21619>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2657, "background_change_event != NULL");
  <D.21620>:
  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.21621;
  unsigned int D.21622;
  unsigned int current_object_key.96;

  D.21621 = mono_environment_exitcode_get ();
  D.21622 = (unsigned int) D.21621;
  _wapi_thread_signal_self (D.21622);
  current_object_key.96 = current_object_key;
  mono_native_tls_free (current_object_key.96);
}


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


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


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

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


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


mono_threads_set_shutting_down ()
{
  _Bool D.21627;
  long int D.21628;
  long int D.21629;
  int shutting_down.97;
  _Bool D.21637;
  long int D.21638;
  long int D.21639;
  unsigned int D.21642;
  unsigned int D.21643;
  unsigned int D.21647;
  unsigned int D.21648;
  void * background_change_event.98;
  _Bool D.21652;
  long int D.21653;
  long int D.21654;
  struct MonoInternalThread * current_thread;

  current_thread = mono_thread_internal_current ();
  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21625>; else goto <D.21626>;
    <D.21625>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.21626>:
    D.21627 = ret != 0;
    D.21628 = (long int) D.21627;
    D.21629 = __builtin_expect (D.21628, 0);
    if (D.21629 != 0) goto <D.21630>; else goto <D.21631>;
    <D.21630>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2934, "ret == 0");
    <D.21631>:
  }
  shutting_down.97 = shutting_down;
  if (shutting_down.97 != 0) goto <D.21633>; else goto <D.21634>;
  <D.21633>:
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21635>; else goto <D.21636>;
    <D.21635>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21636>:
    D.21637 = ret != 0;
    D.21638 = (long int) D.21637;
    D.21639 = __builtin_expect (D.21638, 0);
    if (D.21639 != 0) goto <D.21640>; else goto <D.21641>;
    <D.21640>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2937, "ret == 0");
    <D.21641>:
  }
  lock_thread (current_thread);
  D.21642 = BIT_FIELD_REF <*current_thread, 32, 224>;
  D.21643 = D.21642 & 131;
  if (D.21643 != 0) goto <D.21644>; else goto <D.21645>;
  <D.21644>:
  unlock_thread (current_thread);
  mono_thread_execute_interruption (current_thread);
  goto <D.21646>;
  <D.21645>:
  D.21647 = current_thread->state;
  D.21648 = D.21647 | 16;
  current_thread->state = D.21648;
  unlock_thread (current_thread);
  <D.21646>:
  mono_domain_unset ();
  ExitThread (0);
  <D.21634>:
  shutting_down = 1;
  background_change_event.98 = background_change_event;
  SetEvent (background_change_event.98);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.21650>; else goto <D.21651>;
    <D.21650>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21651>:
    D.21652 = ret != 0;
    D.21653 = (long int) D.21652;
    D.21654 = __builtin_expect (D.21653, 0);
    if (D.21654 != 0) goto <D.21655>; else goto <D.21656>;
    <D.21655>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2967, "ret == 0");
    <D.21656>:
  }
}


mono_thread_manage ()
{
  _Bool D.21659;
  long int D.21660;
  long int D.21661;
  struct MonoGHashTable * threads.99;
  _Bool D.21669;
  long int D.21670;
  long int D.21671;
  _Bool D.21676;
  long int D.21677;
  long int D.21678;
  _Bool D.21683;
  long int D.21684;
  long int D.21685;
  int shutting_down.100;
  _Bool D.21693;
  long int D.21694;
  long int D.21695;
  void * background_change_event.101;
  struct MonoInternalThread *[64] * D.21699;
  _Bool D.21702;
  long int D.21703;
  long int D.21704;
  unsigned int D.21707;
  int D.21710;
  struct MonoInternalThread * D.21713;
  struct MonoInternalThread * D.21714;
  _Bool D.21717;
  long int D.21718;
  long int D.21719;
  _Bool D.21724;
  long int D.21725;
  long int D.21726;
  struct wait_data wait_data;
  struct wait_data * wait;

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

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21657>; else goto <D.21658>;
        <D.21657>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21658>:
        D.21659 = ret != 0;
        D.21660 = (long int) D.21659;
        D.21661 = __builtin_expect (D.21660, 0);
        if (D.21661 != 0) goto <D.21662>; else goto <D.21663>;
        <D.21662>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2980, "ret == 0");
        <D.21663>:
      }
      threads.99 = threads;
      if (threads.99 == 0B) goto <D.21665>; else goto <D.21666>;
      <D.21665>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21667>; else goto <D.21668>;
        <D.21667>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21668>:
        D.21669 = ret != 0;
        D.21670 = (long int) D.21669;
        D.21671 = __builtin_expect (D.21670, 0);
        if (D.21671 != 0) goto <D.21672>; else goto <D.21673>;
        <D.21672>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2983, "ret == 0");
        <D.21673>:
      }
      return;
      <D.21666>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21674>; else goto <D.21675>;
        <D.21674>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21675>:
        D.21676 = ret != 0;
        D.21677 = (long int) D.21676;
        D.21678 = __builtin_expect (D.21677, 0);
        if (D.21678 != 0) goto <D.21679>; else goto <D.21680>;
        <D.21679>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2986, "ret == 0");
        <D.21680>:
      }
      <D.19396>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21681>; else goto <D.21682>;
        <D.21681>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21682>:
        D.21683 = ret != 0;
        D.21684 = (long int) D.21683;
        D.21685 = __builtin_expect (D.21684, 0);
        if (D.21685 != 0) goto <D.21686>; else goto <D.21687>;
        <D.21686>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2989, "ret == 0");
        <D.21687>:
      }
      shutting_down.100 = shutting_down;
      if (shutting_down.100 != 0) goto <D.21689>; else goto <D.21690>;
      <D.21689>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21691>; else goto <D.21692>;
        <D.21691>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21692>:
        D.21693 = ret != 0;
        D.21694 = (long int) D.21693;
        D.21695 = __builtin_expect (D.21694, 0);
        if (D.21695 != 0) goto <D.21696>; else goto <D.21697>;
        <D.21696>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2992, "ret == 0");
        <D.21697>:
      }
      goto <D.19394>;
      <D.21690>:
      background_change_event.101 = background_change_event;
      ResetEvent (background_change_event.101);
      wait->num = 0;
      D.21699 = &wait->threads;
      memset (D.21699, 0, 256);
      threads.99 = threads;
      mono_g_hash_table_foreach (threads.99, build_wait_tids, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21700>; else goto <D.21701>;
        <D.21700>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21701>:
        D.21702 = ret != 0;
        D.21703 = (long int) D.21702;
        D.21704 = __builtin_expect (D.21703, 0);
        if (D.21704 != 0) goto <D.21705>; else goto <D.21706>;
        <D.21705>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3003, "ret == 0");
        <D.21706>:
      }
      D.21707 = wait->num;
      if (D.21707 != 0) goto <D.21708>; else goto <D.21709>;
      <D.21708>:
      wait_for_tids_or_state_change (wait, 4294967295);
      <D.21709>:
      D.21707 = wait->num;
      if (D.21707 != 0) goto <D.19396>; else goto <D.19394>;
      <D.19394>:
      D.21710 = mono_runtime_try_shutdown ();
      if (D.21710 == 0) goto <D.21711>; else goto <D.21712>;
      <D.21711>:
      D.21713 = mono_thread_internal_current ();
      mono_thread_suspend (D.21713);
      D.21714 = mono_thread_internal_current ();
      mono_thread_execute_interruption (D.21714);
      <D.21712>:
      <D.19399>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21715>; else goto <D.21716>;
        <D.21715>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21716>:
        D.21717 = ret != 0;
        D.21718 = (long int) D.21717;
        D.21719 = __builtin_expect (D.21718, 0);
        if (D.21719 != 0) goto <D.21720>; else goto <D.21721>;
        <D.21720>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3023, "ret == 0");
        <D.21721>:
      }
      wait->num = 0;
      D.21699 = &wait->threads;
      memset (D.21699, 0, 256);
      threads.99 = threads;
      mono_g_hash_table_foreach_remove (threads.99, remove_and_abort_threads, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21722>; else goto <D.21723>;
        <D.21722>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21723>:
        D.21724 = ret != 0;
        D.21725 = (long int) D.21724;
        D.21726 = __builtin_expect (D.21725, 0);
        if (D.21726 != 0) goto <D.21727>; else goto <D.21728>;
        <D.21727>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3030, "ret == 0");
        <D.21728>:
      }
      D.21707 = wait->num;
      if (D.21707 != 0) goto <D.21729>; else goto <D.21730>;
      <D.21729>:
      wait_for_tids (wait, 4294967295);
      <D.21730>:
      D.21707 = wait->num;
      if (D.21707 != 0) goto <D.19399>; else goto <D.19400>;
      <D.19400>:
      sched_yield ();
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


remove_and_abort_threads (void * key, void * value, void * user)
{
  unsigned int D.21734;
  gboolean D.21737;
  long long unsigned int D.21738;
  long long unsigned int D.21739;
  unsigned int D.21742;
  unsigned int D.21743;
  unsigned int D.21746;
  unsigned int D.21747;
  unsigned int D.21750;
  void * D.21753;
  unsigned int D.21754;
  int iftmp.102;
  int D.21759;
  struct wait_data * wait;
  gsize self;
  struct MonoInternalThread * thread;
  void * handle;

  wait = user;
  self = GetCurrentThreadId ();
  thread = value;
  D.21734 = wait->num;
  if (D.21734 > 63) goto <D.21735>; else goto <D.21736>;
  <D.21735>:
  D.21737 = 0;
  return D.21737;
  <D.21736>:
  D.21738 = thread->tid;
  D.21739 = (long long unsigned int) self;
  if (D.21738 != D.21739) goto <D.21740>; else goto <D.21741>;
  <D.21740>:
  D.21742 = thread->state;
  D.21743 = D.21742 & 4;
  if (D.21743 != 0) goto <D.21744>; else goto <D.21745>;
  <D.21744>:
  D.21746 = thread->flags;
  D.21747 = D.21746 & 1;
  if (D.21747 == 0) goto <D.21748>; else goto <D.21749>;
  <D.21748>:
  D.21738 = thread->tid;
  D.21750 = (unsigned int) D.21738;
  handle = OpenThread (2032639, 1, D.21750);
  if (handle == 0B) goto <D.21751>; else goto <D.21752>;
  <D.21751>:
  D.21737 = 0;
  return D.21737;
  <D.21752>:
  D.21734 = wait->num;
  D.21753 = thread->handle;
  wait->handles[D.21734] = D.21753;
  D.21734 = wait->num;
  wait->threads[D.21734] = thread;
  D.21734 = wait->num;
  D.21754 = D.21734 + 1;
  wait->num = D.21754;
  mono_thread_internal_stop (thread);
  D.21737 = 1;
  return D.21737;
  <D.21749>:
  <D.21745>:
  <D.21741>:
  D.21738 = thread->tid;
  D.21739 = (long long unsigned int) self;
  if (D.21738 != D.21739) goto <D.21758>; else goto <D.21756>;
  <D.21758>:
  D.21759 = mono_gc_is_finalizer_internal_thread (thread);
  if (D.21759 == 0) goto <D.21760>; else goto <D.21756>;
  <D.21760>:
  iftmp.102 = 1;
  goto <D.21757>;
  <D.21756>:
  iftmp.102 = 0;
  <D.21757>:
  D.21737 = iftmp.102;
  return D.21737;
}


build_wait_tids (void * key, void * value, void * user)
{
  unsigned int D.21762;
  unsigned int D.21765;
  unsigned int D.21766;
  int D.21769;
  struct MonoInternalThread * D.21772;
  struct MonoThread * D.21775;
  struct MonoThread * D.21778;
  struct _MonoInternalThread * D.21779;
  unsigned int D.21782;
  unsigned int D.21783;
  long long unsigned int D.21786;
  unsigned int D.21787;
  mono_bool (*<T1bfb>) (struct MonoThread *) D.21792;
  struct MonoThread * D.21794;
  int D.21795;
  unsigned int D.21796;
  struct wait_data * wait;

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

    thread = value;
    D.21765 = thread->state;
    D.21766 = D.21765 & 4;
    if (D.21766 != 0) goto <D.21767>; else goto <D.21768>;
    <D.21767>:
    return;
    <D.21768>:
    D.21769 = mono_gc_is_finalizer_internal_thread (thread);
    if (D.21769 != 0) goto <D.21770>; else goto <D.21771>;
    <D.21770>:
    return;
    <D.21771>:
    D.21772 = mono_thread_internal_current ();
    if (D.21772 == thread) goto <D.21773>; else goto <D.21774>;
    <D.21773>:
    return;
    <D.21774>:
    D.21775 = mono_thread_get_main ();
    if (D.21775 != 0B) goto <D.21776>; else goto <D.21777>;
    <D.21776>:
    D.21778 = mono_thread_get_main ();
    D.21779 = D.21778->internal_thread;
    if (D.21779 == thread) goto <D.21780>; else goto <D.21781>;
    <D.21780>:
    return;
    <D.21781>:
    <D.21777>:
    D.21782 = thread->flags;
    D.21783 = D.21782 & 1;
    if (D.21783 != 0) goto <D.21784>; else goto <D.21785>;
    <D.21784>:
    return;
    <D.21785>:
    D.21786 = thread->tid;
    D.21787 = (unsigned int) D.21786;
    handle = OpenThread (2032639, 1, D.21787);
    if (handle == 0B) goto <D.21788>; else goto <D.21789>;
    <D.21788>:
    return;
    <D.21789>:
    D.21792 = thread->manage_callback;
    if (D.21792 == 0B) goto <D.21790>; else goto <D.21793>;
    <D.21793>:
    D.21792 = thread->manage_callback;
    D.21794 = thread->root_domain_thread;
    D.21795 = D.21792 (D.21794);
    if (D.21795 == 1) goto <D.21790>; else goto <D.21791>;
    <D.21790>:
    D.21762 = wait->num;
    wait->handles[D.21762] = handle;
    D.21762 = wait->num;
    wait->threads[D.21762] = thread;
    D.21762 = wait->num;
    D.21796 = D.21762 + 1;
    wait->num = D.21796;
    <D.21791>:
  }
  goto <D.21797>;
  <D.21764>:
  <D.21797>:
}


wait_for_tids_or_state_change (struct wait_data * wait, guint32 timeout)
{
  void * background_change_event.103;
  void *[64] * D.21802;
  void * D.21805;
  unsigned int D.21806;
  struct MonoInternalThread * D.21811;
  long long unsigned int D.21812;
  _Bool D.21815;
  long int D.21816;
  long int D.21817;
  struct MonoGHashTable * threads.104;
  const void * tid.105;
  void * D.21822;
  _Bool D.21827;
  long int D.21828;
  long int D.21829;
  _Bool D.21835;
  long int D.21836;
  long int D.21837;
  guint32 i;
  guint32 ret;
  guint32 count;

  count = wait->num;
  if (count <= 63) goto <D.21799>; else goto <D.21800>;
  <D.21799>:
  background_change_event.103 = background_change_event;
  wait->handles[count] = background_change_event.103;
  count = count + 1;
  <D.21800>:
  D.21802 = &wait->handles;
  ret = WaitForMultipleObjectsEx (count, D.21802, 0, timeout, 1);
  if (ret == 4294967295) goto <D.21803>; else goto <D.21804>;
  <D.21803>:
  return;
  <D.21804>:
  i = 0;
  goto <D.19354>;
  <D.19353>:
  D.21805 = wait->handles[i];
  CloseHandle (D.21805);
  i = i + 1;
  <D.19354>:
  D.21806 = wait->num;
  if (D.21806 > i) goto <D.19353>; else goto <D.19355>;
  <D.19355>:
  if (ret == 258) goto <D.21807>; else goto <D.21808>;
  <D.21807>:
  return;
  <D.21808>:
  D.21806 = wait->num;
  if (D.21806 > ret) goto <D.21809>; else goto <D.21810>;
  <D.21809>:
  {
    gsize tid;

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

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.21813>; else goto <D.21814>;
      <D.21813>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.21814>:
      D.21815 = ret != 0;
      D.21816 = (long int) D.21815;
      D.21817 = __builtin_expect (D.21816, 0);
      if (D.21817 != 0) goto <D.21818>; else goto <D.21819>;
      <D.21818>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2819, "ret == 0");
      <D.21819>:
    }
    threads.104 = threads;
    tid.105 = (const void *) tid;
    D.21822 = mono_g_hash_table_lookup (threads.104, tid.105);
    if (D.21822 != 0B) goto <D.21823>; else goto <D.21824>;
    <D.21823>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.21825>; else goto <D.21826>;
      <D.21825>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21826>:
      D.21827 = ret != 0;
      D.21828 = (long int) D.21827;
      D.21829 = __builtin_expect (D.21828, 0);
      if (D.21829 != 0) goto <D.21830>; else goto <D.21831>;
      <D.21830>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2822, "ret == 0");
      <D.21831>:
    }
    D.21811 = wait->threads[ret];
    thread_cleanup (D.21811);
    goto <D.21832>;
    <D.21824>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.21833>; else goto <D.21834>;
      <D.21833>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21834>:
      D.21835 = ret != 0;
      D.21836 = (long int) D.21835;
      D.21837 = __builtin_expect (D.21836, 0);
      if (D.21837 != 0) goto <D.21838>; else goto <D.21839>;
      <D.21838>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2826, "ret == 0");
      <D.21839>:
    }
    <D.21832>:
  }
  <D.21810>:
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.21843;
  int D.21848;
  void * D.21850;
  unsigned int D.21851;

  D.21843 = __builtin_constant_p (__len);
  if (D.21843 != 0) goto <D.21844>; else goto <D.21845>;
  <D.21844>:
  if (__len == 0) goto <D.21846>; else goto <D.21847>;
  <D.21846>:
  D.21848 = __builtin_constant_p (__ch);
  if (D.21848 == 0) goto <D.21841>; else goto <D.21849>;
  <D.21849>:
  if (__ch != 0) goto <D.21841>; else goto <D.21842>;
  <D.21841>:
  __warn_memset_zero_len ();
  D.21850 = __dest;
  return D.21850;
  <D.21842>:
  <D.21847>:
  <D.21845>:
  D.21851 = __builtin_object_size (__dest, 0);
  D.21850 = __builtin___memset_chk (__dest, __ch, __len, D.21851);
  return D.21850;
}


wait_for_tids (struct wait_data * wait, guint32 timeout)
{
  unsigned int D.21853;
  void *[64] * D.21854;
  void * D.21857;
  struct MonoInternalThread * D.21860;
  long long unsigned int D.21861;
  _Bool D.21864;
  long int D.21865;
  long int D.21866;
  struct MonoGHashTable * threads.106;
  const void * tid.107;
  void * D.21871;
  _Bool D.21876;
  long int D.21877;
  long int D.21878;
  _Bool D.21884;
  long int D.21885;
  long int D.21886;
  guint32 i;
  guint32 ret;

  D.21853 = wait->num;
  D.21854 = &wait->handles;
  ret = WaitForMultipleObjectsEx (D.21853, D.21854, 1, timeout, 1);
  if (ret == 4294967295) goto <D.21855>; else goto <D.21856>;
  <D.21855>:
  return;
  <D.21856>:
  i = 0;
  goto <D.19337>;
  <D.19336>:
  D.21857 = wait->handles[i];
  CloseHandle (D.21857);
  i = i + 1;
  <D.19337>:
  D.21853 = wait->num;
  if (D.21853 > i) goto <D.19336>; else goto <D.19338>;
  <D.19338>:
  if (ret == 258) goto <D.21858>; else goto <D.21859>;
  <D.21858>:
  return;
  <D.21859>:
  i = 0;
  goto <D.19344>;
  <D.19343>:
  {
    gsize tid;

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

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.21862>; else goto <D.21863>;
      <D.21862>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.21863>:
      D.21864 = ret != 0;
      D.21865 = (long int) D.21864;
      D.21866 = __builtin_expect (D.21865, 0);
      if (D.21866 != 0) goto <D.21867>; else goto <D.21868>;
      <D.21867>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2766, "ret == 0");
      <D.21868>:
    }
    threads.106 = threads;
    tid.107 = (const void *) tid;
    D.21871 = mono_g_hash_table_lookup (threads.106, tid.107);
    if (D.21871 != 0B) goto <D.21872>; else goto <D.21873>;
    <D.21872>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.21874>; else goto <D.21875>;
      <D.21874>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21875>:
      D.21876 = ret != 0;
      D.21877 = (long int) D.21876;
      D.21878 = __builtin_expect (D.21877, 0);
      if (D.21878 != 0) goto <D.21879>; else goto <D.21880>;
      <D.21879>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2779, "ret == 0");
      <D.21880>:
    }
    D.21860 = wait->threads[i];
    thread_cleanup (D.21860);
    goto <D.21881>;
    <D.21873>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.21882>; else goto <D.21883>;
      <D.21882>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.21883>:
      D.21884 = ret != 0;
      D.21885 = (long int) D.21884;
      D.21886 = __builtin_expect (D.21885, 0);
      if (D.21886 != 0) goto <D.21887>; else goto <D.21888>;
      <D.21887>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 2783, "ret == 0");
      <D.21888>:
    }
    <D.21881>:
  }
  i = i + 1;
  <D.19344>:
  D.21853 = wait->num;
  if (D.21853 > i) goto <D.19343>; else goto <D.19345>;
  <D.19345>:
}


mono_thread_abort_all_other_threads ()
{
  _Bool D.21892;
  long int D.21893;
  long int D.21894;
  struct MonoGHashTable * threads.108;
  void * self.109;
  _Bool D.21901;
  long int D.21902;
  long int D.21903;
  gsize self;

  self = GetCurrentThreadId ();
  {
    int ret;

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

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


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

  thread = value;
  D.21906 = thread->tid;
  user.110 = (unsigned int) user;
  D.21908 = (long long unsigned int) user.110;
  if (D.21906 != D.21908) goto <D.21909>; else goto <D.21910>;
  <D.21909>:
  <D.21910>:
}


mono_thread_suspend_all_other_threads ()
{
  int shutting_down.111;
  _Bool D.21912;
  long int D.21913;
  long int D.21914;
  struct MonoInternalThread *[64] * D.21917;
  _Bool D.21920;
  long int D.21921;
  long int D.21922;
  struct MonoGHashTable * threads.112;
  _Bool D.21928;
  long int D.21929;
  long int D.21930;
  unsigned int D.21933;
  unsigned int D.21934;
  long long unsigned int D.21937;
  long long unsigned int D.21938;
  int D.21940;
  unsigned int D.21942;
  unsigned int D.21943;
  void * D.21944;
  void * D.21947;
  unsigned int D.21950;
  unsigned int D.21951;
  void * D.21954;
  unsigned int D.21955;
  unsigned int D.21956;
  unsigned int eventidx.113;
  unsigned int D.21960;
  void * * D.21961;
  unsigned int D.21962;
  unsigned int D.21965;
  unsigned int D.21966;
  int D.21967;
  unsigned int i.114;
  int D.21976;
  unsigned int D.21981;
  unsigned int D.21982;
  void * D.21985;
  _Bool D.21990;
  long int D.21991;
  long int D.21992;
  struct MonoGHashTable * threads_starting_up.115;
  unsigned int D.21998;
  _Bool D.21999;
  _Bool D.22003;
  long int D.22004;
  long int D.22005;
  struct wait_data wait_data;
  struct wait_data * wait;
  int i;
  gsize self;
  void * * events;
  guint32 eventidx;
  gboolean starting;
  gboolean finished;

  try
    {
      wait = &wait_data;
      self = GetCurrentThreadId ();
      eventidx = 0;
      memset (wait, 0, 516);
      shutting_down.111 = shutting_down;
      D.21912 = shutting_down.111 == 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", 3128, "shutting_down");
      <D.21916>:
      finished = 0;
      goto <D.19448>;
      <D.19447>:
      wait->num = 0;
      D.21917 = &wait->threads;
      memset (D.21917, 0, 256);
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21918>; else goto <D.21919>;
        <D.21918>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21919>:
        D.21920 = ret != 0;
        D.21921 = (long int) D.21920;
        D.21922 = __builtin_expect (D.21921, 0);
        if (D.21922 != 0) goto <D.21923>; else goto <D.21924>;
        <D.21923>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3144, "ret == 0");
        <D.21924>:
      }
      threads.112 = threads;
      mono_g_hash_table_foreach (threads.112, collect_threads_for_suspend, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21926>; else goto <D.21927>;
        <D.21926>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21927>:
        D.21928 = ret != 0;
        D.21929 = (long int) D.21928;
        D.21930 = __builtin_expect (D.21929, 0);
        if (D.21930 != 0) goto <D.21931>; else goto <D.21932>;
        <D.21931>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3146, "ret == 0");
        <D.21932>:
      }
      D.21933 = wait->num;
      D.21934 = D.21933 * 4;
      events = monoeg_malloc0 (D.21934);
      eventidx = 0;
      i = 0;
      goto <D.19438>;
      <D.19437>:
      {
        struct MonoInternalThread * thread;
        gboolean signal_suspend;

        thread = wait->threads[i];
        signal_suspend = 0;
        D.21937 = thread->tid;
        D.21938 = (long long unsigned int) self;
        if (D.21937 == D.21938) goto <D.21935>; else goto <D.21939>;
        <D.21939>:
        D.21940 = mono_gc_is_finalizer_internal_thread (thread);
        if (D.21940 != 0) goto <D.21935>; else goto <D.21941>;
        <D.21941>:
        D.21942 = thread->flags;
        D.21943 = D.21942 & 1;
        if (D.21943 != 0) goto <D.21935>; else goto <D.21936>;
        <D.21935>:
        wait->threads[i] = 0B;
        // predicted unlikely by continue predictor.
        goto <D.19436>;
        <D.21936>:
        lock_thread (thread);
        D.21944 = thread->suspended_event;
        if (D.21944 == 0B) goto <D.21945>; else goto <D.21946>;
        <D.21945>:
        D.21947 = CreateEvent (0B, 1, 0, 0B);
        thread->suspended_event = D.21947;
        D.21944 = thread->suspended_event;
        if (D.21944 == 0B) goto <D.21948>; else goto <D.21949>;
        <D.21948>:
        unlock_thread (thread);
        // predicted unlikely by continue predictor.
        goto <D.19436>;
        <D.21949>:
        <D.21946>:
        D.21950 = BIT_FIELD_REF <*thread, 32, 224>;
        D.21951 = D.21950 & 81;
        if (D.21951 != 0) goto <D.21952>; else goto <D.21953>;
        <D.21952>:
        unlock_thread (thread);
        D.21954 = wait->handles[i];
        CloseHandle (D.21954);
        wait->threads[i] = 0B;
        // predicted unlikely by continue predictor.
        goto <D.19436>;
        <D.21953>:
        D.21955 = thread->state;
        D.21956 = D.21955 & 2;
        if (D.21956 == 0) goto <D.21957>; else goto <D.21958>;
        <D.21957>:
        signal_suspend = 1;
        <D.21958>:
        eventidx.113 = eventidx;
        eventidx = eventidx.113 + 1;
        D.21960 = eventidx.113 * 4;
        D.21961 = events + D.21960;
        D.21944 = thread->suspended_event;
        *D.21961 = D.21944;
        D.21955 = thread->state;
        D.21962 = D.21955 & 128;
        if (D.21962 != 0) goto <D.21963>; else goto <D.21964>;
        <D.21963>:
        D.21955 = thread->state;
        D.21965 = D.21955 & 4294967167;
        thread->state = D.21965;
        <D.21964>:
        D.21955 = thread->state;
        D.21966 = D.21955 | 2;
        thread->state = D.21966;
        unlock_thread (thread);
        D.21967 = mono_thread_info_new_interrupt_enabled ();
        if (D.21967 != 0) goto <D.21968>; else goto <D.21969>;
        <D.21968>:
        suspend_thread_internal (thread, 1);
        goto <D.21970>;
        <D.21969>:
        if (signal_suspend != 0) goto <D.21971>; else goto <D.21972>;
        <D.21971>:
        signal_thread_state_change (thread);
        <D.21972>:
        <D.21970>:
      }
      <D.19436>:
      i = i + 1;
      <D.19438>:
      i.114 = (unsigned int) i;
      D.21933 = wait->num;
      if (i.114 < D.21933) goto <D.19437>; else goto <D.19439>;
      <D.19439>:
      if (eventidx != 0) goto <D.21974>; else goto <D.21975>;
      <D.21974>:
      D.21976 = mono_thread_info_new_interrupt_enabled ();
      if (D.21976 == 0) goto <D.21977>; else goto <D.21978>;
      <D.21977>:
      WaitForMultipleObjectsEx (eventidx, events, 1, 100, 0);
      i = 0;
      goto <D.19443>;
      <D.19442>:
      {
        struct MonoInternalThread * thread;

        thread = wait->threads[i];
        if (thread == 0B) goto <D.21979>; else goto <D.21980>;
        <D.21979>:
        // predicted unlikely by continue predictor.
        goto <D.19441>;
        <D.21980>:
        lock_thread (thread);
        D.21981 = thread->state;
        D.21982 = D.21981 & 64;
        if (D.21982 != 0) goto <D.21983>; else goto <D.21984>;
        <D.21983>:
        D.21985 = thread->suspended_event;
        CloseHandle (D.21985);
        thread->suspended_event = 0B;
        <D.21984>:
        unlock_thread (thread);
      }
      <D.19441>:
      i = i + 1;
      <D.19443>:
      i.114 = (unsigned int) i;
      D.21933 = wait->num;
      if (i.114 < D.21933) goto <D.19442>; else goto <D.19444>;
      <D.19444>:
      <D.21978>:
      <D.21975>:
      if (eventidx == 0) goto <D.21986>; else goto <D.21987>;
      <D.21986>:
      {
        int ret;

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.21988>; else goto <D.21989>;
        <D.21988>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.21989>:
        D.21990 = ret != 0;
        D.21991 = (long int) D.21990;
        D.21992 = __builtin_expect (D.21991, 0);
        if (D.21992 != 0) goto <D.21993>; else goto <D.21994>;
        <D.21993>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3227, "ret == 0");
        <D.21994>:
      }
      threads_starting_up.115 = threads_starting_up;
      if (threads_starting_up.115 != 0B) goto <D.21996>; else goto <D.21997>;
      <D.21996>:
      threads_starting_up.115 = threads_starting_up;
      D.21998 = mono_g_hash_table_size (threads_starting_up.115);
      D.21999 = D.21998 != 0;
      starting = (gboolean) D.21999;
      goto <D.22000>;
      <D.21997>:
      starting = 0;
      <D.22000>:
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22001>; else goto <D.22002>;
        <D.22001>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22002>:
        D.22003 = ret != 0;
        D.22004 = (long int) D.22003;
        D.22005 = __builtin_expect (D.22004, 0);
        if (D.22005 != 0) goto <D.22006>; else goto <D.22007>;
        <D.22006>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3232, "ret == 0");
        <D.22007>:
      }
      if (starting != 0) goto <D.22008>; else goto <D.22009>;
      <D.22008>:
      Sleep (100);
      goto <D.22010>;
      <D.22009>:
      finished = 1;
      <D.22010>:
      <D.21987>:
      monoeg_g_free (events);
      <D.19448>:
      if (finished == 0) goto <D.19447>; else goto <D.19449>;
      <D.19449>:
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


collect_threads_for_suspend (void * key, void * value, void * user_data)
{
  unsigned int D.22011;
  unsigned int D.22012;
  unsigned int D.22015;
  long long unsigned int D.22018;
  unsigned int D.22019;
  unsigned int D.22022;
  struct MonoInternalThread * thread;
  struct wait_data * wait;
  void * handle;

  thread = value;
  wait = user_data;
  D.22011 = BIT_FIELD_REF <*thread, 32, 224>;
  D.22012 = D.22011 & 80;
  if (D.22012 != 0) goto <D.22013>; else goto <D.22014>;
  <D.22013>:
  return;
  <D.22014>:
  D.22015 = wait->num;
  if (D.22015 <= 63) goto <D.22016>; else goto <D.22017>;
  <D.22016>:
  D.22018 = thread->tid;
  D.22019 = (unsigned int) D.22018;
  handle = OpenThread (2032639, 1, D.22019);
  if (handle == 0B) goto <D.22020>; else goto <D.22021>;
  <D.22020>:
  return;
  <D.22021>:
  D.22015 = wait->num;
  wait->handles[D.22015] = handle;
  D.22015 = wait->num;
  wait->threads[D.22015] = thread;
  D.22015 = wait->num;
  D.22022 = D.22015 + 1;
  wait->num = D.22022;
  <D.22017>:
}


mono_threads_perform_thread_dump ()
{
  int thread_dump_requested.116;
  _Bool D.22029;
  long int D.22030;
  long int D.22031;
  struct MonoGHashTable * threads.117;
  _Bool D.22037;
  long int D.22038;
  long int D.22039;

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

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22027>; else goto <D.22028>;
    <D.22027>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22028>:
    D.22029 = ret != 0;
    D.22030 = (long int) D.22029;
    D.22031 = __builtin_expect (D.22030, 0);
    if (D.22031 != 0) goto <D.22032>; else goto <D.22033>;
    <D.22032>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3357, "ret == 0");
    <D.22033>:
  }
  threads.117 = threads;
  mono_g_hash_table_foreach (threads.117, dump_thread, 0B);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22035>; else goto <D.22036>;
    <D.22035>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22036>:
    D.22037 = ret != 0;
    D.22038 = (long int) D.22037;
    D.22039 = __builtin_expect (D.22038, 0);
    if (D.22039 != 0) goto <D.22040>; else goto <D.22041>;
    <D.22040>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3359, "ret == 0");
    <D.22041>:
  }
  thread_dump_requested = 0;
}


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

  thread = value;
  D.22043 = mono_thread_internal_current ();
  if (D.22043 == thread) goto <D.22044>; else goto <D.22045>;
  <D.22044>:
  return;
  <D.22045>:
  D.22046 = thread->tid;
  D.22047 = (long unsigned int) D.22046;
  info = mono_thread_info_safe_suspend_sync (D.22047, 0);
  if (info == 0B) goto <D.22048>; else goto <D.22049>;
  <D.22048>:
  return;
  <D.22049>:
  print_thread_dump (thread, info);
}


print_thread_dump (struct MonoInternalThread * thread, struct MonoThreadInfo * info)
{
  gunichar2 * D.22051;
  unsigned int D.22054;
  long int D.22055;
  struct GError * error.118;
  _Bool D.22057;
  long int D.22058;
  long int D.22059;
  unsigned char D.22063;
  struct MonoRuntimeExceptionHandlingCallbacks * D.22067;
  void (*<T265a>) (gboolean (*MonoInternalStackWalk) (struct MonoStackFrameInfo *, struct MonoContext *, void *), struct MonoThreadUnwindState *, MonoUnwindOptions, void *) D.22068;
  struct MonoThreadUnwindState * D.22069;
  unsigned int D.22070;
  struct _IO_FILE * stdout.119;
  char * D.22072;
  struct GString * text;
  char * name;
  struct GError * error;

  try
    {
      text = monoeg_g_string_new (0B);
      error = 0B;
      D.22051 = thread->name;
      if (D.22051 != 0B) goto <D.22052>; else goto <D.22053>;
      <D.22052>:
      D.22051 = thread->name;
      D.22054 = thread->name_len;
      D.22055 = (long int) D.22054;
      name = monoeg_g_utf16_to_utf8 (D.22051, D.22055, 0B, 0B, &error);
      error.118 = error;
      D.22057 = error.118 != 0B;
      D.22058 = (long int) D.22057;
      D.22059 = __builtin_expect (D.22058, 0);
      if (D.22059 != 0) goto <D.22060>; else goto <D.22061>;
      <D.22060>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3290, "!error");
      <D.22061>:
      monoeg_g_string_append_printf (text, "\n\"%s\"", name);
      monoeg_g_free (name);
      goto <D.22062>;
      <D.22053>:
      D.22063 = thread->threadpool_thread;
      if (D.22063 != 0) goto <D.22064>; else goto <D.22065>;
      <D.22064>:
      monoeg_g_string_append (text, "\n\"<threadpool thread>\"");
      goto <D.22066>;
      <D.22065>:
      monoeg_g_string_append (text, "\n\"<unnamed thread>\"");
      <D.22066>:
      <D.22062>:
      D.22067 = mono_get_eh_callbacks ();
      D.22068 = D.22067->mono_walk_stack_with_state;
      D.22069 = &info->suspend_state;
      D.22068 (print_stack_frame_to_string, D.22069, 0, text);
      D.22070 = info->node.key;
      mono_thread_info_resume (D.22070);
      stdout.119 = stdout;
      D.22072 = text->str;
      fprintf (stdout.119, "%s", D.22072);
      monoeg_g_string_free (text, 1);
      stdout.119 = stdout;
      fflush (stdout.119);
    }
  finally
    {
      error = {CLOBBER};
    }
}


print_stack_frame_to_string (struct MonoStackFrameInfo * frame, struct MonoContext * ctx, void * data)
{
  struct MonoJitInfo * D.22073;
  int D.22078;
  unsigned int D.22079;
  struct MonoDomain * D.22080;
  gboolean D.22082;
  struct GString * p;
  struct MonoMethod * method;

  p = data;
  method = 0B;
  D.22073 = frame->ji;
  if (D.22073 != 0B) goto <D.22074>; else goto <D.22075>;
  <D.22074>:
  D.22073 = frame->ji;
  method = mono_jit_info_get_method (D.22073);
  <D.22075>:
  if (method != 0B) goto <D.22076>; else goto <D.22077>;
  <D.22076>:
  {
    gchar * location;

    D.22078 = frame->native_offset;
    D.22079 = (unsigned int) D.22078;
    D.22080 = frame->domain;
    location = mono_debug_print_stack_frame (method, D.22079, D.22080);
    monoeg_g_string_append_printf (p, "  %s\n", location);
    monoeg_g_free (location);
  }
  goto <D.22081>;
  <D.22077>:
  D.22078 = frame->native_offset;
  monoeg_g_string_append_printf (p, "  at <unknown> <0x%05x>\n", D.22078);
  <D.22081>:
  D.22082 = 0;
  return D.22082;
}


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

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


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

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


mono_threads_request_thread_dump ()
{
  int D.22088;
  _Bool D.22093;
  long int D.22094;
  long int D.22095;
  struct MonoGHashTable * threads.120;
  _Bool D.22101;
  long int D.22102;
  long int D.22103;
  int D.22106;
  struct MonoInternalThread * D.22109;
  unsigned char D.22112;
  void * D.22115;
  unsigned int i.121;
  unsigned int D.22117;
  struct wait_data wait_data;
  struct wait_data * wait;
  int i;

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

        ret = pthread_mutex_lock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22091>; else goto <D.22092>;
        <D.22091>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22092>:
        D.22093 = ret != 0;
        D.22094 = (long int) D.22093;
        D.22095 = __builtin_expect (D.22094, 0);
        if (D.22095 != 0) goto <D.22096>; else goto <D.22097>;
        <D.22096>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3390, "ret == 0");
        <D.22097>:
      }
      threads.120 = threads;
      mono_g_hash_table_foreach (threads.120, collect_threads, wait);
      {
        int ret;

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22099>; else goto <D.22100>;
        <D.22099>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22100>:
        D.22101 = ret != 0;
        D.22102 = (long int) D.22101;
        D.22103 = __builtin_expect (D.22102, 0);
        if (D.22103 != 0) goto <D.22104>; else goto <D.22105>;
        <D.22104>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3392, "ret == 0");
        <D.22105>:
      }
      i = 0;
      goto <D.19496>;
      <D.19495>:
      {
        struct MonoInternalThread * thread;

        thread = wait->threads[i];
        D.22106 = mono_gc_is_finalizer_internal_thread (thread);
        if (D.22106 == 0) goto <D.22107>; else goto <D.22108>;
        <D.22107>:
        D.22109 = mono_thread_internal_current ();
        if (D.22109 != thread) goto <D.22110>; else goto <D.22111>;
        <D.22110>:
        D.22112 = thread->thread_dump_requested;
        if (D.22112 == 0) goto <D.22113>; else goto <D.22114>;
        <D.22113>:
        thread->thread_dump_requested = 1;
        signal_thread_state_change (thread);
        <D.22114>:
        <D.22111>:
        <D.22108>:
        D.22115 = wait->handles[i];
        CloseHandle (D.22115);
      }
      i = i + 1;
      <D.19496>:
      i.121 = (unsigned int) i;
      D.22117 = wait->num;
      if (i.121 < D.22117) goto <D.19495>; else goto <D.19497>;
      <D.19497>:
    }
  finally
    {
      wait_data = {CLOBBER};
    }
}


collect_threads (void * key, void * value, void * user_data)
{
  unsigned int D.22121;
  long long unsigned int D.22124;
  unsigned int D.22125;
  unsigned int D.22128;
  struct MonoInternalThread * thread;
  struct wait_data * wait;
  void * handle;

  thread = value;
  wait = user_data;
  D.22121 = wait->num;
  if (D.22121 <= 63) goto <D.22122>; else goto <D.22123>;
  <D.22122>:
  D.22124 = thread->tid;
  D.22125 = (unsigned int) D.22124;
  handle = OpenThread (2032639, 1, D.22125);
  if (handle == 0B) goto <D.22126>; else goto <D.22127>;
  <D.22126>:
  return;
  <D.22127>:
  D.22121 = wait->num;
  wait->handles[D.22121] = handle;
  D.22121 = wait->num;
  wait->threads[D.22121] = thread;
  D.22121 = wait->num;
  D.22128 = D.22121 + 1;
  wait->num = D.22128;
  <D.22123>:
}


mono_thread_push_appdomain_ref (struct MonoDomain * domain)
{
  volatile int * D.22132;
  int D.22133;
  void * D.22135;
  struct RefStack * D.22138;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.22130>; else goto <D.22131>;
  <D.22130>:
  <D.19531>:
  D.22132 = &thread->lock_thread_id;
  D.22133 = InterlockedCompareExchange (D.22132, 1, 0);
  if (D.22133 == 0) goto <D.19530>; else goto <D.22134>;
  <D.22134>:
  goto <D.19531>;
  <D.19530>:
  D.22135 = thread->appdomain_refs;
  if (D.22135 == 0B) goto <D.22136>; else goto <D.22137>;
  <D.22136>:
  D.22138 = ref_stack_new (16);
  thread->appdomain_refs = D.22138;
  <D.22137>:
  D.22135 = thread->appdomain_refs;
  ref_stack_push (D.22135, domain);
  thread->lock_thread_id = 0;
  <D.22131>:
}


ref_stack_new (gint initial_size)
{
  int D.22139;
  unsigned int initial_size.122;
  unsigned int D.22141;
  void * D.22142;
  struct RefStack * D.22143;
  struct RefStack * rs;

  D.22139 = MAX_EXPR <initial_size, 16>;
  initial_size = D.22139 + 1;
  rs = monoeg_malloc0 (12);
  initial_size.122 = (unsigned int) initial_size;
  D.22141 = initial_size.122 * 4;
  D.22142 = monoeg_malloc0 (D.22141);
  rs->refs = D.22142;
  rs->allocated = initial_size;
  D.22143 = rs;
  return D.22143;
}


ref_stack_push (struct RefStack * rs, void * ptr)
{
  _Bool D.22145;
  long int D.22146;
  long int D.22147;
  int D.22150;
  int D.22151;
  void * * D.22154;
  unsigned int D.22155;
  unsigned int D.22156;
  unsigned int D.22157;
  void * D.22158;
  int D.22159;
  unsigned int D.22160;
  void * * D.22161;
  int D.22162;
  int D.22163;
  unsigned int D.22164;
  unsigned int D.22165;
  void * * D.22166;

  D.22145 = rs == 0B;
  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", 3443, "rs != NULL");
  <D.22149>:
  D.22150 = rs->bottom;
  D.22151 = rs->allocated;
  if (D.22150 >= D.22151) goto <D.22152>; else goto <D.22153>;
  <D.22152>:
  D.22154 = rs->refs;
  D.22151 = rs->allocated;
  D.22155 = (unsigned int) D.22151;
  D.22156 = D.22155 * 8;
  D.22157 = D.22156 + 1;
  D.22158 = monoeg_realloc (D.22154, D.22157);
  rs->refs = D.22158;
  D.22151 = rs->allocated;
  D.22159 = D.22151 << 1;
  rs->allocated = D.22159;
  D.22154 = rs->refs;
  D.22151 = rs->allocated;
  D.22155 = (unsigned int) D.22151;
  D.22160 = D.22155 * 4;
  D.22161 = D.22154 + D.22160;
  *D.22161 = 0B;
  <D.22153>:
  D.22154 = rs->refs;
  D.22150 = rs->bottom;
  D.22162 = D.22150;
  D.22163 = D.22162 + 1;
  rs->bottom = D.22163;
  D.22164 = (unsigned int) D.22162;
  D.22165 = D.22164 * 4;
  D.22166 = D.22154 + D.22165;
  *D.22166 = ptr;
}


mono_thread_pop_appdomain_ref ()
{
  volatile int * D.22169;
  int D.22170;
  void * D.22172;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.22167>; else goto <D.22168>;
  <D.22167>:
  <D.19537>:
  D.22169 = &thread->lock_thread_id;
  D.22170 = InterlockedCompareExchange (D.22169, 1, 0);
  if (D.22170 == 0) goto <D.19536>; else goto <D.22171>;
  <D.22171>:
  goto <D.19537>;
  <D.19536>:
  D.22172 = thread->appdomain_refs;
  ref_stack_pop (D.22172);
  thread->lock_thread_id = 0;
  <D.22168>:
}


ref_stack_pop (struct RefStack * rs)
{
  int D.22176;
  int D.22177;
  void * * D.22178;
  unsigned int D.22179;
  unsigned int D.22180;
  void * * D.22181;

  if (rs == 0B) goto <D.22173>; else goto <D.22175>;
  <D.22175>:
  D.22176 = rs->bottom;
  if (D.22176 == 0) goto <D.22173>; else goto <D.22174>;
  <D.22173>:
  return;
  <D.22174>:
  D.22176 = rs->bottom;
  D.22177 = D.22176 + -1;
  rs->bottom = D.22177;
  D.22178 = rs->refs;
  D.22176 = rs->bottom;
  D.22179 = (unsigned int) D.22176;
  D.22180 = D.22179 * 4;
  D.22181 = D.22178 + D.22180;
  *D.22181 = 0B;
}


mono_thread_internal_has_appdomain_ref (struct MonoInternalThread * thread, struct MonoDomain * domain)
{
  volatile int * D.22183;
  int D.22184;
  void * D.22186;
  gboolean D.22187;
  gboolean res;

  <D.19544>:
  D.22183 = &thread->lock_thread_id;
  D.22184 = InterlockedCompareExchange (D.22183, 1, 0);
  if (D.22184 == 0) goto <D.19543>; else goto <D.22185>;
  <D.22185>:
  goto <D.19544>;
  <D.19543>:
  D.22186 = thread->appdomain_refs;
  res = ref_stack_find (D.22186, domain);
  thread->lock_thread_id = 0;
  D.22187 = res;
  return D.22187;
}


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

  if (rs == 0B) goto <D.22189>; else goto <D.22190>;
  <D.22189>:
  D.22191 = 0;
  return D.22191;
  <D.22190>:
  refs = rs->refs;
  goto <D.19524>;
  <D.19523>:
  D.22192 = *refs;
  if (D.22192 == ptr) goto <D.22193>; else goto <D.22194>;
  <D.22193>:
  D.22191 = 1;
  return D.22191;
  <D.22194>:
  refs = refs + 4;
  <D.19524>:
  if (refs != 0B) goto <D.22195>; else goto <D.19525>;
  <D.22195>:
  D.22192 = *refs;
  if (D.22192 != 0B) goto <D.19523>; else goto <D.19525>;
  <D.19525>:
  D.22191 = 0;
  return D.22191;
}


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

  D.22198 = thread->internal_thread;
  D.22197 = mono_thread_internal_has_appdomain_ref (D.22198, domain);
  return D.22197;
}


mono_threads_abort_appdomain_threads (struct MonoDomain * domain, int timeout)
{
  _Bool D.22202;
  long int D.22203;
  long int D.22204;
  struct MonoGHashTable * threads.123;
  _Bool D.22210;
  long int D.22211;
  long int D.22212;
  unsigned int D.22215;
  struct MonoInternalThread * D.22218;
  unsigned int i.124;
  unsigned int D.22220;
  unsigned int D.22221;
  unsigned int timeout.125;
  unsigned int D.22223;
  gboolean D.22228;
  struct abort_appdomain_data user_data;
  guint32 start_time;
  int orig_timeout;
  int i;

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

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

        ret = pthread_mutex_unlock (&threads_mutex.mutex);
        if (ret != 0) goto <D.22208>; else goto <D.22209>;
        <D.22208>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22209>:
        D.22210 = ret != 0;
        D.22211 = (long int) D.22210;
        D.22212 = __builtin_expect (D.22211, 0);
        if (D.22212 != 0) goto <D.22213>; else goto <D.22214>;
        <D.22213>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3586, "ret == 0");
        <D.22214>:
      }
      D.22215 = user_data.wait.num;
      if (D.22215 != 0) goto <D.22216>; else goto <D.22217>;
      <D.22216>:
      i = 0;
      goto <D.19573>;
      <D.19572>:
      D.22218 = user_data.wait.threads[i];
      ves_icall_System_Threading_Thread_Abort (D.22218, 0B);
      i = i + 1;
      <D.19573>:
      i.124 = (unsigned int) i;
      D.22215 = user_data.wait.num;
      if (i.124 < D.22215) goto <D.19572>; else goto <D.19574>;
      <D.19574>:
      wait_for_tids (&user_data.wait, 100);
      <D.22217>:
      D.22220 = mono_msec_ticks ();
      D.22221 = D.22220 - start_time;
      timeout.125 = (unsigned int) timeout;
      D.22223 = timeout.125 - D.22221;
      timeout = (int) D.22223;
      start_time = mono_msec_ticks ();
      if (orig_timeout != -1) goto <D.22224>; else goto <D.22225>;
      <D.22224>:
      if (timeout < 0) goto <D.22226>; else goto <D.22227>;
      <D.22226>:
      D.22228 = 0;
      return D.22228;
      <D.22227>:
      <D.22225>:
      D.22215 = user_data.wait.num;
      if (D.22215 != 0) goto <D.19575>; else goto <D.19576>;
      <D.19576>:
      D.22228 = 1;
      return D.22228;
    }
  finally
    {
      user_data = {CLOBBER};
    }
}


collect_appdomain_thread (void * key, void * value, void * user_data)
{
  int D.22231;
  unsigned int D.22234;
  long long unsigned int D.22237;
  unsigned int D.22238;
  unsigned int D.22241;
  struct MonoInternalThread * thread;
  struct abort_appdomain_data * data;
  struct MonoDomain * domain;

  thread = value;
  data = user_data;
  domain = data->domain;
  D.22231 = mono_thread_internal_has_appdomain_ref (thread, domain);
  if (D.22231 != 0) goto <D.22232>; else goto <D.22233>;
  <D.22232>:
  D.22234 = data->wait.num;
  if (D.22234 <= 63) goto <D.22235>; else goto <D.22236>;
  <D.22235>:
  {
    void * handle;

    D.22237 = thread->tid;
    D.22238 = (unsigned int) D.22237;
    handle = OpenThread (2032639, 1, D.22238);
    if (handle == 0B) goto <D.22239>; else goto <D.22240>;
    <D.22239>:
    return;
    <D.22240>:
    D.22234 = data->wait.num;
    data->wait.handles[D.22234] = handle;
    D.22234 = data->wait.num;
    data->wait.threads[D.22234] = thread;
    D.22234 = data->wait.num;
    D.22241 = D.22234 + 1;
    data->wait.num = D.22241;
  }
  goto <D.22242>;
  <D.22236>:
  <D.22242>:
  <D.22233>:
}


mono_threads_clear_cached_culture (struct MonoDomain * domain)
{
  _Bool D.22246;
  long int D.22247;
  long int D.22248;
  struct MonoGHashTable * threads.126;
  _Bool D.22254;
  long int D.22255;
  long int D.22256;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22244>; else goto <D.22245>;
    <D.22244>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22245>:
    D.22246 = ret != 0;
    D.22247 = (long int) D.22246;
    D.22248 = __builtin_expect (D.22247, 0);
    if (D.22248 != 0) goto <D.22249>; else goto <D.22250>;
    <D.22249>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3642, "ret == 0");
    <D.22250>:
  }
  threads.126 = threads;
  mono_g_hash_table_foreach (threads.126, clear_cached_culture, domain);
  {
    int ret;

    ret = pthread_mutex_unlock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22252>; else goto <D.22253>;
    <D.22252>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22253>:
    D.22254 = ret != 0;
    D.22255 = (long int) D.22254;
    D.22256 = __builtin_expect (D.22255, 0);
    if (D.22256 != 0) goto <D.22257>; else goto <D.22258>;
    <D.22257>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3644, "ret == 0");
    <D.22258>:
  }
}


clear_cached_culture (void * key, void * value, void * user_data)
{
  struct MonoArray * D.22259;
  unsigned int i.127;
  char * D.22263;
  struct MonoVTable * D.22266;
  struct MonoDomain * D.22267;
  struct MonoInternalThread * thread;
  struct MonoDomain * domain;
  int i;

  thread = value;
  domain = user_data;
  D.22259 = thread->cached_culture_info;
  if (D.22259 != 0B) goto <D.22260>; else goto <D.22261>;
  <D.22260>:
  i = 0;
  goto <D.19588>;
  <D.19587>:
  {
    struct MonoObject * obj;

    D.22259 = thread->cached_culture_info;
    i.127 = (unsigned int) i;
    D.22263 = mono_array_addr_with_size (D.22259, 4, i.127);
    obj = MEM[(struct MonoObject * *)D.22263];
    if (obj != 0B) goto <D.22264>; else goto <D.22265>;
    <D.22264>:
    D.22266 = obj->vtable;
    D.22267 = D.22266->domain;
    if (D.22267 == domain) goto <D.22268>; else goto <D.22269>;
    <D.22268>:
    {
      struct MonoObject * * __p;

      D.22259 = thread->cached_culture_info;
      i.127 = (unsigned int) i;
      __p = mono_array_addr_with_size (D.22259, 4, i.127);
      *__p = 0B;
    }
    <D.22269>:
    <D.22265>:
  }
  i = i + 1;
  <D.19588>:
  if (i <= 7) goto <D.19587>; else goto <D.19589>;
  <D.19589>:
  <D.22261>:
}


mono_thread_get_undeniable_exception ()
{
  struct MonoException * D.22272;
  int D.22275;
  struct MonoException * D.22278;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread != 0B) goto <D.22270>; else goto <D.22271>;
  <D.22270>:
  D.22272 = thread->abort_exc;
  if (D.22272 != 0B) goto <D.22273>; else goto <D.22274>;
  <D.22273>:
  D.22275 = is_running_protected_wrapper ();
  if (D.22275 == 0) goto <D.22276>; else goto <D.22277>;
  <D.22276>:
  D.22272 = thread->abort_exc;
  D.22272->trace_ips = 0B;
  D.22272 = thread->abort_exc;
  D.22272->stack_trace = 0B;
  D.22278 = thread->abort_exc;
  return D.22278;
  <D.22277>:
  <D.22274>:
  <D.22271>:
  D.22278 = 0B;
  return D.22278;
}


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

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


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

  if (managed != 0) goto <D.22283>; else goto <D.22284>;
  <D.22283>:
  D.22285 = 1;
  return D.22285;
  <D.22284>:
  D.22286 = mono_threads_is_critical_method (m);
  if (D.22286 != 0) goto <D.22287>; else goto <D.22288>;
  <D.22287>:
  MEM[(gboolean *)data] = 1;
  D.22285 = 1;
  return D.22285;
  <D.22288>:
  D.22285 = 0;
  return D.22285;
}


mono_alloc_special_static_data (guint32 static_type, guint32 size, guint32 align, uintptr_t * bitmap, int numbits)
{
  _Bool D.22294;
  long int D.22295;
  long int D.22296;
  struct MonoGHashTable * threads.128;
  void * offset.129;
  _Bool D.22308;
  long int D.22309;
  long int D.22310;
  _Bool D.22314;
  long int D.22315;
  long int D.22316;
  _Bool D.22321;
  long int D.22322;
  long int D.22323;
  _Bool D.22328;
  long int D.22329;
  long int D.22330;
  uint32_t D.22333;
  guint32 offset;

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

    {
      int ret;

      ret = pthread_mutex_lock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22292>; else goto <D.22293>;
      <D.22292>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22293>:
      D.22294 = ret != 0;
      D.22295 = (long int) D.22294;
      D.22296 = __builtin_expect (D.22295, 0);
      if (D.22296 != 0) goto <D.22297>; else goto <D.22298>;
      <D.22297>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3902, "ret == 0");
      <D.22298>:
    }
    item = search_tls_slot_in_freelist (&thread_static_info, size, align);
    if (item != 0B) goto <D.22299>; else goto <D.22300>;
    <D.22299>:
    offset = item->offset;
    monoeg_g_free (item);
    goto <D.22301>;
    <D.22300>:
    offset = mono_alloc_static_data_slot (&thread_static_info, size, align);
    <D.22301>:
    update_tls_reference_bitmap (offset, bitmap, numbits);
    threads.128 = threads;
    if (threads.128 != 0B) goto <D.22303>; else goto <D.22304>;
    <D.22303>:
    threads.128 = threads;
    offset.129 = (void *) offset;
    mono_g_hash_table_foreach (threads.128, alloc_thread_static_data_helper, offset.129);
    <D.22304>:
    {
      int ret;

      ret = pthread_mutex_unlock (&threads_mutex.mutex);
      if (ret != 0) goto <D.22306>; else goto <D.22307>;
      <D.22306>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22307>:
      D.22308 = ret != 0;
      D.22309 = (long int) D.22308;
      D.22310 = __builtin_expect (D.22309, 0);
      if (D.22310 != 0) goto <D.22311>; else goto <D.22312>;
      <D.22311>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3915, "ret == 0");
      <D.22312>:
    }
  }
  goto <D.22313>;
  <D.22291>:
  D.22314 = static_type != 2;
  D.22315 = (long int) D.22314;
  D.22316 = __builtin_expect (D.22315, 0);
  if (D.22316 != 0) goto <D.22317>; else goto <D.22318>;
  <D.22317>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3917, "static_type == SPECIAL_STATIC_CONTEXT");
  <D.22318>:
  {
    int ret;

    ret = pthread_mutex_lock (&contexts_mutex.mutex);
    if (ret != 0) goto <D.22319>; else goto <D.22320>;
    <D.22319>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22320>:
    D.22321 = ret != 0;
    D.22322 = (long int) D.22321;
    D.22323 = __builtin_expect (D.22322, 0);
    if (D.22323 != 0) goto <D.22324>; else goto <D.22325>;
    <D.22324>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3918, "ret == 0");
    <D.22325>:
  }
  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.22326>; else goto <D.22327>;
    <D.22326>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22327>:
    D.22328 = ret != 0;
    D.22329 = (long int) D.22328;
    D.22330 = __builtin_expect (D.22329, 0);
    if (D.22330 != 0) goto <D.22331>; else goto <D.22332>;
    <D.22331>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3920, "ret == 0");
    <D.22332>:
  }
  offset = offset | 2147483648;
  <D.22313>:
  D.22333 = offset;
  return D.22333;
}


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

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


search_tls_slot_in_freelist (struct StaticDataInfo * static_data, guint32 size, guint32 align)
{
  unsigned int D.22336;
  struct MonoThreadDomainTls * D.22341;
  struct MonoThreadDomainTls * D.22343;
  struct MonoThreadDomainTls * prev;
  struct MonoThreadDomainTls * tmp;

  prev = 0B;
  tmp = static_data->freelist;
  goto <D.19675>;
  <D.19674>:
  D.22336 = tmp->size;
  if (D.22336 == size) goto <D.22337>; else goto <D.22338>;
  <D.22337>:
  if (prev != 0B) goto <D.22339>; else goto <D.22340>;
  <D.22339>:
  D.22341 = tmp->next;
  prev->next = D.22341;
  goto <D.22342>;
  <D.22340>:
  D.22341 = tmp->next;
  static_data->freelist = D.22341;
  <D.22342>:
  D.22343 = tmp;
  return D.22343;
  <D.22338>:
  tmp = tmp->next;
  <D.19675>:
  if (tmp != 0B) goto <D.19674>; else goto <D.19676>;
  <D.19676>:
  D.22343 = 0B;
  return D.22343;
}


update_tls_reference_bitmap (guint32 offset, uintptr_t * bitmap, int numbits)
{
  unsigned int D.22345;
  unsigned int D.22346;
  uintptr_t * D.22347;
  int D.22350;
  unsigned int D.22351;
  unsigned int D.22352;
  unsigned int D.22353;
  unsigned int D.22354;
  void * D.22355;
  unsigned int i.130;
  unsigned int D.22357;
  unsigned int D.22358;
  uintptr_t * D.22359;
  unsigned int D.22360;
  int D.22361;
  long int D.22362;
  long unsigned int D.22363;
  long unsigned int D.22364;
  unsigned int i.131;
  unsigned int D.22368;
  unsigned int D.22369;
  unsigned int D.22370;
  uintptr_t * D.22371;
  unsigned int D.22372;
  int D.22373;
  int D.22374;
  long int D.22375;
  long unsigned int D.22376;
  long unsigned int D.22377;
  int i;
  int idx;
  uintptr_t * rb;

  D.22345 = offset >> 24;
  D.22346 = D.22345 + 4294967295;
  idx = (int) D.22346;
  D.22347 = static_reference_bitmaps[idx];
  if (D.22347 == 0B) goto <D.22348>; else goto <D.22349>;
  <D.22348>:
  D.22350 = static_data_size[idx];
  D.22351 = (unsigned int) D.22350;
  D.22352 = D.22351 / 128;
  D.22353 = D.22352 + 1;
  D.22354 = D.22353 * 4;
  D.22355 = monoeg_malloc0 (D.22354);
  static_reference_bitmaps[idx] = D.22355;
  <D.22349>:
  rb = static_reference_bitmaps[idx];
  offset = offset & 16777215;
  offset = offset / 4;
  i = 0;
  goto <D.19686>;
  <D.19685>:
  i.130 = (unsigned int) i;
  D.22357 = i.130 / 4;
  D.22358 = D.22357 * 4;
  D.22359 = bitmap + D.22358;
  D.22360 = *D.22359;
  D.22361 = i & 31;
  D.22362 = 1 << D.22361;
  D.22363 = (long unsigned int) D.22362;
  D.22364 = D.22360 & D.22363;
  if (D.22364 != 0) goto <D.22365>; else goto <D.22366>;
  <D.22365>:
  i.131 = (unsigned int) i;
  D.22368 = offset + i.131;
  D.22369 = D.22368 / 32;
  D.22370 = D.22369 * 4;
  D.22371 = rb + D.22370;
  D.22370 = D.22369 * 4;
  D.22371 = rb + D.22370;
  D.22372 = *D.22371;
  i.131 = (unsigned int) i;
  D.22368 = offset + i.131;
  D.22373 = (int) D.22368;
  D.22374 = D.22373 & 31;
  D.22375 = 1 << D.22374;
  D.22376 = (long unsigned int) D.22375;
  D.22377 = D.22372 | D.22376;
  *D.22371 = D.22377;
  <D.22366>:
  i = i + 1;
  <D.19686>:
  if (i < numbits) goto <D.19685>; else goto <D.19687>;
  <D.19687>:
}


mono_alloc_static_data_slot (struct StaticDataInfo * static_data, guint32 size, guint32 align)
{
  int D.22378;
  int D.22381;
  unsigned int D.22384;
  unsigned int D.22385;
  unsigned int D.22386;
  int D.22387;
  unsigned int D.22388;
  unsigned int D.22389;
  int D.22390;
  unsigned int D.22391;
  int D.22392;
  unsigned int D.22393;
  int D.22396;
  _Bool D.22397;
  long int D.22398;
  long int D.22399;
  _Bool D.22402;
  long int D.22403;
  long int D.22404;
  int D.22407;
  int D.22408;
  int D.22409;
  guint32 D.22410;
  guint32 offset;

  D.22378 = static_data->idx;
  if (D.22378 == 0) goto <D.22379>; else goto <D.22380>;
  <D.22379>:
  D.22381 = static_data->offset;
  if (D.22381 == 0) goto <D.22382>; else goto <D.22383>;
  <D.22382>:
  static_data->offset = 32;
  <D.22383>:
  <D.22380>:
  D.22381 = static_data->offset;
  D.22384 = (unsigned int) D.22381;
  D.22385 = D.22384 + align;
  D.22386 = D.22385 + 4294967295;
  D.22387 = (int) D.22386;
  static_data->offset = D.22387;
  D.22381 = static_data->offset;
  D.22384 = (unsigned int) D.22381;
  D.22388 = -align;
  D.22389 = D.22384 & D.22388;
  D.22390 = (int) D.22389;
  static_data->offset = D.22390;
  D.22381 = static_data->offset;
  D.22384 = (unsigned int) D.22381;
  D.22391 = D.22384 + size;
  D.22378 = static_data->idx;
  D.22392 = static_data_size[D.22378];
  D.22393 = (unsigned int) D.22392;
  if (D.22391 >= D.22393) goto <D.22394>; else goto <D.22395>;
  <D.22394>:
  D.22378 = static_data->idx;
  D.22396 = D.22378 + 1;
  static_data->idx = D.22396;
  D.22378 = static_data->idx;
  D.22392 = static_data_size[D.22378];
  D.22393 = (unsigned int) D.22392;
  D.22397 = D.22393 < size;
  D.22398 = (long int) D.22397;
  D.22399 = __builtin_expect (D.22398, 0);
  if (D.22399 != 0) goto <D.22400>; else goto <D.22401>;
  <D.22400>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3801, "size <= static_data_size [static_data->idx]");
  <D.22401>:
  D.22378 = static_data->idx;
  D.22402 = D.22378 > 7;
  D.22403 = (long int) D.22402;
  D.22404 = __builtin_expect (D.22403, 0);
  if (D.22404 != 0) goto <D.22405>; else goto <D.22406>;
  <D.22405>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3802, "static_data->idx < NUM_STATIC_DATA_IDX");
  <D.22406>:
  static_data->offset = 0;
  <D.22395>:
  D.22381 = static_data->offset;
  D.22378 = static_data->idx;
  D.22396 = D.22378 + 1;
  D.22407 = D.22396 << 24;
  D.22408 = D.22381 | D.22407;
  offset = (guint32) D.22408;
  D.22381 = static_data->offset;
  D.22384 = (unsigned int) D.22381;
  D.22391 = D.22384 + size;
  D.22409 = (int) D.22391;
  static_data->offset = D.22409;
  D.22410 = offset;
  return D.22410;
}


mono_get_special_static_data_for_thread (struct MonoInternalThread * thread, guint32 offset)
{
  unsigned int D.22412;
  unsigned int D.22413;
  void * D.22416;
  void * * D.22419;
  unsigned int idx.132;
  unsigned int D.22422;
  void * * D.22423;
  void * D.22424;
  _Bool D.22427;
  long int D.22428;
  long int D.22429;
  void * * * D.22432;
  _Bool D.22435;
  long int D.22436;
  long int D.22437;
  sizetype D.22440;
  guint32 static_type;
  int idx;

  static_type = offset & 2147483648;
  offset = offset & 2147483647;
  D.22412 = offset >> 24;
  D.22413 = D.22412 + 4294967295;
  idx = (int) D.22413;
  if (static_type == 0) goto <D.22414>; else goto <D.22415>;
  <D.22414>:
  D.22416 = get_thread_static_data (thread, offset);
  return D.22416;
  <D.22415>:
  {
    struct MonoAppContext * context;

    context = mono_context_get ();
    D.22419 = context->static_data;
    if (D.22419 == 0B) goto <D.22417>; else goto <D.22420>;
    <D.22420>:
    D.22419 = context->static_data;
    idx.132 = (unsigned int) idx;
    D.22422 = idx.132 * 4;
    D.22423 = D.22419 + D.22422;
    D.22424 = *D.22423;
    if (D.22424 == 0B) goto <D.22417>; else goto <D.22418>;
    <D.22417>:
    {
      int ret;

      ret = pthread_mutex_lock (&contexts_mutex.mutex);
      if (ret != 0) goto <D.22425>; else goto <D.22426>;
      <D.22425>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22426>:
      D.22427 = ret != 0;
      D.22428 = (long int) D.22427;
      D.22429 = __builtin_expect (D.22428, 0);
      if (D.22429 != 0) goto <D.22430>; else goto <D.22431>;
      <D.22430>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3945, "ret == 0");
      <D.22431>:
    }
    D.22432 = &context->static_data;
    mono_alloc_static_data (D.22432, offset, 0);
    {
      int ret;

      ret = pthread_mutex_unlock (&contexts_mutex.mutex);
      if (ret != 0) goto <D.22433>; else goto <D.22434>;
      <D.22433>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22434>:
      D.22435 = ret != 0;
      D.22436 = (long int) D.22435;
      D.22437 = __builtin_expect (D.22436, 0);
      if (D.22437 != 0) goto <D.22438>; else goto <D.22439>;
      <D.22438>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 3947, "ret == 0");
      <D.22439>:
    }
    <D.22418>:
    D.22419 = context->static_data;
    idx.132 = (unsigned int) idx;
    D.22422 = idx.132 * 4;
    D.22423 = D.22419 + D.22422;
    D.22424 = *D.22423;
    D.22440 = offset & 16777215;
    D.22416 = D.22424 + D.22440;
    return D.22416;
  }
}


mono_get_special_static_data (guint32 offset)
{
  void * D.22442;
  struct MonoInternalThread * D.22443;

  D.22443 = mono_thread_internal_current ();
  D.22442 = mono_get_special_static_data_for_thread (D.22443, offset);
  return D.22442;
}


mono_alloc_special_static_data_free (struct GHashTable * special_static_fields)
{
  _Bool D.22447;
  long int D.22448;
  long int D.22449;
  _Bool D.22454;
  long int D.22455;
  long int D.22456;

  {
    int ret;

    ret = pthread_mutex_lock (&threads_mutex.mutex);
    if (ret != 0) goto <D.22445>; else goto <D.22446>;
    <D.22445>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22446>:
    D.22447 = ret != 0;
    D.22448 = (long int) D.22447;
    D.22449 = __builtin_expect (D.22448, 0);
    if (D.22449 != 0) goto <D.22450>; else goto <D.22451>;
    <D.22450>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4020, "ret == 0");
    <D.22451>:
  }
  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.22452>; else goto <D.22453>;
    <D.22452>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22453>:
    D.22454 = ret != 0;
    D.22455 = (long int) D.22454;
    D.22456 = __builtin_expect (D.22455, 0);
    if (D.22456 != 0) goto <D.22457>; else goto <D.22458>;
    <D.22457>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4022, "ret == 0");
    <D.22458>:
  }
}


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

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


do_free_special_slot (guint32 offset, guint32 size)
{
  unsigned int D.22463;
  unsigned int D.22464;
  unsigned int D.22465;
  struct MonoGHashTable * threads.133;
  int D.22469;
  struct MonoThreadDomainTls * D.22472;
  guint32 static_type;

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

    try
      {
        item = monoeg_malloc0 (12);
        D.22463 = offset & 2147483647;
        data.offset = D.22463;
        data.size = size;
        D.22464 = data.offset;
        D.22465 = data.size;
        clear_reference_bitmap (D.22464, D.22465);
        threads.133 = threads;
        if (threads.133 != 0B) goto <D.22467>; else goto <D.22468>;
        <D.22467>:
        threads.133 = threads;
        mono_g_hash_table_foreach (threads.133, free_thread_static_data_helper, &data);
        <D.22468>:
        item->offset = offset;
        item->size = size;
        D.22469 = mono_runtime_is_shutting_down ();
        if (D.22469 == 0) goto <D.22470>; else goto <D.22471>;
        <D.22470>:
        D.22472 = thread_static_info.freelist;
        item->next = D.22472;
        thread_static_info.freelist = item;
        goto <D.22473>;
        <D.22471>:
        monoeg_g_free (item);
        <D.22473>:
      }
    finally
      {
        data = {CLOBBER};
      }
  }
  goto <D.22474>;
  <D.22462>:
  <D.22474>:
}


free_thread_static_data_helper (void * key, void * value, void * user)
{
  unsigned int D.22475;
  unsigned int D.22476;
  unsigned int D.22477;
  void * * D.22480;
  unsigned int idx.134;
  unsigned int D.22483;
  void * * D.22484;
  void * D.22485;
  sizetype D.22486;
  unsigned int D.22487;
  struct MonoInternalThread * thread;
  struct TlsOffsetSize * data;
  int idx;
  char * ptr;

  thread = value;
  data = user;
  D.22475 = data->offset;
  D.22476 = D.22475 >> 24;
  D.22477 = D.22476 + 4294967295;
  idx = (int) D.22477;
  D.22480 = thread->static_data;
  if (D.22480 == 0B) goto <D.22478>; else goto <D.22481>;
  <D.22481>:
  D.22480 = thread->static_data;
  idx.134 = (unsigned int) idx;
  D.22483 = idx.134 * 4;
  D.22484 = D.22480 + D.22483;
  D.22485 = *D.22484;
  if (D.22485 == 0B) goto <D.22478>; else goto <D.22479>;
  <D.22478>:
  return;
  <D.22479>:
  D.22480 = thread->static_data;
  idx.134 = (unsigned int) idx;
  D.22483 = idx.134 * 4;
  D.22484 = D.22480 + D.22483;
  D.22485 = *D.22484;
  D.22475 = data->offset;
  D.22486 = D.22475 & 16777215;
  ptr = D.22485 + D.22486;
  D.22487 = data->size;
  mono_gc_bzero_atomic (ptr, D.22487);
}


clear_reference_bitmap (guint32 offset, guint32 size)
{
  unsigned int D.22489;
  unsigned int D.22490;
  unsigned int D.22491;
  unsigned int D.22492;
  uintptr_t * D.22493;
  unsigned int D.22494;
  int offset.135;
  int D.22496;
  long int D.22497;
  long int D.22498;
  long unsigned int D.22499;
  long unsigned int D.22500;
  int idx;
  uintptr_t * rb;

  D.22489 = offset >> 24;
  D.22490 = D.22489 + 4294967295;
  idx = (int) D.22490;
  rb = static_reference_bitmaps[idx];
  offset = offset & 16777215;
  offset = offset / 4;
  size = size / 4;
  size = size + offset;
  goto <D.19695>;
  <D.19694>:
  D.22491 = offset / 32;
  D.22492 = D.22491 * 4;
  D.22493 = rb + D.22492;
  D.22492 = D.22491 * 4;
  D.22493 = rb + D.22492;
  D.22494 = *D.22493;
  offset.135 = (int) offset;
  D.22496 = offset.135 & 31;
  D.22497 = 1 << D.22496;
  D.22498 = ~D.22497;
  D.22499 = (long unsigned int) D.22498;
  D.22500 = D.22494 & D.22499;
  *D.22493 = D.22500;
  offset = offset + 1;
  <D.19695>:
  if (offset < size) goto <D.19694>; else goto <D.19696>;
  <D.19696>:
}


mono_special_static_data_free_slot (guint32 offset, guint32 size)
{
  _Bool D.22503;
  long int D.22504;
  long int D.22505;
  _Bool D.22510;
  long int D.22511;
  long int D.22512;

  {
    int ret;

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

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


mono_thread_alloc_tls (struct MonoReflectionType * type)
{
  struct MonoType * D.22515;
  int D.22516;
  int align.136;
  unsigned int align.137;
  int max_set.138;
  int D.22520;
  union mono_mutex_t * D.22523;
  _Bool D.22526;
  long int D.22527;
  long int D.22528;
  struct MonoTlsDataRecord * D.22531;
  _Bool D.22534;
  long int D.22535;
  long int D.22536;
  uint32_t D.22539;
  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.22515 = type->type;
      klass = mono_class_from_mono_type (D.22515);
      bitmap = mono_class_compute_bitmap (klass, &default_bitmap, 128, -2, &max_set, 0);
      D.22515 = type->type;
      D.22516 = mono_type_size (D.22515, &align);
      size = (guint32) D.22516;
      align.136 = align;
      align.137 = (unsigned int) align.136;
      max_set.138 = max_set;
      D.22520 = max_set.138 + 1;
      tls_offset = mono_alloc_special_static_data (1, size, align.137, bitmap, D.22520);
      if (&default_bitmap != bitmap) goto <D.22521>; else goto <D.22522>;
      <D.22521>:
      monoeg_g_free (bitmap);
      <D.22522>:
      tlsrec = monoeg_malloc0 (12);
      tlsrec->tls_offset = tls_offset;
      tlsrec->size = size;
      {
        int ret;

        D.22523 = &domain->lock.mutex;
        ret = pthread_mutex_lock (D.22523);
        if (ret != 0) goto <D.22524>; else goto <D.22525>;
        <D.22524>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.22525>:
        D.22526 = ret != 0;
        D.22527 = (long int) D.22526;
        D.22528 = __builtin_expect (D.22527, 0);
        if (D.22528 != 0) goto <D.22529>; else goto <D.22530>;
        <D.22529>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4060, "ret == 0");
        <D.22530>:
      }
      D.22531 = domain->tlsrec_list;
      tlsrec->next = D.22531;
      domain->tlsrec_list = tlsrec;
      {
        int ret;

        D.22523 = &domain->lock.mutex;
        ret = pthread_mutex_unlock (D.22523);
        if (ret != 0) goto <D.22532>; else goto <D.22533>;
        <D.22532>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.22533>:
        D.22534 = ret != 0;
        D.22535 = (long int) D.22534;
        D.22536 = __builtin_expect (D.22535, 0);
        if (D.22536 != 0) goto <D.22537>; else goto <D.22538>;
        <D.22537>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4063, "ret == 0");
        <D.22538>:
      }
      D.22539 = tls_offset;
      return D.22539;
    }
  finally
    {
      max_set = {CLOBBER};
      default_bitmap = {CLOBBER};
      align = {CLOBBER};
    }
}


mono_thread_destroy_tls (uint32_t tls_offset)
{
  union mono_mutex_t * D.22542;
  _Bool D.22545;
  long int D.22546;
  long int D.22547;
  unsigned int D.22550;
  struct MonoTlsDataRecord * D.22555;
  _Bool D.22559;
  long int D.22560;
  long int D.22561;
  struct MonoTlsDataRecord * prev;
  struct MonoTlsDataRecord * cur;
  guint32 size;
  struct MonoDomain * domain;

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

    D.22542 = &domain->lock.mutex;
    ret = pthread_mutex_lock (D.22542);
    if (ret != 0) goto <D.22543>; else goto <D.22544>;
    <D.22543>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22544>:
    D.22545 = ret != 0;
    D.22546 = (long int) D.22545;
    D.22547 = __builtin_expect (D.22546, 0);
    if (D.22547 != 0) goto <D.22548>; else goto <D.22549>;
    <D.22548>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4074, "ret == 0");
    <D.22549>:
  }
  cur = domain->tlsrec_list;
  goto <D.19786>;
  <D.19785>:
  D.22550 = cur->tls_offset;
  if (D.22550 == tls_offset) goto <D.22551>; else goto <D.22552>;
  <D.22551>:
  if (prev != 0B) goto <D.22553>; else goto <D.22554>;
  <D.22553>:
  D.22555 = cur->next;
  prev->next = D.22555;
  goto <D.22556>;
  <D.22554>:
  D.22555 = cur->next;
  domain->tlsrec_list = D.22555;
  <D.22556>:
  size = cur->size;
  monoeg_g_free (cur);
  goto <D.19784>;
  <D.22552>:
  prev = cur;
  cur = cur->next;
  <D.19786>:
  if (cur != 0B) goto <D.19785>; else goto <D.19784>;
  <D.19784>:
  {
    int ret;

    D.22542 = &domain->lock.mutex;
    ret = pthread_mutex_unlock (D.22542);
    if (ret != 0) goto <D.22557>; else goto <D.22558>;
    <D.22557>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22558>:
    D.22559 = ret != 0;
    D.22560 = (long int) D.22559;
    D.22561 = __builtin_expect (D.22560, 0);
    if (D.22561 != 0) goto <D.22562>; else goto <D.22563>;
    <D.22562>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4089, "ret == 0");
    <D.22563>:
  }
  if (size != 0) goto <D.22564>; else goto <D.22565>;
  <D.22564>:
  mono_special_static_data_free_slot (tls_offset, size);
  <D.22565>:
}


mono_thread_destroy_domain_tls (struct MonoDomain * domain)
{
  struct MonoTlsDataRecord * D.22566;
  unsigned int D.22567;

  goto <D.19792>;
  <D.19791>:
  D.22566 = domain->tlsrec_list;
  D.22567 = D.22566->tls_offset;
  mono_thread_destroy_tls (D.22567);
  <D.19792>:
  D.22566 = domain->tlsrec_list;
  if (D.22566 != 0B) goto <D.19791>; else goto <D.19793>;
  <D.19793>:
}


mono_thread_free_local_slot_values (int slot, MonoBoolean thread_local)
{
  struct MonoClassField * local_slots.139;
  struct MonoClass * D.22573;
  struct MonoClassField * local_slots.140;
  union mono_mutex_t * D.22577;
  _Bool D.22580;
  long int D.22581;
  long int D.22582;
  struct GHashTable * D.22585;
  _Bool D.22590;
  long int D.22591;
  long int D.22592;
  unsigned int addr.141;
  unsigned int D.22598;
  unsigned int D.22599;
  unsigned int D.22600;
  unsigned int D.22601;
  int D.22602;
  _Bool D.22605;
  long int D.22606;
  long int D.22607;
  struct MonoGHashTable * threads.142;
  _Bool D.22613;
  long int D.22614;
  long int D.22615;
  struct MonoDomain * domain;
  struct LocalSlotID sid;

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

        addr = 0B;
        local_slots.139 = local_slots;
        if (local_slots.139 == 0B) goto <D.22571>; else goto <D.22572>;
        <D.22571>:
        D.22573 = mono_defaults.thread_class;
        local_slots.140 = mono_class_get_field_from_name (D.22573, "local_slots");
        local_slots = local_slots.140;
        local_slots.139 = local_slots;
        if (local_slots.139 == 0B) goto <D.22575>; else goto <D.22576>;
        <D.22575>:
        monoeg_g_log (0B, 16, "local_slots field not found in Thread class");
        return;
        <D.22576>:
        <D.22572>:
        domain = mono_domain_get ();
        {
          int ret;

          D.22577 = &domain->lock.mutex;
          ret = pthread_mutex_lock (D.22577);
          if (ret != 0) goto <D.22578>; else goto <D.22579>;
          <D.22578>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.22579>:
          D.22580 = ret != 0;
          D.22581 = (long int) D.22580;
          D.22582 = __builtin_expect (D.22581, 0);
          if (D.22582 != 0) goto <D.22583>; else goto <D.22584>;
          <D.22583>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4150, "ret == 0");
          <D.22584>:
        }
        D.22585 = domain->special_static_fields;
        if (D.22585 != 0B) goto <D.22586>; else goto <D.22587>;
        <D.22586>:
        D.22585 = domain->special_static_fields;
        local_slots.139 = local_slots;
        addr = monoeg_g_hash_table_lookup (D.22585, local_slots.139);
        <D.22587>:
        {
          int ret;

          D.22577 = &domain->lock.mutex;
          ret = pthread_mutex_unlock (D.22577);
          if (ret != 0) goto <D.22588>; else goto <D.22589>;
          <D.22588>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.22589>:
          D.22590 = ret != 0;
          D.22591 = (long int) D.22590;
          D.22592 = __builtin_expect (D.22591, 0);
          if (D.22592 != 0) goto <D.22593>; else goto <D.22594>;
          <D.22593>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4153, "ret == 0");
          <D.22594>:
        }
        if (addr == 0B) goto <D.22595>; else goto <D.22596>;
        <D.22595>:
        return;
        <D.22596>:
        addr.141 = (unsigned int) addr;
        sid.offset = addr.141;
        D.22598 = sid.offset;
        D.22599 = D.22598 & 2147483647;
        sid.offset = D.22599;
        D.22598 = sid.offset;
        D.22600 = D.22598 >> 24;
        D.22601 = D.22600 + 4294967295;
        D.22602 = (int) D.22601;
        sid.idx = D.22602;
        {
          int ret;

          ret = pthread_mutex_lock (&threads_mutex.mutex);
          if (ret != 0) goto <D.22603>; else goto <D.22604>;
          <D.22603>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.22604>:
          D.22605 = ret != 0;
          D.22606 = (long int) D.22605;
          D.22607 = __builtin_expect (D.22606, 0);
          if (D.22607 != 0) goto <D.22608>; else goto <D.22609>;
          <D.22608>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4160, "ret == 0");
          <D.22609>:
        }
        threads.142 = threads;
        mono_g_hash_table_foreach (threads.142, clear_local_slot, &sid);
        {
          int ret;

          ret = pthread_mutex_unlock (&threads_mutex.mutex);
          if (ret != 0) goto <D.22611>; else goto <D.22612>;
          <D.22611>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.22612>:
          D.22613 = ret != 0;
          D.22614 = (long int) D.22613;
          D.22615 = __builtin_expect (D.22614, 0);
          if (D.22615 != 0) goto <D.22616>; else goto <D.22617>;
          <D.22616>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4162, "ret == 0");
          <D.22617>:
        }
      }
      goto <D.22618>;
      <D.22569>:
      <D.22618>:
    }
  finally
    {
      sid = {CLOBBER};
    }
}


clear_local_slot (void * key, void * value, void * user_data)
{
  void * * D.22624;
  int D.22626;
  unsigned int D.22627;
  unsigned int D.22628;
  void * * D.22629;
  void * D.22630;
  unsigned int D.22631;
  sizetype D.22632;
  struct MonoArray * * D.22633;
  int D.22637;
  unsigned int D.22638;
  unsigned int D.22639;
  struct LocalSlotID * sid;
  struct MonoInternalThread * thread;
  struct MonoArray * slots_array;

  sid = user_data;
  thread = value;
  D.22624 = thread->static_data;
  if (D.22624 == 0B) goto <D.22622>; else goto <D.22625>;
  <D.22625>:
  D.22624 = thread->static_data;
  D.22626 = sid->idx;
  D.22627 = (unsigned int) D.22626;
  D.22628 = D.22627 * 4;
  D.22629 = D.22624 + D.22628;
  D.22630 = *D.22629;
  if (D.22630 == 0B) goto <D.22622>; else goto <D.22623>;
  <D.22622>:
  return;
  <D.22623>:
  D.22624 = thread->static_data;
  D.22626 = sid->idx;
  D.22627 = (unsigned int) D.22626;
  D.22628 = D.22627 * 4;
  D.22629 = D.22624 + D.22628;
  D.22630 = *D.22629;
  D.22631 = sid->offset;
  D.22632 = D.22631 & 16777215;
  D.22633 = D.22630 + D.22632;
  slots_array = *D.22633;
  if (slots_array == 0B) goto <D.22634>; else goto <D.22636>;
  <D.22636>:
  D.22637 = sid->slot;
  D.22638 = (unsigned int) D.22637;
  D.22639 = mono_array_length (slots_array);
  if (D.22638 >= D.22639) goto <D.22634>; else goto <D.22635>;
  <D.22634>:
  return;
  <D.22635>:
  {
    struct MonoObject * * __p;

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


mono_thread_request_interruption (gboolean running_managed)
{
  struct MonoException * D.22643;
  gint32 * D.22644;
  int D.22645;
  int D.22651;
  void (*<T468>) (void) mono_thread_notify_pending_exc_fn.143;
  void * D.22657;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22641>; else goto <D.22642>;
  <D.22641>:
  D.22643 = 0B;
  return D.22643;
  <D.22642>:
  D.22644 = &thread->interruption_requested;
  D.22645 = InterlockedCompareExchange (D.22644, 1, 0);
  if (D.22645 == 1) goto <D.22646>; else goto <D.22647>;
  <D.22646>:
  D.22643 = 0B;
  return D.22643;
  <D.22647>:
  InterlockedIncrement (&thread_interruption_requested);
  if (running_managed == 0) goto <D.22648>; else goto <D.22650>;
  <D.22650>:
  D.22651 = is_running_protected_wrapper ();
  if (D.22651 != 0) goto <D.22648>; else goto <D.22649>;
  <D.22648>:
  mono_thread_notify_pending_exc_fn.143 = mono_thread_notify_pending_exc_fn;
  if (mono_thread_notify_pending_exc_fn.143 != 0B) goto <D.22653>; else goto <D.22654>;
  <D.22653>:
  if (running_managed == 0) goto <D.22655>; else goto <D.22656>;
  <D.22655>:
  mono_thread_notify_pending_exc_fn.143 = mono_thread_notify_pending_exc_fn;
  mono_thread_notify_pending_exc_fn.143 ();
  <D.22656>:
  <D.22654>:
  D.22657 = thread->handle;
  QueueUserAPC (dummy_apc, D.22657, 0B);
  D.22643 = 0B;
  return D.22643;
  <D.22649>:
  D.22643 = mono_thread_execute_interruption (thread);
  return D.22643;
}


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

  D.22659 = 0;
  return D.22659;
}


mono_thread_resume_interruption ()
{
  struct MonoException * D.22663;
  unsigned int D.22664;
  unsigned int D.22665;
  _Bool D.22666;
  gint32 * D.22669;
  int D.22670;
  struct MonoInternalThread * thread;
  gboolean still_aborting;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22661>; else goto <D.22662>;
  <D.22661>:
  D.22663 = 0B;
  return D.22663;
  <D.22662>:
  lock_thread (thread);
  D.22664 = thread->state;
  D.22665 = D.22664 & 128;
  D.22666 = D.22665 != 0;
  still_aborting = (gboolean) D.22666;
  unlock_thread (thread);
  if (still_aborting == 0) goto <D.22667>; else goto <D.22668>;
  <D.22667>:
  D.22663 = 0B;
  return D.22663;
  <D.22668>:
  D.22669 = &thread->interruption_requested;
  D.22670 = InterlockedCompareExchange (D.22669, 1, 0);
  if (D.22670 == 1) goto <D.22671>; else goto <D.22672>;
  <D.22671>:
  D.22663 = 0B;
  return D.22663;
  <D.22672>:
  InterlockedIncrement (&thread_interruption_requested);
  wapi_self_interrupt ();
  D.22663 = mono_thread_execute_interruption (thread);
  return D.22663;
}


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

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

    thread = mono_thread_internal_current ();
    if (thread != 0B) goto <D.22677>; else goto <D.22678>;
    <D.22677>:
    D.22679 = thread->interruption_requested;
    return D.22679;
    <D.22678>:
  }
  <D.22676>:
  D.22679 = 0;
  return D.22679;
}


mono_thread_interruption_checkpoint ()
{
  mono_thread_interruption_checkpoint_request (0);
}


mono_thread_interruption_checkpoint_request (gboolean bypass_abort_protection)
{
  int D.22685;
  int D.22689;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22681>; else goto <D.22682>;
  <D.22681>:
  return;
  <D.22682>:
  D.22685 = thread->interruption_requested;
  if (D.22685 != 0) goto <D.22686>; else goto <D.22687>;
  <D.22686>:
  if (bypass_abort_protection != 0) goto <D.22683>; else goto <D.22688>;
  <D.22688>:
  D.22689 = is_running_protected_wrapper ();
  if (D.22689 == 0) goto <D.22683>; else goto <D.22684>;
  <D.22683>:
  {
    struct MonoException * exc;

    exc = mono_thread_execute_interruption (thread);
    if (exc != 0B) goto <D.22690>; else goto <D.22691>;
    <D.22690>:
    mono_raise_exception (exc);
    <D.22691>:
  }
  <D.22684>:
  <D.22687>:
}


mono_thread_force_interruption_checkpoint ()
{
  mono_thread_interruption_checkpoint_request (1);
}


mono_thread_get_and_clear_pending_exception ()
{
  struct MonoException * D.22695;
  int D.22696;
  int D.22699;
  struct MonoException * D.22702;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  if (thread == 0B) goto <D.22693>; else goto <D.22694>;
  <D.22693>:
  D.22695 = 0B;
  return D.22695;
  <D.22694>:
  D.22696 = thread->interruption_requested;
  if (D.22696 != 0) goto <D.22697>; else goto <D.22698>;
  <D.22697>:
  D.22699 = is_running_protected_wrapper ();
  if (D.22699 == 0) goto <D.22700>; else goto <D.22701>;
  <D.22700>:
  D.22695 = mono_thread_execute_interruption (thread);
  return D.22695;
  <D.22701>:
  <D.22698>:
  D.22702 = thread->pending_exception;
  if (D.22702 != 0B) goto <D.22703>; else goto <D.22704>;
  <D.22703>:
  {
    struct MonoException * exc;

    exc = thread->pending_exception;
    thread->pending_exception = 0B;
    D.22695 = exc;
    return D.22695;
  }
  <D.22704>:
  D.22695 = 0B;
  return D.22695;
}


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

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


mono_thread_interruption_request_flag ()
{
  gint32 * D.22710;

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


mono_thread_init_apartment_state ()
{

}


mono_thread_cleanup_apartment_state ()
{

}


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

  lock_thread (thread);
  D.22712 = thread->state;
  D.22713 = D.22712 | state;
  thread->state = D.22713;
  unlock_thread (thread);
}


mono_thread_clr_state (struct MonoInternalThread * thread, MonoThreadState state)
{
  unsigned int D.22714;
  unsigned int D.22715;
  unsigned int D.22716;

  lock_thread (thread);
  D.22714 = thread->state;
  D.22715 = ~state;
  D.22716 = D.22714 & D.22715;
  thread->state = D.22716;
  unlock_thread (thread);
}


mono_thread_test_state (struct MonoInternalThread * thread, MonoThreadState test)
{
  unsigned int D.22717;
  unsigned int D.22718;
  gboolean D.22721;
  gboolean ret;

  ret = 0;
  lock_thread (thread);
  D.22717 = thread->state;
  D.22718 = D.22717 & test;
  if (D.22718 != 0) goto <D.22719>; else goto <D.22720>;
  <D.22719>:
  ret = 1;
  <D.22720>:
  unlock_thread (thread);
  D.22721 = ret;
  return D.22721;
}


mono_thread_get_execution_context ()
{
  struct MonoObject * D.22723;
  struct MonoObject * * D.22724;

  D.22724 = get_execution_context_addr ();
  D.22723 = *D.22724;
  return D.22723;
}


get_execution_context_addr ()
{
  struct MonoClass * D.22728;
  _Bool D.22729;
  long int D.22730;
  long int D.22731;
  struct MonoClass * D.22734;
  struct MonoVTable * D.22735;
  _Bool D.22736;
  long int D.22737;
  long int D.22738;
  union mono_mutex_t * D.22741;
  _Bool D.22744;
  long int D.22745;
  long int D.22746;
  struct GHashTable * D.22749;
  void * D.22750;
  _Bool D.22753;
  long int D.22754;
  long int D.22755;
  _Bool D.22758;
  long int D.22759;
  long int D.22760;
  struct MonoObject * * D.22763;
  struct MonoDomain * domain;
  guint32 offset;

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

    D.22728 = mono_defaults.thread_class;
    field = mono_class_get_field_from_name (D.22728, "_ec");
    D.22729 = field == 0B;
    D.22730 = (long int) D.22729;
    D.22731 = __builtin_expect (D.22730, 0);
    if (D.22731 != 0) goto <D.22732>; else goto <D.22733>;
    <D.22732>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4501, "field");
    <D.22733>:
    D.22734 = mono_defaults.appdomain_class;
    D.22735 = mono_class_try_get_vtable (domain, D.22734);
    D.22736 = D.22735 == 0B;
    D.22737 = (long int) D.22736;
    D.22738 = __builtin_expect (D.22737, 0);
    if (D.22738 != 0) goto <D.22739>; else goto <D.22740>;
    <D.22739>:
    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.22740>:
    {
      int ret;

      D.22741 = &domain->lock.mutex;
      ret = pthread_mutex_lock (D.22741);
      if (ret != 0) goto <D.22742>; else goto <D.22743>;
      <D.22742>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.22743>:
      D.22744 = ret != 0;
      D.22745 = (long int) D.22744;
      D.22746 = __builtin_expect (D.22745, 0);
      if (D.22746 != 0) goto <D.22747>; else goto <D.22748>;
      <D.22747>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4505, "ret == 0");
      <D.22748>:
    }
    D.22749 = domain->special_static_fields;
    D.22750 = monoeg_g_hash_table_lookup (D.22749, field);
    offset = (guint32) D.22750;
    {
      int ret;

      D.22741 = &domain->lock.mutex;
      ret = pthread_mutex_unlock (D.22741);
      if (ret != 0) goto <D.22751>; else goto <D.22752>;
      <D.22751>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.22752>:
      D.22753 = ret != 0;
      D.22754 = (long int) D.22753;
      D.22755 = __builtin_expect (D.22754, 0);
      if (D.22755 != 0) goto <D.22756>; else goto <D.22757>;
      <D.22756>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4507, "ret == 0");
      <D.22757>:
    }
    D.22758 = offset == 0;
    D.22759 = (long int) D.22758;
    D.22760 = __builtin_expect (D.22759, 0);
    if (D.22760 != 0) goto <D.22761>; else goto <D.22762>;
    <D.22761>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threads.c", 4508, "offset");
    <D.22762>:
    domain->execution_context_field_offset = offset;
  }
  <D.22727>:
  D.22763 = mono_get_special_static_data (offset);
  return D.22763;
}


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

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


mono_runtime_set_has_tls_get (gboolean val)
{
  has_tls_get = val;
}


mono_runtime_has_tls_get ()
{
  gboolean D.22766;

  D.22766 = has_tls_get;
  return D.22766;
}


mono_thread_kill (struct MonoInternalThread * thread, int signal)
{
  int D.22768;
  long long unsigned int D.22769;
  long unsigned int D.22770;
  int D.22771;

  D.22769 = thread->tid;
  D.22770 = (long unsigned int) D.22769;
  D.22771 = mono_thread_get_abort_signal ();
  D.22768 = pthread_kill (D.22770, D.22771);
  return D.22768;
}


mono_thread_is_foreign (struct MonoThread * thread)
{
  struct _MonoInternalThread * D.22773;
  mono_bool D.22774;
  int D.22775;
  _Bool D.22776;
  struct MonoThreadInfo * info;

  D.22773 = thread->internal_thread;
  info = D.22773->thread_info;
  D.22775 = info->runtime_thread;
  D.22776 = D.22775 == 0;
  D.22774 = (mono_bool) D.22776;
  return D.22774;
}


