mono_thread_pool_remove_socket (int sock)
{
  int D.19091;
  _Bool D.19096;
  long int D.19097;
  long int D.19098;
  struct MonoGHashTable * D.19101;
  _Bool D.19106;
  long int D.19107;
  long int D.19108;
  long int D.19111;
  const void * D.19112;
  void * list.0;
  struct MonoMList * list.1;
  _Bool D.19119;
  long int D.19120;
  long int D.19121;
  int D.19124;
  struct MonoMList * list;
  struct MonoSocketAsyncResult * state;
  struct MonoObject * ares;

  try
    {
      D.19091 = socket_io_data.inited;
      if (D.19091 == 0) goto <D.19092>; else goto <D.19093>;
      <D.19092>:
      return;
      <D.19093>:
      {
        int ret;

        ret = pthread_mutex_lock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.19094>; else goto <D.19095>;
        <D.19094>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.19095>:
        D.19096 = ret != 0;
        D.19097 = (long int) D.19096;
        D.19098 = __builtin_expect (D.19097, 0);
        if (D.19098 != 0) goto <D.19099>; else goto <D.19100>;
        <D.19099>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 446, "ret == 0");
        <D.19100>:
      }
      D.19101 = socket_io_data.sock_to_state;
      if (D.19101 == 0B) goto <D.19102>; else goto <D.19103>;
      <D.19102>:
      {
        int ret;

        ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.19104>; else goto <D.19105>;
        <D.19104>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19105>:
        D.19106 = ret != 0;
        D.19107 = (long int) D.19106;
        D.19108 = __builtin_expect (D.19107, 0);
        if (D.19108 != 0) goto <D.19109>; else goto <D.19110>;
        <D.19109>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 448, "ret == 0");
        <D.19110>:
      }
      return;
      <D.19103>:
      D.19111 = (long int) sock;
      D.19112 = (const void *) D.19111;
      D.19101 = socket_io_data.sock_to_state;
      list.0 = mono_g_hash_table_lookup (D.19101, D.19112);
      list = list.0;
      list.1 = list;
      if (list.1 != 0B) goto <D.19115>; else goto <D.19116>;
      <D.19115>:
      D.19111 = (long int) sock;
      D.19112 = (const void *) D.19111;
      D.19101 = socket_io_data.sock_to_state;
      mono_g_hash_table_remove (D.19101, D.19112);
      <D.19116>:
      {
        int ret;

        ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.19117>; else goto <D.19118>;
        <D.19117>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19118>:
        D.19119 = ret != 0;
        D.19120 = (long int) D.19119;
        D.19121 = __builtin_expect (D.19120, 0);
        if (D.19121 != 0) goto <D.19122>; else goto <D.19123>;
        <D.19122>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 454, "ret == 0");
        <D.19123>:
      }
      goto <D.18714>;
      <D.18713>:
      list.1 = list;
      state = mono_mlist_get_data (list.1);
      D.19124 = state->operation;
      if (D.19124 == 2) goto <D.19125>; else goto <D.19126>;
      <D.19125>:
      state->operation = 6;
      goto <D.19127>;
      <D.19126>:
      D.19124 = state->operation;
      if (D.19124 == 4) goto <D.19128>; else goto <D.19129>;
      <D.19128>:
      state->operation = 7;
      <D.19129>:
      <D.19127>:
      ares = get_io_event (&list, 1);
      threadpool_append_job (&async_io_tp, ares);
      list.1 = list;
      if (list.1 != 0B) goto <D.19130>; else goto <D.19131>;
      <D.19130>:
      ares = get_io_event (&list, 4);
      threadpool_append_job (&async_io_tp, ares);
      <D.19131>:
      <D.18714>:
      list.1 = list;
      if (list.1 != 0B) goto <D.18713>; else goto <D.18715>;
      <D.18715>:
    }
  finally
    {
      list = {CLOBBER};
    }
}


get_io_event (struct MonoMList * * list, gint event)
{
  int D.19135;
  struct MonoMList * D.19141;
  struct MonoMList * D.19143;
  struct MonoMList * D.19144;
  struct MonoObject * D.19145;
  struct MonoObject * state;
  struct MonoMList * current;
  struct MonoMList * prev;

  current = *list;
  prev = 0B;
  state = 0B;
  goto <D.18703>;
  <D.18702>:
  state = mono_mlist_get_data (current);
  D.19135 = get_event_from_state (state);
  if (D.19135 == event) goto <D.18701>; else goto <D.19136>;
  <D.19136>:
  state = 0B;
  prev = current;
  current = mono_mlist_next (current);
  <D.18703>:
  if (current != 0B) goto <D.18702>; else goto <D.18701>;
  <D.18701>:
  if (current != 0B) goto <D.19137>; else goto <D.19138>;
  <D.19137>:
  if (prev != 0B) goto <D.19139>; else goto <D.19140>;
  <D.19139>:
  D.19141 = mono_mlist_next (current);
  mono_mlist_set_next (prev, D.19141);
  goto <D.19142>;
  <D.19140>:
  D.19143 = *list;
  D.19144 = mono_mlist_next (D.19143);
  *list = D.19144;
  <D.19142>:
  <D.19138>:
  D.19145 = state;
  return D.19145;
}


get_event_from_state (struct MonoSocketAsyncResult * state)
{
  int D.19147;
  int D.19148;

  D.19147 = state->operation;
  switch (D.19147) <default: <D.18677>, case 0: <D.18664>, case 1: <D.18674>, case 2: <D.18665>, case 3: <D.18667>, case 4: <D.18671>, case 5: <D.18673>, case 6: <D.18666>, case 7: <D.18672>, case 8: <D.18668>, case 10: <D.18676>, case 11: <D.18669>, case 12: <D.18670>, case 13: <D.18675>>
  <D.18664>:
  <D.18665>:
  <D.18666>:
  <D.18667>:
  <D.18668>:
  <D.18669>:
  <D.18670>:
  D.19148 = 1;
  return D.19148;
  <D.18671>:
  <D.18672>:
  <D.18673>:
  <D.18674>:
  <D.18675>:
  <D.18676>:
  D.19148 = 4;
  return D.19148;
  <D.18677>:
  monoeg_g_log (0B, 32, "get_event_from_state: unknown value in switch!!!");
  D.19148 = 0;
  return D.19148;
}


threadpool_append_job (struct ThreadPool * tp, struct MonoObject * ar)
{
  threadpool_append_jobs (tp, &ar, 1);
}


threadpool_append_jobs (struct ThreadPool * tp, struct MonoObject * * jobs, gint njobs)
{
  int D.19150;
  int D.19153;
  volatile gint * D.19156;
  int D.19157;
  int D.19160;
  struct MonoDomain * D.19163;
  int D.19164;
  struct MonoDomain * D.19167;
  long unsigned int D.19168;
  long unsigned int D.19169;
  struct MonoObject * * D.19170;
  struct MonoVTable * D.19174;
  struct MonoDomain * D.19175;
  int D.19176;
  int D.19179;
  int D.19180;
  long int D.19183;
  void * D.19184;
  int D.19187;
  struct MonoCQ * D.19190;
  int D.19191;
  int iftmp.2;
  int D.19194;
  static int job_counter;
  struct MonoObject * ar;
  gint i;

  D.19150 = mono_runtime_is_shutting_down ();
  if (D.19150 != 0) goto <D.19151>; else goto <D.19152>;
  <D.19151>:
  return;
  <D.19152>:
  D.19153 = tp->pool_status;
  if (D.19153 == 0) goto <D.19154>; else goto <D.19155>;
  <D.19154>:
  D.19156 = &tp->pool_status;
  D.19157 = InterlockedCompareExchange (D.19156, 1, 0);
  if (D.19157 == 0) goto <D.19158>; else goto <D.19159>;
  <D.19158>:
  D.19160 = tp->is_io;
  if (D.19160 == 0) goto <D.19161>; else goto <D.19162>;
  <D.19161>:
  D.19163 = mono_get_root_domain ();
  mono_thread_create_internal (D.19163, monitor_thread, 0B, 1, 0, 262144);
  threadpool_start_thread (tp);
  <D.19162>:
  D.19164 = mono_config_is_server_mode ();
  if (D.19164 != 0) goto <D.19165>; else goto <D.19166>;
  <D.19165>:
  D.19167 = mono_get_root_domain ();
  mono_thread_create_internal (D.19167, threadpool_start_idle_threads, tp, 1, 0, 262144);
  <D.19166>:
  <D.19159>:
  <D.19155>:
  i = 0;
  goto <D.18887>;
  <D.18886>:
  D.19168 = (long unsigned int) i;
  D.19169 = D.19168 * 8;
  D.19170 = jobs + D.19169;
  ar = *D.19170;
  if (ar == 0B) goto <D.19171>; else goto <D.19173>;
  <D.19173>:
  D.19174 = ar->vtable;
  D.19175 = D.19174->domain;
  D.19176 = mono_domain_is_unloading (D.19175);
  if (D.19176 != 0) goto <D.19171>; else goto <D.19172>;
  <D.19171>:
  // predicted unlikely by continue predictor.
  goto <D.18884>;
  <D.19172>:
  D.19160 = tp->is_io;
  if (D.19160 == 0) goto <D.19177>; else goto <D.19178>;
  <D.19177>:
  D.19179 = InterlockedIncrement (&job_counter);
  D.19180 = D.19179 % 10;
  if (D.19180 == 0) goto <D.19181>; else goto <D.19182>;
  <D.19181>:
  {
    struct MonoAsyncResult * o;

    o = ar;
    D.19183 = mono_100ns_ticks ();
    o->add_time = D.19183;
  }
  <D.19182>:
  <D.19178>:
  threadpool_jobs_inc (ar);
  D.19184 = tp->pc_nitems;
  mono_perfcounter_update_value (D.19184, 1, 1);
  D.19160 = tp->is_io;
  if (D.19160 == 0) goto <D.19185>; else goto <D.19186>;
  <D.19185>:
  D.19187 = mono_wsq_local_push (ar);
  if (D.19187 != 0) goto <D.19188>; else goto <D.19189>;
  <D.19188>:
  // predicted unlikely by continue predictor.
  goto <D.18884>;
  <D.19189>:
  <D.19186>:
  D.19190 = tp->queue;
  mono_cq_enqueue (D.19190, ar);
  <D.18884>:
  i = i + 1;
  <D.18887>:
  if (i < njobs) goto <D.18886>; else goto <D.18888>;
  <D.18888>:
  i = 0;
  goto <D.18890>;
  <D.18889>:
  pulse_on_new_job (tp);
  i = i + 1;
  <D.18890>:
  D.19191 = tp->waiting;
  if (D.19191 > 0) goto <D.19192>; else goto <D.18891>;
  <D.19192>:
  D.19194 = tp->max_threads;
  if (D.19194 <= njobs) goto <D.19195>; else goto <D.19196>;
  <D.19195>:
  iftmp.2 = tp->max_threads;
  goto <D.19197>;
  <D.19196>:
  iftmp.2 = njobs;
  <D.19197>:
  if (iftmp.2 > i) goto <D.18889>; else goto <D.18891>;
  <D.18891>:
}


threadpool_start_idle_threads (struct ThreadPool * tp)
{
  guint32 iftmp.3;
  int D.19200;
  int D.19204;
  int D.19207;
  volatile gint * D.19208;
  int D.19209;
  void * D.19211;
  void (*<Tbd4>) (void *) D.19212;
  struct MonoDomain * D.19213;
  int n;
  guint32 stack_size;

  D.19200 = tp->is_io;
  if (D.19200 == 0) goto <D.19201>; else goto <D.19202>;
  <D.19201>:
  iftmp.3 = 0;
  goto <D.19203>;
  <D.19202>:
  iftmp.3 = 262144;
  <D.19203>:
  stack_size = iftmp.3;
  <D.18765>:
  <D.18764>:
  n = tp->nthreads;
  D.19204 = tp->min_threads;
  if (D.19204 <= n) goto <D.19205>; else goto <D.19206>;
  <D.19205>:
  return;
  <D.19206>:
  D.19207 = n + 1;
  D.19208 = &tp->nthreads;
  D.19209 = InterlockedCompareExchange (D.19208, D.19207, n);
  if (D.19209 == n) goto <D.18763>; else goto <D.19210>;
  <D.19210>:
  goto <D.18764>;
  <D.18763>:
  D.19211 = tp->pc_nthreads;
  mono_perfcounter_update_value (D.19211, 1, 1);
  D.19212 = tp->async_invoke;
  D.19213 = mono_get_root_domain ();
  mono_thread_create_internal (D.19213, D.19212, tp, 1, 0, stack_size);
  SleepEx (100, 1);
  goto <D.18765>;
}


monitor_thread (void * unused)
{
  struct MonoDomain * D.19215;
  struct MonoString * D.19216;
  unsigned int D.19217;
  unsigned int D.19219;
  unsigned int D.19220;
  int D.19221;
  unsigned int D.19223;
  unsigned int D.19224;
  int i.4;
  int D.19229;
  int suspended.5;
  int D.19234;
  struct MonoCQ * D.19237;
  int D.19238;
  _Bool D.19239;
  int D.19242;
  _Bool D.19247;
  long int D.19248;
  long int D.19249;
  struct GPtrArray * wsqs.6;
  void * * D.19253;
  long unsigned int D.19254;
  long unsigned int D.19255;
  void * * D.19256;
  int D.19257;
  unsigned int i.7;
  unsigned int D.19262;
  _Bool D.19265;
  long int D.19266;
  long int D.19267;
  struct ThreadPool * pools[2];
  struct MonoInternalThread * thread;
  guint32 ms;
  gboolean need_one;
  int i;

  try
    {
      pools[0] = &async_tp;
      pools[1] = &async_io_tp;
      thread = mono_thread_internal_current ();
      D.19215 = mono_domain_get ();
      D.19216 = mono_string_new (D.19215, "Threadpool monitor");
      ves_icall_System_Threading_Thread_SetName_internal (thread, D.19216);
      <D.18807>:
      ms = 500;
      i = 10;
      <D.18793>:
      {
        guint32 ts;

        ts = mono_msec_ticks ();
        D.19217 = SleepEx (ms, 1);
        if (D.19217 == 0) goto <D.18792>; else goto <D.19218>;
        <D.19218>:
        D.19219 = mono_msec_ticks ();
        D.19220 = D.19219 - ts;
        ms = ms - D.19220;
        D.19221 = mono_runtime_is_shutting_down ();
        if (D.19221 != 0) goto <D.18792>; else goto <D.19222>;
        <D.19222>:
        D.19223 = thread->state;
        D.19224 = D.19223 & 3;
        if (D.19224 != 0) goto <D.19225>; else goto <D.19226>;
        <D.19225>:
        mono_thread_interruption_checkpoint ();
        <D.19226>:
      }
      if (ms != 0) goto <D.19227>; else goto <D.18792>;
      <D.19227>:
      i.4 = i;
      i = i.4 + -1;
      if (i.4 != 0) goto <D.18793>; else goto <D.18792>;
      <D.18792>:
      D.19229 = mono_runtime_is_shutting_down ();
      if (D.19229 != 0) goto <D.18794>; else goto <D.19230>;
      <D.19230>:
      suspended.5 = suspended;
      if (suspended.5 != 0) goto <D.19232>; else goto <D.19233>;
      <D.19232>:
      // predicted unlikely by continue predictor.
      goto <D.18795>;
      <D.19233>:
      i = 0;
      goto <D.18805>;
      <D.18804>:
      {
        struct ThreadPool * tp;

        tp = pools[i];
        D.19234 = tp->waiting;
        if (D.19234 > 0) goto <D.19235>; else goto <D.19236>;
        <D.19235>:
        // predicted unlikely by continue predictor.
        goto <D.18797>;
        <D.19236>:
        D.19237 = tp->queue;
        D.19238 = mono_cq_count (D.19237);
        D.19239 = D.19238 > 0;
        need_one = (gboolean) D.19239;
        if (need_one == 0) goto <D.19240>; else goto <D.19241>;
        <D.19240>:
        D.19242 = tp->is_io;
        if (D.19242 == 0) goto <D.19243>; else goto <D.19244>;
        <D.19243>:
        {
          int ret;

          ret = pthread_mutex_lock (&wsqs_lock.mutex);
          if (ret != 0) goto <D.19245>; else goto <D.19246>;
          <D.19245>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.19246>:
          D.19247 = ret != 0;
          D.19248 = (long int) D.19247;
          D.19249 = __builtin_expect (D.19248, 0);
          if (D.19249 != 0) goto <D.19250>; else goto <D.19251>;
          <D.19250>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 801, "ret == 0");
          <D.19251>:
        }
        i = 0;
        goto <D.18802>;
        <D.18801>:
        {
          struct MonoWSQ * wsq;

          wsqs.6 = wsqs;
          D.19253 = wsqs.6->pdata;
          D.19254 = (long unsigned int) i;
          D.19255 = D.19254 * 8;
          D.19256 = D.19253 + D.19255;
          wsq = *D.19256;
          D.19257 = mono_wsq_count (wsq);
          if (D.19257 != 0) goto <D.19258>; else goto <D.19259>;
          <D.19258>:
          need_one = 1;
          goto <D.18800>;
          <D.19259>:
        }
        i = i + 1;
        <D.18802>:
        wsqs.6 = wsqs;
        if (wsqs.6 != 0B) goto <D.19260>; else goto <D.18800>;
        <D.19260>:
        i.7 = (unsigned int) i;
        wsqs.6 = wsqs;
        D.19262 = wsqs.6->len;
        if (i.7 < D.19262) goto <D.18801>; else goto <D.18800>;
        <D.18800>:
        {
          int ret;

          ret = pthread_mutex_unlock (&wsqs_lock.mutex);
          if (ret != 0) goto <D.19263>; else goto <D.19264>;
          <D.19263>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.19264>:
          D.19265 = ret != 0;
          D.19266 = (long int) D.19265;
          D.19267 = __builtin_expect (D.19266, 0);
          if (D.19267 != 0) goto <D.19268>; else goto <D.19269>;
          <D.19268>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 810, "ret == 0");
          <D.19269>:
        }
        <D.19244>:
        <D.19241>:
        if (need_one != 0) goto <D.19270>; else goto <D.19271>;
        <D.19270>:
        threadpool_start_thread (tp);
        <D.19271>:
      }
      <D.18797>:
      i = i + 1;
      <D.18805>:
      if (i <= 1) goto <D.18804>; else goto <D.18806>;
      <D.18806>:
      <D.18795>:
      goto <D.18807>;
      <D.18794>:
    }
  finally
    {
      pools = {CLOBBER};
    }
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.19272;
  unsigned int exch.8;
  unsigned int comp.9;
  unsigned int D.19275;

  exch.8 = (unsigned int) exch;
  comp.9 = (unsigned int) comp;
  D.19275 = __sync_val_compare_and_swap_4 (dest, comp.9, exch.8);
  D.19272 = (gint32) D.19275;
  return D.19272;
}


threadpool_start_thread (struct ThreadPool * tp)
{
  guint32 iftmp.10;
  int D.19278;
  int D.19282;
  volatile gint * D.19283;
  int D.19284;
  void * D.19287;
  void (*<Tbd4>) (void *) D.19288;
  struct MonoDomain * D.19289;
  gboolean D.19290;
  int D.19291;
  int D.19293;
  gint n;
  guint32 stack_size;

  D.19278 = tp->is_io;
  if (D.19278 == 0) goto <D.19279>; else goto <D.19280>;
  <D.19279>:
  iftmp.10 = 0;
  goto <D.19281>;
  <D.19280>:
  iftmp.10 = 262144;
  <D.19281>:
  stack_size = iftmp.10;
  goto <D.18864>;
  <D.18863>:
  D.19282 = n + 1;
  D.19283 = &tp->nthreads;
  D.19284 = InterlockedCompareExchange (D.19283, D.19282, n);
  if (D.19284 == n) goto <D.19285>; else goto <D.19286>;
  <D.19285>:
  D.19287 = tp->pc_nthreads;
  mono_perfcounter_update_value (D.19287, 1, 1);
  D.19288 = tp->async_invoke;
  D.19289 = mono_get_root_domain ();
  mono_thread_create_internal (D.19289, D.19288, tp, 1, 0, stack_size);
  D.19290 = 1;
  return D.19290;
  <D.19286>:
  <D.18864>:
  D.19291 = mono_runtime_is_shutting_down ();
  if (D.19291 == 0) goto <D.19292>; else goto <D.18865>;
  <D.19292>:
  n = tp->nthreads;
  D.19293 = tp->max_threads;
  if (n < D.19293) goto <D.18863>; else goto <D.18865>;
  <D.18865>:
  D.19290 = 0;
  return D.19290;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.19295;
  unsigned int D.19296;

  D.19296 = __sync_add_and_fetch_4 (val, 1);
  D.19295 = (gint32) D.19296;
  return D.19295;
}


threadpool_jobs_inc (struct MonoObject * obj)
{
  struct MonoVTable * D.19300;
  struct MonoDomain * D.19301;
  volatile int * D.19302;

  if (obj != 0B) goto <D.19298>; else goto <D.19299>;
  <D.19298>:
  D.19300 = obj->vtable;
  D.19301 = D.19300->domain;
  D.19302 = &D.19301->threadpool_jobs;
  InterlockedIncrement (D.19302);
  <D.19299>:
}


pulse_on_new_job (struct ThreadPool * tp)
{
  int D.19303;
  union MonoSemType * D.19306;

  D.19303 = tp->waiting;
  if (D.19303 != 0) goto <D.19304>; else goto <D.19305>;
  <D.19304>:
  D.19306 = &tp->new_job;
  mono_sem_post (D.19306);
  <D.19305>:
}


mono_thread_pool_init_tls ()
{
  mono_wsq_init ();
}


mono_thread_pool_init ()
{
  int tp_inited.11;
  int tp_inited.12;
  int D.19315;
  const gchar * D.19318;
  const gchar * D.19321;
  int D.19324;
  int D.19325;
  int D.19326;
  int D.19327;
  int D.19328;
  struct MonoImage * D.19329;
  struct MonoClass * async_call_klass.13;
  struct MonoClass * async_call_klass.14;
  _Bool D.19332;
  long int D.19333;
  long int D.19334;
  unsigned int D.19337;
  struct GPtrArray * wsqs.15;
  void * D.19339;
  void * D.19340;
  _Bool D.19341;
  long int D.19342;
  long int D.19343;
  void * D.19346;
  void * D.19347;
  _Bool D.19348;
  long int D.19349;
  long int D.19350;
  void * D.19353;
  void * D.19354;
  _Bool D.19355;
  long int D.19356;
  long int D.19357;
  void * D.19360;
  void * D.19361;
  _Bool D.19362;
  long int D.19363;
  long int D.19364;
  gint threads_per_cpu;
  gint thread_count;
  gint cpu_count;
  int result;

  threads_per_cpu = 1;
  cpu_count = mono_cpu_count ();
  tp_inited.11 = tp_inited;
  if (tp_inited.11 == 2) goto <D.19308>; else goto <D.19309>;
  <D.19308>:
  return;
  <D.19309>:
  result = InterlockedCompareExchange (&tp_inited, 1, 0);
  if (result == 1) goto <D.19310>; else goto <D.19311>;
  <D.19310>:
  <D.18818>:
  SleepEx (1, 0);
  tp_inited.12 = tp_inited;
  if (tp_inited.12 == 2) goto <D.19313>; else goto <D.19314>;
  <D.19313>:
  return;
  <D.19314>:
  goto <D.18818>;
  <D.19311>:
  D.19315 = mono_gc_is_moving ();
  if (D.19315 == 0) goto <D.19316>; else goto <D.19317>;
  <D.19316>:
  mono_gc_register_root (&socket_io_data.sock_to_state, 8, 0B);
  <D.19317>:
  InitializeCriticalSection (&socket_io_data.io_lock);
  D.19318 = monoeg_g_getenv ("MONO_THREADS_PER_CPU");
  if (D.19318 != 0B) goto <D.19319>; else goto <D.19320>;
  <D.19319>:
  D.19321 = monoeg_g_getenv ("MONO_THREADS_PER_CPU");
  threads_per_cpu = atoi (D.19321);
  if (threads_per_cpu <= 0) goto <D.19322>; else goto <D.19323>;
  <D.19322>:
  threads_per_cpu = 1;
  <D.19323>:
  <D.19320>:
  D.19324 = cpu_count * 100;
  D.19325 = cpu_count * threads_per_cpu;
  thread_count = MIN_EXPR <D.19324, D.19325>;
  D.19324 = cpu_count * 100;
  D.19326 = MAX_EXPR <D.19324, thread_count>;
  threadpool_init (&async_tp, thread_count, D.19326, async_invoke_thread);
  D.19327 = cpu_count * 4;
  D.19328 = cpu_count * 2;
  threadpool_init (&async_io_tp, D.19328, D.19327, async_invoke_thread);
  async_io_tp.is_io = 1;
  D.19329 = mono_defaults.corlib;
  async_call_klass.13 = mono_class_from_name (D.19329, "System", "MonoAsyncCall");
  async_call_klass = async_call_klass.13;
  async_call_klass.14 = async_call_klass;
  D.19332 = async_call_klass.14 == 0B;
  D.19333 = (long int) D.19332;
  D.19334 = __builtin_expect (D.19333, 0);
  if (D.19334 != 0) goto <D.19335>; else goto <D.19336>;
  <D.19335>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 858, "async_call_klass");
  <D.19336>:
  InitializeCriticalSection (&wsqs_lock);
  D.19324 = cpu_count * 100;
  D.19326 = MAX_EXPR <D.19324, thread_count>;
  D.19337 = (unsigned int) D.19326;
  wsqs.15 = monoeg_g_ptr_array_sized_new (D.19337);
  wsqs = wsqs.15;
  D.19339 = init_perf_counter ("Mono Threadpool", "Work Items Added");
  async_tp.pc_nitems = D.19339;
  D.19340 = async_tp.pc_nitems;
  D.19341 = D.19340 == 0B;
  D.19342 = (long int) D.19341;
  D.19343 = __builtin_expect (D.19342, 0);
  if (D.19343 != 0) goto <D.19344>; else goto <D.19345>;
  <D.19344>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 865, "async_tp.pc_nitems");
  <D.19345>:
  D.19346 = init_perf_counter ("Mono Threadpool", "IO Work Items Added");
  async_io_tp.pc_nitems = D.19346;
  D.19347 = async_io_tp.pc_nitems;
  D.19348 = D.19347 == 0B;
  D.19349 = (long int) D.19348;
  D.19350 = __builtin_expect (D.19349, 0);
  if (D.19350 != 0) goto <D.19351>; else goto <D.19352>;
  <D.19351>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 868, "async_io_tp.pc_nitems");
  <D.19352>:
  D.19353 = init_perf_counter ("Mono Threadpool", "# of Threads");
  async_tp.pc_nthreads = D.19353;
  D.19354 = async_tp.pc_nthreads;
  D.19355 = D.19354 == 0B;
  D.19356 = (long int) D.19355;
  D.19357 = __builtin_expect (D.19356, 0);
  if (D.19357 != 0) goto <D.19358>; else goto <D.19359>;
  <D.19358>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 871, "async_tp.pc_nthreads");
  <D.19359>:
  D.19360 = init_perf_counter ("Mono Threadpool", "# of IO Threads");
  async_io_tp.pc_nthreads = D.19360;
  D.19361 = async_io_tp.pc_nthreads;
  D.19362 = D.19361 == 0B;
  D.19363 = (long int) D.19362;
  D.19364 = __builtin_expect (D.19363, 0);
  if (D.19364 != 0) goto <D.19365>; else goto <D.19366>;
  <D.19365>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 874, "async_io_tp.pc_nthreads");
  <D.19366>:
  tp_inited = 2;
}


async_invoke_thread (void * data)
{
  int D.19368;
  void (*<Tbd4>) (void *) tp_start_func.16;
  void * tp_hooks_user_data.17;
  volatile gint * D.19377;
  struct MonoVTable * D.19378;
  void * data.18;
  struct MonoVTable * D.19380;
  int D.19381;
  _Bool D.19382;
  int D.19385;
  gint * D.19386;
  int D.19387;
  int D.19388;
  int D.19389;
  struct MonoArray * D.19390;
  void * D.19391;
  long int D.19392;
  unsigned int D.19393;
  int D.19394;
  int D.19395;
  _Bool D.19397;
  long int D.19398;
  long int D.19399;
  int D.19405;
  int D.19407;
  volatile gint * D.19408;
  int D.19409;
  volatile gint * D.19412;
  int D.19413;
  void (*<Tbd4>) (void *) tp_item_begin_func.19;
  void * tp_item_user_data.20;
  long int D.19422;
  void (*<Tbd4>) (void *) tp_item_end_func.21;
  unsigned char D.19434;
  struct MonoDelegate * D.19437;
  struct MonoDomain * D.19440;
  volatile gint * D.19441;
  int D.19447;
  volatile gint * D.19448;
  volatile gint * D.19451;
  int D.19452;
  struct MonoCQ * D.19454;
  int D.19455;
  union MonoSemType * D.19457;
  volatile gint * D.19458;
  int D.19459;
  int D.19467;
  volatile gint * D.19474;
  int D.19479;
  int D.19484;
  volatile gint * D.19485;
  int D.19486;
  void * D.19487;
  void (*<Tbd4>) (void *) tp_finish_func.22;
  struct MonoDomain * domain;
  struct MonoWSQ * wsq;
  struct ThreadPool * tp;
  gboolean must_die;

  tp = data;
  wsq = 0B;
  D.19368 = tp->is_io;
  if (D.19368 == 0) goto <D.19369>; else goto <D.19370>;
  <D.19369>:
  wsq = add_wsq ();
  <D.19370>:
  set_tp_thread_info (tp);
  tp_start_func.16 = tp_start_func;
  if (tp_start_func.16 != 0B) goto <D.19372>; else goto <D.19373>;
  <D.19372>:
  tp_start_func.16 = tp_start_func;
  tp_hooks_user_data.17 = tp_hooks_user_data;
  tp_start_func.16 (tp_hooks_user_data.17);
  <D.19373>:
  data = 0B;
  <D.19043>:
  {
    struct MonoAsyncResult * ar;
    struct MonoClass * klass;
    gboolean is_io_task;
    gboolean is_socket;
    int n_naps;

    n_naps = 0;
    is_io_task = 0;
    ar = data;
    if (ar != 0B) goto <D.19375>; else goto <D.19376>;
    <D.19375>:
    D.19377 = &tp->busy_threads;
    InterlockedIncrement (D.19377);
    D.19378 = MEM[(struct MonoObject *)ar].vtable;
    domain = D.19378->domain;
    data.18 = data;
    D.19380 = MEM[(struct MonoObject *)data.18].vtable;
    klass = D.19380->klass;
    D.19381 = is_corlib_asyncresult (domain, klass);
    D.19382 = D.19381 == 0;
    is_io_task = (gboolean) D.19382;
    is_socket = 0;
    if (is_io_task != 0) goto <D.19383>; else goto <D.19384>;
    <D.19383>:
    {
      struct MonoSocketAsyncResult * state;

      state = data;
      is_socket = is_socketasyncresult (domain, klass);
      ar = state->ares;
      D.19385 = state->operation;
      switch (D.19385) <default: <D.19396>, case 2: <D.19025>, case 4: <D.19027>>
      <D.19025>:
      D.19386 = &state->error;
      D.19387 = state->socket_flags;
      D.19388 = state->size;
      D.19389 = state->offset;
      D.19390 = state->buffer;
      D.19391 = state->handle;
      D.19392 = (long int) D.19391;
      D.19393 = (unsigned int) D.19392;
      D.19394 = ves_icall_System_Net_Sockets_Socket_Receive_internal (D.19393, D.19390, D.19389, D.19388, D.19387, D.19386);
      state->total = D.19394;
      goto <D.19026>;
      <D.19027>:
      D.19386 = &state->error;
      D.19387 = state->socket_flags;
      D.19388 = state->size;
      D.19389 = state->offset;
      D.19390 = state->buffer;
      D.19391 = state->handle;
      D.19392 = (long int) D.19391;
      D.19393 = (unsigned int) D.19392;
      D.19395 = ves_icall_System_Net_Sockets_Socket_Send_internal (D.19393, D.19390, D.19389, D.19388, D.19387, D.19386);
      state->total = D.19395;
      goto <D.19026>;
      <D.19396>:
      <D.19026>:
    }
    <D.19384>:
    D.19397 = domain == 0B;
    D.19398 = (long int) D.19397;
    D.19399 = __builtin_expect (D.19398, 0);
    if (D.19399 != 0) goto <D.19400>; else goto <D.19401>;
    <D.19400>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1492, "domain");
    <D.19401>:
    D.19405 = mono_domain_is_unloading (domain);
    if (D.19405 != 0) goto <D.19402>; else goto <D.19406>;
    <D.19406>:
    D.19407 = mono_runtime_is_shutting_down ();
    if (D.19407 != 0) goto <D.19402>; else goto <D.19403>;
    <D.19402>:
    threadpool_jobs_dec (ar);
    data = 0B;
    ar = 0B;
    D.19408 = &tp->busy_threads;
    InterlockedDecrement (D.19408);
    goto <D.19404>;
    <D.19403>:
    mono_thread_push_appdomain_ref (domain);
    D.19409 = threadpool_jobs_dec (ar);
    if (D.19409 != 0) goto <D.19410>; else goto <D.19411>;
    <D.19410>:
    data = 0B;
    ar = 0B;
    mono_thread_pop_appdomain_ref ();
    D.19412 = &tp->busy_threads;
    InterlockedDecrement (D.19412);
    // predicted unlikely by continue predictor.
    goto <D.19028>;
    <D.19411>:
    D.19413 = mono_domain_set (domain, 0);
    if (D.19413 != 0) goto <D.19414>; else goto <D.19415>;
    <D.19414>:
    {
      struct MonoObject * exc;

      tp_item_begin_func.19 = tp_item_begin_func;
      if (tp_item_begin_func.19 != 0B) goto <D.19417>; else goto <D.19418>;
      <D.19417>:
      tp_item_begin_func.19 = tp_item_begin_func;
      tp_item_user_data.20 = tp_item_user_data;
      tp_item_begin_func.19 (tp_item_user_data.20);
      <D.19418>:
      if (is_io_task == 0) goto <D.19420>; else goto <D.19421>;
      <D.19420>:
      D.19422 = ar->add_time;
      if (D.19422 > 0) goto <D.19423>; else goto <D.19424>;
      <D.19423>:
      D.19422 = ar->add_time;
      process_idle_times (tp, D.19422);
      <D.19424>:
      <D.19421>:
      exc = mono_async_invoke (tp, ar);
      tp_item_end_func.21 = tp_item_end_func;
      if (tp_item_end_func.21 != 0B) goto <D.19426>; else goto <D.19427>;
      <D.19426>:
      tp_item_end_func.21 = tp_item_end_func;
      tp_item_user_data.20 = tp_item_user_data;
      tp_item_end_func.21 (tp_item_user_data.20);
      <D.19427>:
      if (exc != 0B) goto <D.19428>; else goto <D.19429>;
      <D.19428>:
      mono_internal_thread_unhandled_exception (exc);
      <D.19429>:
      if (is_socket != 0) goto <D.19430>; else goto <D.19431>;
      <D.19430>:
      D.19368 = tp->is_io;
      if (D.19368 != 0) goto <D.19432>; else goto <D.19433>;
      <D.19432>:
      {
        struct MonoSocketAsyncResult * state;

        state = data;
        D.19434 = state->completed;
        if (D.19434 != 0) goto <D.19435>; else goto <D.19436>;
        <D.19435>:
        D.19437 = state->callback;
        if (D.19437 != 0B) goto <D.19438>; else goto <D.19439>;
        <D.19438>:
        {
          struct MonoAsyncResult * cb_ares;

          D.19437 = state->callback;
          cb_ares = create_simple_asyncresult (D.19437, state);
          icall_append_job (cb_ares);
        }
        <D.19439>:
        <D.19436>:
      }
      <D.19433>:
      <D.19431>:
      D.19440 = mono_get_root_domain ();
      mono_domain_set (D.19440, 1);
    }
    <D.19415>:
    mono_thread_pop_appdomain_ref ();
    D.19441 = &tp->busy_threads;
    InterlockedDecrement (D.19441);
    clear_thread_state ();
    <D.19404>:
    <D.19376>:
    ar = 0B;
    data = 0B;
    must_die = should_i_die (tp);
    if (must_die == 0) goto <D.19444>; else goto <D.19445>;
    <D.19444>:
    D.19368 = tp->is_io;
    if (D.19368 != 0) goto <D.19442>; else goto <D.19446>;
    <D.19446>:
    D.19447 = mono_wsq_local_pop (&data);
    if (D.19447 == 0) goto <D.19442>; else goto <D.19443>;
    <D.19442>:
    dequeue_or_steal (tp, &data, wsq);
    <D.19443>:
    <D.19445>:
    n_naps = 0;
    goto <D.19038>;
    <D.19037>:
    {
      gboolean res;

      D.19448 = &tp->waiting;
      InterlockedIncrement (D.19448);
      dequeue_or_steal (tp, &data, wsq);
      data.18 = data;
      if (data.18 != 0B) goto <D.19449>; else goto <D.19450>;
      <D.19449>:
      D.19451 = &tp->waiting;
      InterlockedDecrement (D.19451);
      goto <D.19033>;
      <D.19450>:
      mono_gc_set_skip_thread (1);
      goto <D.19036>;
      <D.19035>:
      D.19452 = mono_runtime_is_shutting_down ();
      if (D.19452 != 0) goto <D.19034>; else goto <D.19453>;
      <D.19453>:
      check_for_interruption_critical ();
      <D.19036>:
      D.19454 = tp->queue;
      D.19455 = mono_cq_count (D.19454);
      if (D.19455 == 0) goto <D.19456>; else goto <D.19034>;
      <D.19456>:
      D.19457 = &tp->new_job;
      res = mono_sem_timedwait (D.19457, 2000, 1);
      if (res == -1) goto <D.19035>; else goto <D.19034>;
      <D.19034>:
      D.19458 = &tp->waiting;
      InterlockedDecrement (D.19458);
      mono_gc_set_skip_thread (0);
      D.19459 = mono_runtime_is_shutting_down ();
      if (D.19459 != 0) goto <D.19033>; else goto <D.19460>;
      <D.19460>:
      must_die = should_i_die (tp);
      dequeue_or_steal (tp, &data, wsq);
      n_naps = n_naps + 1;
    }
    <D.19038>:
    if (must_die == 0) goto <D.19461>; else goto <D.19033>;
    <D.19461>:
    data.18 = data;
    if (data.18 == 0B) goto <D.19462>; else goto <D.19033>;
    <D.19462>:
    if (n_naps <= 3) goto <D.19037>; else goto <D.19033>;
    <D.19033>:
    data.18 = data;
    if (data.18 == 0B) goto <D.19463>; else goto <D.19464>;
    <D.19463>:
    D.19368 = tp->is_io;
    if (D.19368 == 0) goto <D.19465>; else goto <D.19466>;
    <D.19465>:
    D.19467 = mono_runtime_is_shutting_down ();
    if (D.19467 == 0) goto <D.19468>; else goto <D.19469>;
    <D.19468>:
    mono_wsq_local_pop (&data);
    data.18 = data;
    if (data.18 != 0B) goto <D.19470>; else goto <D.19471>;
    <D.19470>:
    if (must_die != 0) goto <D.19472>; else goto <D.19473>;
    <D.19472>:
    D.19474 = &tp->destroy_thread;
    InterlockedCompareExchange (D.19474, 1, 0);
    pulse_on_new_job (tp);
    <D.19473>:
    <D.19471>:
    <D.19469>:
    <D.19466>:
    <D.19464>:
    data.18 = data;
    if (data.18 == 0B) goto <D.19475>; else goto <D.19476>;
    <D.19475>:
    {
      gint nt;
      gboolean down;

      <D.19042>:
      nt = tp->nthreads;
      down = mono_runtime_is_shutting_down ();
      if (down == 0) goto <D.19477>; else goto <D.19478>;
      <D.19477>:
      D.19479 = tp->min_threads;
      if (D.19479 >= nt) goto <D.19041>; else goto <D.19480>;
      <D.19480>:
      <D.19478>:
      if (down != 0) goto <D.19481>; else goto <D.19483>;
      <D.19483>:
      D.19484 = nt + -1;
      D.19485 = &tp->nthreads;
      D.19486 = InterlockedCompareExchange (D.19485, D.19484, nt);
      if (D.19486 == nt) goto <D.19481>; else goto <D.19482>;
      <D.19481>:
      D.19487 = tp->pc_nthreads;
      mono_perfcounter_update_value (D.19487, 1, -1);
      D.19368 = tp->is_io;
      if (D.19368 == 0) goto <D.19488>; else goto <D.19489>;
      <D.19488>:
      remove_wsq (wsq);
      <D.19489>:
      fire_profiler_thread_end ();
      tp_finish_func.22 = tp_finish_func;
      if (tp_finish_func.22 != 0B) goto <D.19491>; else goto <D.19492>;
      <D.19491>:
      tp_finish_func.22 = tp_finish_func;
      tp_hooks_user_data.17 = tp_hooks_user_data;
      tp_finish_func.22 (tp_hooks_user_data.17);
      <D.19492>:
      return;
      <D.19482>:
      goto <D.19042>;
      <D.19041>:
    }
    <D.19476>:
  }
  <D.19028>:
  goto <D.19043>;
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "threadpool.c", 1616);
}


add_wsq ()
{
  _Bool D.19496;
  long int D.19497;
  long int D.19498;
  struct GPtrArray * wsqs.23;
  _Bool D.19506;
  long int D.19507;
  long int D.19508;
  struct MonoWSQ * D.19511;
  void * * D.19512;
  long unsigned int D.19513;
  long unsigned int D.19514;
  void * * D.19515;
  void * D.19516;
  _Bool D.19521;
  long int D.19522;
  long int D.19523;
  unsigned int i.24;
  unsigned int D.19527;
  _Bool D.19530;
  long int D.19531;
  long int D.19532;
  int i;
  struct MonoWSQ * wsq;

  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19494>; else goto <D.19495>;
    <D.19494>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19495>:
    D.19496 = ret != 0;
    D.19497 = (long int) D.19496;
    D.19498 = __builtin_expect (D.19497, 0);
    if (D.19498 != 0) goto <D.19499>; else goto <D.19500>;
    <D.19499>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1221, "ret == 0");
    <D.19500>:
  }
  wsq = mono_wsq_create ();
  wsqs.23 = wsqs;
  if (wsqs.23 == 0B) goto <D.19502>; else goto <D.19503>;
  <D.19502>:
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19504>; else goto <D.19505>;
    <D.19504>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19505>:
    D.19506 = ret != 0;
    D.19507 = (long int) D.19506;
    D.19508 = __builtin_expect (D.19507, 0);
    if (D.19508 != 0) goto <D.19509>; else goto <D.19510>;
    <D.19509>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1224, "ret == 0");
    <D.19510>:
  }
  D.19511 = 0B;
  return D.19511;
  <D.19503>:
  i = 0;
  goto <D.18943>;
  <D.18942>:
  wsqs.23 = wsqs;
  D.19512 = wsqs.23->pdata;
  D.19513 = (long unsigned int) i;
  D.19514 = D.19513 * 8;
  D.19515 = D.19512 + D.19514;
  D.19516 = *D.19515;
  if (D.19516 == 0B) goto <D.19517>; else goto <D.19518>;
  <D.19517>:
  wsqs.23 = wsqs;
  D.19512 = wsqs.23->pdata;
  D.19513 = (long unsigned int) i;
  D.19514 = D.19513 * 8;
  D.19515 = D.19512 + D.19514;
  *D.19515 = wsq;
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19519>; else goto <D.19520>;
    <D.19519>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19520>:
    D.19521 = ret != 0;
    D.19522 = (long int) D.19521;
    D.19523 = __builtin_expect (D.19522, 0);
    if (D.19523 != 0) goto <D.19524>; else goto <D.19525>;
    <D.19524>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1230, "ret == 0");
    <D.19525>:
  }
  D.19511 = wsq;
  return D.19511;
  <D.19518>:
  i = i + 1;
  <D.18943>:
  i.24 = (unsigned int) i;
  wsqs.23 = wsqs;
  D.19527 = wsqs.23->len;
  if (i.24 < D.19527) goto <D.18942>; else goto <D.18944>;
  <D.18944>:
  wsqs.23 = wsqs;
  monoeg_g_ptr_array_add (wsqs.23, wsq);
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19528>; else goto <D.19529>;
    <D.19528>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19529>:
    D.19530 = ret != 0;
    D.19531 = (long int) D.19530;
    D.19532 = __builtin_expect (D.19531, 0);
    if (D.19532 != 0) goto <D.19533>; else goto <D.19534>;
    <D.19533>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1235, "ret == 0");
    <D.19534>:
  }
  D.19511 = wsq;
  return D.19511;
}


set_tp_thread_info (struct ThreadPool * tp)
{
  long unsigned int D.19536;
  const gchar * iftmp.25;
  int D.19538;
  struct MonoDomain * D.19542;
  struct MonoString * D.19543;
  const gchar * name;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.19536 = thread->tid;
  mono_profiler_thread_start (D.19536);
  D.19538 = tp->is_io;
  if (D.19538 != 0) goto <D.19539>; else goto <D.19540>;
  <D.19539>:
  iftmp.25 = "IO Threadpool worker";
  goto <D.19541>;
  <D.19540>:
  iftmp.25 = "Threadpool worker";
  <D.19541>:
  name = iftmp.25;
  D.19542 = mono_domain_get ();
  D.19543 = mono_string_new (D.19542, name);
  mono_thread_set_name_internal (thread, D.19543, 0);
}


is_corlib_asyncresult (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.19544;
  gboolean D.19547;
  _Bool D.19548;
  int D.19549;
  int D.18540;
  int iftmp.26;
  int D.18536;
  const char[12] * D.19555;
  unsigned char D.19556;
  int D.19557;
  unsigned char D.19558;
  int D.19559;
  _Bool D.19560;
  _Bool D.19561;
  _Bool D.19562;
  const unsigned char * D.19565;
  unsigned char D.19566;
  int D.19567;
  const unsigned char * D.19568;
  unsigned char D.19569;
  int D.19570;
  _Bool D.19571;
  _Bool D.19572;
  const unsigned char * D.19575;
  unsigned char D.19576;
  int D.19577;
  const unsigned char * D.19578;
  unsigned char D.19579;
  int D.19580;
  _Bool D.19581;
  _Bool D.19582;
  const unsigned char * D.19585;
  unsigned char D.19586;
  int D.19587;
  const unsigned char * D.19588;
  unsigned char D.19589;
  int D.19590;
  const char * D.19592;
  int D.18549;
  int iftmp.27;
  int D.18545;
  const char[34] * D.19598;
  unsigned char D.19599;
  int D.19600;
  unsigned char D.19601;
  int D.19602;
  _Bool D.19603;
  _Bool D.19604;
  _Bool D.19605;
  const unsigned char * D.19608;
  unsigned char D.19609;
  int D.19610;
  const unsigned char * D.19611;
  unsigned char D.19612;
  int D.19613;
  _Bool D.19614;
  _Bool D.19615;
  const unsigned char * D.19618;
  unsigned char D.19619;
  int D.19620;
  const unsigned char * D.19621;
  unsigned char D.19622;
  int D.19623;
  _Bool D.19624;
  _Bool D.19625;
  const unsigned char * D.19628;
  unsigned char D.19629;
  int D.19630;
  const unsigned char * D.19631;
  unsigned char D.19632;
  int D.19633;
  const char * D.19635;

  D.19544 = domain->corlib_asyncresult_class;
  if (D.19544 != 0B) goto <D.19545>; else goto <D.19546>;
  <D.19545>:
  D.19544 = domain->corlib_asyncresult_class;
  D.19548 = D.19544 == klass;
  D.19547 = (gboolean) D.19548;
  return D.19547;
  <D.19546>:
  D.19549 = is_corlib_type (domain, klass);
  if (D.19549 != 0) goto <D.19550>; else goto <D.19551>;
  <D.19550>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 11;
    if (__s1_len <= 3) goto <D.19553>; else goto <D.19554>;
    <D.19553>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.19555 = "AsyncResult";
      D.19556 = MEM[(const unsigned char *)D.19555];
      D.19557 = (int) D.19556;
      D.19558 = *__s2;
      D.19559 = (int) D.19558;
      __result = D.19557 - D.19559;
      {
        D.19560 = __s1_len != 0;
        D.19561 = __result == 0;
        D.19562 = D.19560 & D.19561;
        if (D.19562 != 0) goto <D.19563>; else goto <D.19564>;
        <D.19563>:
        D.19565 = &MEM[(void *)"AsyncResult" + 1B];
        D.19566 = *D.19565;
        D.19567 = (int) D.19566;
        D.19568 = __s2 + 1;
        D.19569 = *D.19568;
        D.19570 = (int) D.19569;
        __result = D.19567 - D.19570;
        D.19571 = __s1_len > 1;
        D.19561 = __result == 0;
        D.19572 = D.19571 & D.19561;
        if (D.19572 != 0) goto <D.19573>; else goto <D.19574>;
        <D.19573>:
        D.19575 = &MEM[(void *)"AsyncResult" + 2B];
        D.19576 = *D.19575;
        D.19577 = (int) D.19576;
        D.19578 = __s2 + 2;
        D.19579 = *D.19578;
        D.19580 = (int) D.19579;
        __result = D.19577 - D.19580;
        D.19581 = __s1_len > 2;
        D.19561 = __result == 0;
        D.19582 = D.19581 & D.19561;
        if (D.19582 != 0) goto <D.19583>; else goto <D.19584>;
        <D.19583>:
        D.19585 = &MEM[(void *)"AsyncResult" + 3B];
        D.19586 = *D.19585;
        D.19587 = (int) D.19586;
        D.19588 = __s2 + 3;
        D.19589 = *D.19588;
        D.19590 = (int) D.19589;
        __result = D.19587 - D.19590;
        <D.19584>:
        <D.19574>:
        <D.19564>:
      }
      D.18536 = __result;
    }
    iftmp.26 = D.18536;
    goto <D.19591>;
    <D.19554>:
    D.19592 = klass->name;
    iftmp.26 = __builtin_strcmp ("AsyncResult", D.19592);
    <D.19591>:
    D.18540 = iftmp.26;
  }
  if (D.18540 == 0) goto <D.19593>; else goto <D.19594>;
  <D.19593>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 33;
    if (__s1_len <= 3) goto <D.19596>; else goto <D.19597>;
    <D.19596>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name_space;
      D.19598 = "System.Runtime.Remoting.Messaging";
      D.19599 = MEM[(const unsigned char *)D.19598];
      D.19600 = (int) D.19599;
      D.19601 = *__s2;
      D.19602 = (int) D.19601;
      __result = D.19600 - D.19602;
      {
        D.19603 = __s1_len != 0;
        D.19604 = __result == 0;
        D.19605 = D.19603 & D.19604;
        if (D.19605 != 0) goto <D.19606>; else goto <D.19607>;
        <D.19606>:
        D.19608 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 1B];
        D.19609 = *D.19608;
        D.19610 = (int) D.19609;
        D.19611 = __s2 + 1;
        D.19612 = *D.19611;
        D.19613 = (int) D.19612;
        __result = D.19610 - D.19613;
        D.19614 = __s1_len > 1;
        D.19604 = __result == 0;
        D.19615 = D.19614 & D.19604;
        if (D.19615 != 0) goto <D.19616>; else goto <D.19617>;
        <D.19616>:
        D.19618 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 2B];
        D.19619 = *D.19618;
        D.19620 = (int) D.19619;
        D.19621 = __s2 + 2;
        D.19622 = *D.19621;
        D.19623 = (int) D.19622;
        __result = D.19620 - D.19623;
        D.19624 = __s1_len > 2;
        D.19604 = __result == 0;
        D.19625 = D.19624 & D.19604;
        if (D.19625 != 0) goto <D.19626>; else goto <D.19627>;
        <D.19626>:
        D.19628 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 3B];
        D.19629 = *D.19628;
        D.19630 = (int) D.19629;
        D.19631 = __s2 + 3;
        D.19632 = *D.19631;
        D.19633 = (int) D.19632;
        __result = D.19630 - D.19633;
        <D.19627>:
        <D.19617>:
        <D.19607>:
      }
      D.18545 = __result;
    }
    iftmp.27 = D.18545;
    goto <D.19634>;
    <D.19597>:
    D.19635 = klass->name_space;
    iftmp.27 = __builtin_strcmp ("System.Runtime.Remoting.Messaging", D.19635);
    <D.19634>:
    D.18549 = iftmp.27;
  }
  if (D.18549 == 0) goto <D.19636>; else goto <D.19637>;
  <D.19636>:
  domain->corlib_asyncresult_class = klass;
  D.19547 = 1;
  return D.19547;
  <D.19637>:
  <D.19594>:
  <D.19551>:
  D.19547 = 0;
  return D.19547;
}


is_corlib_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.19639;
  struct MonoImage * D.19640;
  struct MonoImage * D.19641;
  _Bool D.19642;

  D.19640 = klass->image;
  D.19641 = mono_defaults.corlib;
  D.19642 = D.19640 == D.19641;
  D.19639 = (gboolean) D.19642;
  return D.19639;
}


is_socketasyncresult (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.19644;
  int iftmp.28;
  struct MonoClass * D.19648;
  int D.19650;
  int D.18584;
  int iftmp.29;
  int D.18583;
  const char[18] * D.19655;
  unsigned char D.19656;
  int D.19657;
  unsigned char D.19658;
  int D.19659;
  _Bool D.19660;
  _Bool D.19661;
  _Bool D.19662;
  const unsigned char * D.19665;
  unsigned char D.19666;
  int D.19667;
  const unsigned char * D.19668;
  unsigned char D.19669;
  int D.19670;
  _Bool D.19671;
  _Bool D.19672;
  const unsigned char * D.19675;
  unsigned char D.19676;
  int D.19677;
  const unsigned char * D.19678;
  unsigned char D.19679;
  int D.19680;
  _Bool D.19681;
  _Bool D.19682;
  const unsigned char * D.19685;
  unsigned char D.19686;
  int D.19687;
  const unsigned char * D.19688;
  unsigned char D.19689;
  int D.19690;
  const char * D.19692;

  D.19648 = klass->nested_in;
  if (D.19648 != 0B) goto <D.19649>; else goto <D.19646>;
  <D.19649>:
  D.19648 = klass->nested_in;
  D.19650 = is_socket (domain, D.19648);
  if (D.19650 != 0) goto <D.19651>; else goto <D.19646>;
  <D.19651>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 17;
    if (__s2_len <= 3) goto <D.19653>; else goto <D.19654>;
    <D.19653>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.19655 = "SocketAsyncResult";
      D.19656 = MEM[(const unsigned char *)D.19655];
      D.19657 = (int) D.19656;
      D.19658 = *__s2;
      D.19659 = (int) D.19658;
      __result = D.19657 - D.19659;
      {
        D.19660 = __s2_len != 0;
        D.19661 = __result == 0;
        D.19662 = D.19660 & D.19661;
        if (D.19662 != 0) goto <D.19663>; else goto <D.19664>;
        <D.19663>:
        D.19665 = &MEM[(void *)"SocketAsyncResult" + 1B];
        D.19666 = *D.19665;
        D.19667 = (int) D.19666;
        D.19668 = __s2 + 1;
        D.19669 = *D.19668;
        D.19670 = (int) D.19669;
        __result = D.19667 - D.19670;
        D.19671 = __s2_len > 1;
        D.19661 = __result == 0;
        D.19672 = D.19671 & D.19661;
        if (D.19672 != 0) goto <D.19673>; else goto <D.19674>;
        <D.19673>:
        D.19675 = &MEM[(void *)"SocketAsyncResult" + 2B];
        D.19676 = *D.19675;
        D.19677 = (int) D.19676;
        D.19678 = __s2 + 2;
        D.19679 = *D.19678;
        D.19680 = (int) D.19679;
        __result = D.19677 - D.19680;
        D.19681 = __s2_len > 2;
        D.19661 = __result == 0;
        D.19682 = D.19681 & D.19661;
        if (D.19682 != 0) goto <D.19683>; else goto <D.19684>;
        <D.19683>:
        D.19685 = &MEM[(void *)"SocketAsyncResult" + 3B];
        D.19686 = *D.19685;
        D.19687 = (int) D.19686;
        D.19688 = __s2 + 3;
        D.19689 = *D.19688;
        D.19690 = (int) D.19689;
        __result = D.19687 - D.19690;
        <D.19684>:
        <D.19674>:
        <D.19664>:
      }
      D.18583 = __result;
    }
    iftmp.29 = -D.18583;
    goto <D.19691>;
    <D.19654>:
    D.19692 = klass->name;
    iftmp.29 = __builtin_strcmp (D.19692, "SocketAsyncResult");
    <D.19691>:
    D.18584 = iftmp.29;
  }
  if (D.18584 == 0) goto <D.19693>; else goto <D.19646>;
  <D.19693>:
  iftmp.28 = 1;
  goto <D.19647>;
  <D.19646>:
  iftmp.28 = 0;
  <D.19647>:
  D.19644 = iftmp.28;
  return D.19644;
}


is_socket (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.19695;
  gboolean D.19698;
  _Bool D.19699;
  int D.19700;
  int D.18562;
  int iftmp.30;
  int D.18558;
  const char[7] * D.19706;
  unsigned char D.19707;
  int D.19708;
  unsigned char D.19709;
  int D.19710;
  _Bool D.19711;
  _Bool D.19712;
  _Bool D.19713;
  const unsigned char * D.19716;
  unsigned char D.19717;
  int D.19718;
  const unsigned char * D.19719;
  unsigned char D.19720;
  int D.19721;
  _Bool D.19722;
  _Bool D.19723;
  const unsigned char * D.19726;
  unsigned char D.19727;
  int D.19728;
  const unsigned char * D.19729;
  unsigned char D.19730;
  int D.19731;
  _Bool D.19732;
  _Bool D.19733;
  const unsigned char * D.19736;
  unsigned char D.19737;
  int D.19738;
  const unsigned char * D.19739;
  unsigned char D.19740;
  int D.19741;
  const char * D.19743;
  int D.18571;
  int iftmp.31;
  int D.18567;
  const char[19] * D.19749;
  unsigned char D.19750;
  int D.19751;
  unsigned char D.19752;
  int D.19753;
  _Bool D.19754;
  _Bool D.19755;
  _Bool D.19756;
  const unsigned char * D.19759;
  unsigned char D.19760;
  int D.19761;
  const unsigned char * D.19762;
  unsigned char D.19763;
  int D.19764;
  _Bool D.19765;
  _Bool D.19766;
  const unsigned char * D.19769;
  unsigned char D.19770;
  int D.19771;
  const unsigned char * D.19772;
  unsigned char D.19773;
  int D.19774;
  _Bool D.19775;
  _Bool D.19776;
  const unsigned char * D.19779;
  unsigned char D.19780;
  int D.19781;
  const unsigned char * D.19782;
  unsigned char D.19783;
  int D.19784;
  const char * D.19786;

  D.19695 = domain->socket_class;
  if (D.19695 != 0B) goto <D.19696>; else goto <D.19697>;
  <D.19696>:
  D.19695 = domain->socket_class;
  D.19699 = D.19695 == klass;
  D.19698 = (gboolean) D.19699;
  return D.19698;
  <D.19697>:
  D.19700 = is_socket_type (domain, klass);
  if (D.19700 != 0) goto <D.19701>; else goto <D.19702>;
  <D.19701>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 6;
    if (__s1_len <= 3) goto <D.19704>; else goto <D.19705>;
    <D.19704>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.19706 = "Socket";
      D.19707 = MEM[(const unsigned char *)D.19706];
      D.19708 = (int) D.19707;
      D.19709 = *__s2;
      D.19710 = (int) D.19709;
      __result = D.19708 - D.19710;
      {
        D.19711 = __s1_len != 0;
        D.19712 = __result == 0;
        D.19713 = D.19711 & D.19712;
        if (D.19713 != 0) goto <D.19714>; else goto <D.19715>;
        <D.19714>:
        D.19716 = &MEM[(void *)"Socket" + 1B];
        D.19717 = *D.19716;
        D.19718 = (int) D.19717;
        D.19719 = __s2 + 1;
        D.19720 = *D.19719;
        D.19721 = (int) D.19720;
        __result = D.19718 - D.19721;
        D.19722 = __s1_len > 1;
        D.19712 = __result == 0;
        D.19723 = D.19722 & D.19712;
        if (D.19723 != 0) goto <D.19724>; else goto <D.19725>;
        <D.19724>:
        D.19726 = &MEM[(void *)"Socket" + 2B];
        D.19727 = *D.19726;
        D.19728 = (int) D.19727;
        D.19729 = __s2 + 2;
        D.19730 = *D.19729;
        D.19731 = (int) D.19730;
        __result = D.19728 - D.19731;
        D.19732 = __s1_len > 2;
        D.19712 = __result == 0;
        D.19733 = D.19732 & D.19712;
        if (D.19733 != 0) goto <D.19734>; else goto <D.19735>;
        <D.19734>:
        D.19736 = &MEM[(void *)"Socket" + 3B];
        D.19737 = *D.19736;
        D.19738 = (int) D.19737;
        D.19739 = __s2 + 3;
        D.19740 = *D.19739;
        D.19741 = (int) D.19740;
        __result = D.19738 - D.19741;
        <D.19735>:
        <D.19725>:
        <D.19715>:
      }
      D.18558 = __result;
    }
    iftmp.30 = D.18558;
    goto <D.19742>;
    <D.19705>:
    D.19743 = klass->name;
    iftmp.30 = __builtin_strcmp ("Socket", D.19743);
    <D.19742>:
    D.18562 = iftmp.30;
  }
  if (D.18562 == 0) goto <D.19744>; else goto <D.19745>;
  <D.19744>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 18;
    if (__s1_len <= 3) goto <D.19747>; else goto <D.19748>;
    <D.19747>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name_space;
      D.19749 = "System.Net.Sockets";
      D.19750 = MEM[(const unsigned char *)D.19749];
      D.19751 = (int) D.19750;
      D.19752 = *__s2;
      D.19753 = (int) D.19752;
      __result = D.19751 - D.19753;
      {
        D.19754 = __s1_len != 0;
        D.19755 = __result == 0;
        D.19756 = D.19754 & D.19755;
        if (D.19756 != 0) goto <D.19757>; else goto <D.19758>;
        <D.19757>:
        D.19759 = &MEM[(void *)"System.Net.Sockets" + 1B];
        D.19760 = *D.19759;
        D.19761 = (int) D.19760;
        D.19762 = __s2 + 1;
        D.19763 = *D.19762;
        D.19764 = (int) D.19763;
        __result = D.19761 - D.19764;
        D.19765 = __s1_len > 1;
        D.19755 = __result == 0;
        D.19766 = D.19765 & D.19755;
        if (D.19766 != 0) goto <D.19767>; else goto <D.19768>;
        <D.19767>:
        D.19769 = &MEM[(void *)"System.Net.Sockets" + 2B];
        D.19770 = *D.19769;
        D.19771 = (int) D.19770;
        D.19772 = __s2 + 2;
        D.19773 = *D.19772;
        D.19774 = (int) D.19773;
        __result = D.19771 - D.19774;
        D.19775 = __s1_len > 2;
        D.19755 = __result == 0;
        D.19776 = D.19775 & D.19755;
        if (D.19776 != 0) goto <D.19777>; else goto <D.19778>;
        <D.19777>:
        D.19779 = &MEM[(void *)"System.Net.Sockets" + 3B];
        D.19780 = *D.19779;
        D.19781 = (int) D.19780;
        D.19782 = __s2 + 3;
        D.19783 = *D.19782;
        D.19784 = (int) D.19783;
        __result = D.19781 - D.19784;
        <D.19778>:
        <D.19768>:
        <D.19758>:
      }
      D.18567 = __result;
    }
    iftmp.31 = D.18567;
    goto <D.19785>;
    <D.19748>:
    D.19786 = klass->name_space;
    iftmp.31 = __builtin_strcmp ("System.Net.Sockets", D.19786);
    <D.19785>:
    D.18571 = iftmp.31;
  }
  if (D.18571 == 0) goto <D.19787>; else goto <D.19788>;
  <D.19787>:
  domain->socket_class = klass;
  D.19698 = 1;
  return D.19698;
  <D.19788>:
  <D.19745>:
  <D.19702>:
  D.19698 = 0;
  return D.19698;
}


is_socket_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.19790;

  D.19790 = is_system_type (domain, klass);
  return D.19790;
}


is_system_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoImage * D.19792;
  struct MonoImage * D.19795;
  gboolean D.19796;
  struct MonoImage * D.19797;
  _Bool D.19798;

  D.19792 = domain->system_image;
  if (D.19792 == 0B) goto <D.19793>; else goto <D.19794>;
  <D.19793>:
  D.19795 = mono_image_loaded ("System");
  domain->system_image = D.19795;
  <D.19794>:
  D.19797 = klass->image;
  D.19792 = domain->system_image;
  D.19798 = D.19797 == D.19792;
  D.19796 = (gboolean) D.19798;
  return D.19796;
}


threadpool_jobs_dec (struct MonoObject * obj)
{
  gboolean D.19802;
  struct MonoVTable * D.19803;
  volatile int * D.19804;
  void * D.19807;
  struct MonoDomain * domain;
  int remaining_jobs;

  if (obj == 0B) goto <D.19800>; else goto <D.19801>;
  <D.19800>:
  D.19802 = 0;
  return D.19802;
  <D.19801>:
  D.19803 = obj->vtable;
  domain = D.19803->domain;
  D.19804 = &domain->threadpool_jobs;
  remaining_jobs = InterlockedDecrement (D.19804);
  if (remaining_jobs == 0) goto <D.19805>; else goto <D.19806>;
  <D.19805>:
  D.19807 = domain->cleanup_semaphore;
  if (D.19807 != 0B) goto <D.19808>; else goto <D.19809>;
  <D.19808>:
  D.19807 = domain->cleanup_semaphore;
  ReleaseSemaphore (D.19807, 1, 0B);
  D.19802 = 1;
  return D.19802;
  <D.19809>:
  <D.19806>:
  D.19802 = 0;
  return D.19802;
}


process_idle_times (struct ThreadPool * tp, gint64 t)
{
  int D.19813;
  volatile gint * D.19815;
  int D.19816;
  int D.19818;
  long int D.19821;
  long int D.19822;
  int D.19823;
  int D.19824;
  long int D.19825;
  long int D.19829;
  long int D.19832;
  long int D.19833;
  long int D.19838;
  int D.19839;
  long int D.19840;
  long int D.19841;
  long int D.19845;
  long int D.19846;
  long int D.19847;
  long int D.19852;
  int D.19862;
  int D.19865;
  int D.19870;
  volatile gint * D.19873;
  int D.19874;
  gint64 ticks;
  gint64 avg;
  gboolean compute_avg;
  gint new_threads;
  gint64 per1;

  D.19813 = tp->ignore_times;
  if (D.19813 != 0) goto <D.19811>; else goto <D.19814>;
  <D.19814>:
  if (t <= 0) goto <D.19811>; else goto <D.19812>;
  <D.19811>:
  return;
  <D.19812>:
  compute_avg = 0;
  ticks = mono_100ns_ticks ();
  t = ticks - t;
  <D.18988>:
  D.19815 = &tp->sp_lock;
  D.19816 = InterlockedCompareExchange (D.19815, 1, 0);
  if (D.19816 == 0) goto <D.18987>; else goto <D.19817>;
  <D.19817>:
  goto <D.18988>;
  <D.18987>:
  D.19818 = tp->ignore_times;
  if (D.19818 != 0) goto <D.19819>; else goto <D.19820>;
  <D.19819>:
  tp->sp_lock = 0;
  return;
  <D.19820>:
  D.19821 = tp->time_sum;
  D.19822 = D.19821 + t;
  tp->time_sum = D.19822;
  D.19823 = tp->n_sum;
  D.19824 = D.19823 + 1;
  tp->n_sum = D.19824;
  D.19825 = tp->last_check;
  if (D.19825 == 0) goto <D.19826>; else goto <D.19827>;
  <D.19826>:
  tp->last_check = ticks;
  goto <D.19828>;
  <D.19827>:
  D.19829 = tp->last_check;
  if (D.19829 > 0) goto <D.19830>; else goto <D.19831>;
  <D.19830>:
  D.19832 = tp->last_check;
  D.19833 = ticks - D.19832;
  if (D.19833 > 5000000) goto <D.19834>; else goto <D.19835>;
  <D.19834>:
  tp->ignore_times = 1;
  compute_avg = 1;
  <D.19835>:
  <D.19831>:
  <D.19828>:
  tp->sp_lock = 0;
  if (compute_avg == 0) goto <D.19836>; else goto <D.19837>;
  <D.19836>:
  return;
  <D.19837>:
  tp->last_check = ticks;
  new_threads = 0;
  D.19838 = tp->time_sum;
  D.19839 = tp->n_sum;
  D.19840 = (long int) D.19839;
  avg = D.19838 / D.19840;
  D.19841 = tp->averages[1];
  if (D.19841 == 0) goto <D.19842>; else goto <D.19843>;
  <D.19842>:
  tp->averages[1] = avg;
  goto <D.19844>;
  <D.19843>:
  D.19841 = tp->averages[1];
  D.19845 = avg - D.19841;
  D.19846 = ABS_EXPR <D.19845>;
  D.19847 = D.19846 * 100;
  D.19841 = tp->averages[1];
  per1 = D.19847 / D.19841;
  if (per1 > 5) goto <D.19848>; else goto <D.19849>;
  <D.19848>:
  D.19841 = tp->averages[1];
  if (D.19841 < avg) goto <D.19850>; else goto <D.19851>;
  <D.19850>:
  D.19841 = tp->averages[1];
  D.19852 = tp->averages[0];
  if (D.19841 < D.19852) goto <D.19853>; else goto <D.19854>;
  <D.19853>:
  new_threads = -1;
  goto <D.19855>;
  <D.19854>:
  new_threads = 1;
  <D.19855>:
  goto <D.19856>;
  <D.19851>:
  D.19841 = tp->averages[1];
  if (D.19841 > avg) goto <D.19857>; else goto <D.19858>;
  <D.19857>:
  D.19841 = tp->averages[1];
  D.19852 = tp->averages[0];
  if (D.19841 < D.19852) goto <D.19859>; else goto <D.19860>;
  <D.19859>:
  new_threads = 1;
  <D.19860>:
  <D.19858>:
  <D.19856>:
  goto <D.19861>;
  <D.19849>:
  {
    int min;
    int n;

    min = tp->min_threads;
    n = tp->nthreads;
    D.19862 = n - min;
    if (D.19862 < min) goto <D.19863>; else goto <D.19864>;
    <D.19863>:
    D.19865 = tp->busy_threads;
    if (D.19865 == n) goto <D.19866>; else goto <D.19867>;
    <D.19866>:
    new_threads = 1;
    <D.19867>:
    <D.19864>:
  }
  <D.19861>:
  <D.19844>:
  tp->time_sum = 0;
  tp->n_sum = 0;
  D.19841 = tp->averages[1];
  tp->averages[0] = D.19841;
  tp->averages[1] = avg;
  tp->ignore_times = 0;
  if (new_threads == -1) goto <D.19868>; else goto <D.19869>;
  <D.19868>:
  D.19870 = tp->destroy_thread;
  if (D.19870 == 0) goto <D.19871>; else goto <D.19872>;
  <D.19871>:
  D.19873 = &tp->destroy_thread;
  D.19874 = InterlockedCompareExchange (D.19873, 1, 0);
  if (D.19874 == 0) goto <D.19875>; else goto <D.19876>;
  <D.19875>:
  pulse_on_new_job (tp);
  <D.19876>:
  <D.19872>:
  <D.19869>:
}


mono_async_invoke (struct ThreadPool * tp, struct MonoAsyncResult * ares)
{
  struct MonoAsyncResult * ares.32;
  struct MonoObject * D.19879;
  struct MonoObject * D.19882;
  struct MonoObject * * D.19883;
  struct MonoObject * pa.33;
  struct MonoObject * D.19888;
  struct MonoMethod * D.19889;
  struct MonoMethodMessage * D.19891;
  struct MonoObject * * D.19892;
  struct MonoObject * exc.34;
  struct MonoObject * * D.19894;
  struct MonoArray * out_args.35;
  struct MonoArray * * D.19896;
  struct MonoObject * D.19897;
  struct MonoMethod * D.19905;
  struct MonoDelegate * D.19907;
  struct MonoObject * cb_exc.36;
  struct MonoObject * D.19909;
  struct MonoObject * D.19912;
  struct ASyncCall * ac;
  struct MonoObject * res;
  struct MonoObject * exc;
  struct MonoArray * out_args;
  void * wait_event;
  struct MonoInternalThread * thread;

  try
    {
      ares.32 = ares;
      ac = ares.32->object_data;
      exc = 0B;
      out_args = 0B;
      wait_event = 0B;
      thread = mono_thread_internal_current ();
      ares.32 = ares;
      D.19879 = ares.32->execution_context;
      if (D.19879 != 0B) goto <D.19880>; else goto <D.19881>;
      <D.19880>:
      D.19882 = mono_thread_get_execution_context ();
      ares.32 = ares;
      D.19883 = &ares.32->original_context;
      ares.32 = ares;
      mono_gc_wbarrier_set_field (ares.32, D.19883, D.19882);
      ares.32 = ares;
      D.19879 = ares.32->execution_context;
      mono_thread_set_execution_context (D.19879);
      goto <D.19884>;
      <D.19881>:
      ares.32 = ares;
      ares.32->original_context = 0B;
      <D.19884>:
      if (ac == 0B) goto <D.19885>; else goto <D.19886>;
      <D.19885>:
      {
        void * pa;

        try
          {
            ares.32 = ares;
            pa.33 = ares.32->async_state;
            pa = pa.33;
            ares.32 = ares;
            D.19888 = ares.32->async_delegate;
            D.19889 = MEM[(struct MonoDelegate *)D.19888].method;
            thread->async_invoke_method = D.19889;
            ares.32 = ares;
            D.19888 = ares.32->async_delegate;
            res = mono_runtime_delegate_invoke (D.19888, &pa, &exc);
            thread->async_invoke_method = 0B;
          }
        finally
          {
            pa = {CLOBBER};
          }
      }
      goto <D.19890>;
      <D.19886>:
      {
        struct MonoObject * cb_exc;

        try
          {
            cb_exc = 0B;
            D.19891 = ac->msg;
            D.19891->exc = 0B;
            D.19891 = ac->msg;
            ares.32 = ares;
            D.19888 = ares.32->async_delegate;
            res = mono_message_invoke (D.19888, D.19891, &exc, &out_args);
            D.19892 = &ac->res;
            mono_gc_wbarrier_set_field (ac, D.19892, res);
            exc.34 = exc;
            D.19891 = ac->msg;
            D.19894 = &D.19891->exc;
            mono_gc_wbarrier_set_field (ac, D.19894, exc.34);
            out_args.35 = out_args;
            D.19896 = &ac->out_args;
            mono_gc_wbarrier_set_field (ac, D.19896, out_args.35);
            ares.32 = ares;
            mono_monitor_enter (ares.32);
            ares.32 = ares;
            ares.32->completed = 1;
            ares.32 = ares;
            D.19897 = ares.32->handle;
            if (D.19897 != 0B) goto <D.19898>; else goto <D.19899>;
            <D.19898>:
            ares.32 = ares;
            D.19897 = ares.32->handle;
            wait_event = mono_wait_handle_get_handle (D.19897);
            <D.19899>:
            ares.32 = ares;
            mono_monitor_exit (ares.32);
            if (wait_event != 0B) goto <D.19900>; else goto <D.19901>;
            <D.19900>:
            SetEvent (wait_event);
            <D.19901>:
            if (ac != 0B) goto <D.19904>; else goto <D.19902>;
            <D.19904>:
            D.19905 = ac->cb_method;
            if (D.19905 != 0B) goto <D.19906>; else goto <D.19902>;
            <D.19906>:
            {
              void * pa;

              pa = &ares;
              cb_exc = 0B;
              D.19905 = ac->cb_method;
              thread->async_invoke_method = D.19905;
              D.19907 = ac->cb_target;
              D.19905 = ac->cb_method;
              mono_runtime_invoke (D.19905, D.19907, pa, &cb_exc);
              thread->async_invoke_method = 0B;
              cb_exc.36 = cb_exc;
              exc = cb_exc.36;
            }
            goto <D.19903>;
            <D.19902>:
            exc = 0B;
            <D.19903>:
          }
        finally
          {
            cb_exc = {CLOBBER};
          }
      }
      <D.19890>:
      ares.32 = ares;
      D.19909 = ares.32->original_context;
      if (D.19909 != 0B) goto <D.19910>; else goto <D.19911>;
      <D.19910>:
      ares.32 = ares;
      D.19909 = ares.32->original_context;
      mono_thread_set_execution_context (D.19909);
      ares.32 = ares;
      ares.32->original_context = 0B;
      <D.19911>:
      D.19912 = exc;
      return D.19912;
    }
  finally
    {
      exc = {CLOBBER};
      out_args = {CLOBBER};
    }
}


create_simple_asyncresult (struct MonoObject * target, struct MonoObject * state)
{
  struct MonoClass * D.19915;
  struct MonoObject * * D.19916;
  struct MonoObject * * D.19917;
  struct MonoAsyncResult * D.19918;
  struct MonoDomain * domain;
  struct MonoAsyncResult * ares;

  domain = mono_domain_get ();
  D.19915 = mono_defaults.asyncresult_class;
  ares = mono_object_new (domain, D.19915);
  D.19916 = &ares->async_delegate;
  mono_gc_wbarrier_set_field (ares, D.19916, target);
  D.19917 = &ares->async_state;
  mono_gc_wbarrier_set_field (ares, D.19917, state);
  D.19918 = ares;
  return D.19918;
}


clear_thread_state ()
{
  int D.19920;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  mono_thread_clr_state (thread, 4294967291);
  D.19920 = mono_thread_test_state (thread, 4);
  if (D.19920 == 0) goto <D.19921>; else goto <D.19922>;
  <D.19921>:
  ves_icall_System_Threading_Thread_SetState (thread, 4);
  <D.19922>:
}


check_for_interruption_critical ()
{
  unsigned int D.19923;
  unsigned int D.19924;
  struct MonoInternalThread * thread;

  mono_gc_set_skip_thread (0);
  thread = mono_thread_internal_current ();
  D.19923 = thread->state;
  D.19924 = D.19923 & 3;
  if (D.19924 != 0) goto <D.19925>; else goto <D.19926>;
  <D.19925>:
  mono_thread_interruption_checkpoint ();
  <D.19926>:
  mono_gc_set_skip_thread (1);
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.19927;
  unsigned int D.19928;

  D.19928 = __sync_sub_and_fetch_4 (val, 1);
  D.19927 = (gint32) D.19928;
  return D.19927;
}


should_i_die (struct ThreadPool * tp)
{
  int D.19930;
  volatile gint * D.19933;
  int D.19934;
  int D.19937;
  int D.19938;
  _Bool D.19939;
  gboolean D.19940;
  gboolean result;

  result = 0;
  D.19930 = tp->destroy_thread;
  if (D.19930 == 1) goto <D.19931>; else goto <D.19932>;
  <D.19931>:
  D.19933 = &tp->destroy_thread;
  D.19934 = InterlockedCompareExchange (D.19933, 0, 1);
  if (D.19934 == 1) goto <D.19935>; else goto <D.19936>;
  <D.19935>:
  D.19937 = tp->nthreads;
  D.19938 = tp->min_threads;
  D.19939 = D.19937 > D.19938;
  result = (gboolean) D.19939;
  <D.19936>:
  <D.19932>:
  D.19940 = result;
  return D.19940;
}


dequeue_or_steal (struct ThreadPool * tp, void * * data, struct MonoWSQ * local_wsq)
{
  int D.19942;
  gboolean D.19945;
  struct MonoCQ * D.19946;
  int D.19947;
  void * D.19950;
  _Bool D.19953;

  D.19942 = mono_runtime_is_shutting_down ();
  if (D.19942 != 0) goto <D.19943>; else goto <D.19944>;
  <D.19943>:
  D.19945 = 0;
  return D.19945;
  <D.19944>:
  D.19946 = tp->queue;
  mono_cq_dequeue (D.19946, data);
  D.19947 = tp->is_io;
  if (D.19947 == 0) goto <D.19948>; else goto <D.19949>;
  <D.19948>:
  D.19950 = *data;
  if (D.19950 == 0B) goto <D.19951>; else goto <D.19952>;
  <D.19951>:
  try_steal (local_wsq, data, 0);
  <D.19952>:
  <D.19949>:
  D.19950 = *data;
  D.19953 = D.19950 != 0B;
  D.19945 = (gboolean) D.19953;
  return D.19945;
}


try_steal (struct MonoWSQ * local_wsq, void * * data, gboolean retry)
{
  struct GPtrArray * wsqs.37;
  void * D.19960;
  int D.19961;
  _Bool D.19966;
  long int D.19967;
  long int D.19968;
  void * * D.19971;
  long unsigned int D.19972;
  long unsigned int D.19973;
  void * * D.19974;
  int D.19978;
  unsigned int ms.38;
  void * D.19980;
  _Bool D.19985;
  long int D.19986;
  long int D.19987;
  unsigned int i.39;
  unsigned int D.19992;
  _Bool D.19995;
  long int D.19996;
  long int D.19997;
  _Bool D.20000;
  _Bool D.20001;
  _Bool D.20002;
  int i;
  int ms;

  wsqs.37 = wsqs;
  if (wsqs.37 == 0B) goto <D.19955>; else goto <D.19958>;
  <D.19958>:
  if (data == 0B) goto <D.19955>; else goto <D.19959>;
  <D.19959>:
  D.19960 = *data;
  if (D.19960 != 0B) goto <D.19955>; else goto <D.19956>;
  <D.19955>:
  return;
  <D.19956>:
  ms = 0;
  <D.18971>:
  D.19961 = mono_runtime_is_shutting_down ();
  if (D.19961 != 0) goto <D.19962>; else goto <D.19963>;
  <D.19962>:
  return;
  <D.19963>:
  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19964>; else goto <D.19965>;
    <D.19964>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19965>:
    D.19966 = ret != 0;
    D.19967 = (long int) D.19966;
    D.19968 = __builtin_expect (D.19967, 0);
    if (D.19968 != 0) goto <D.19969>; else goto <D.19970>;
    <D.19969>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1282, "ret == 0");
    <D.19970>:
  }
  i = 0;
  goto <D.18968>;
  <D.18967>:
  {
    struct MonoWSQ * wsq;

    wsqs.37 = wsqs;
    D.19971 = wsqs.37->pdata;
    D.19972 = (long unsigned int) i;
    D.19973 = D.19972 * 8;
    D.19974 = D.19971 + D.19973;
    wsq = *D.19974;
    if (wsq == local_wsq) goto <D.19975>; else goto <D.19977>;
    <D.19977>:
    D.19978 = mono_wsq_count (wsq);
    if (D.19978 == 0) goto <D.19975>; else goto <D.19976>;
    <D.19975>:
    // predicted unlikely by continue predictor.
    goto <D.18965>;
    <D.19976>:
    ms.38 = (unsigned int) ms;
    wsqs.37 = wsqs;
    D.19971 = wsqs.37->pdata;
    D.19972 = (long unsigned int) i;
    D.19973 = D.19972 * 8;
    D.19974 = D.19971 + D.19973;
    D.19980 = *D.19974;
    mono_wsq_try_steal (D.19980, data, ms.38);
    D.19960 = *data;
    if (D.19960 != 0B) goto <D.19981>; else goto <D.19982>;
    <D.19981>:
    {
      int ret;

      ret = pthread_mutex_unlock (&wsqs_lock.mutex);
      if (ret != 0) goto <D.19983>; else goto <D.19984>;
      <D.19983>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19984>:
      D.19985 = ret != 0;
      D.19986 = (long int) D.19985;
      D.19987 = __builtin_expect (D.19986, 0);
      if (D.19987 != 0) goto <D.19988>; else goto <D.19989>;
      <D.19988>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1291, "ret == 0");
      <D.19989>:
    }
    return;
    <D.19982>:
  }
  <D.18965>:
  i = i + 1;
  <D.18968>:
  wsqs.37 = wsqs;
  if (wsqs.37 != 0B) goto <D.19990>; else goto <D.18969>;
  <D.19990>:
  i.39 = (unsigned int) i;
  wsqs.37 = wsqs;
  D.19992 = wsqs.37->len;
  if (i.39 < D.19992) goto <D.18967>; else goto <D.18969>;
  <D.18969>:
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19993>; else goto <D.19994>;
    <D.19993>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19994>:
    D.19995 = ret != 0;
    D.19996 = (long int) D.19995;
    D.19997 = __builtin_expect (D.19996, 0);
    if (D.19997 != 0) goto <D.19998>; else goto <D.19999>;
    <D.19998>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1295, "ret == 0");
    <D.19999>:
  }
  ms = ms + 10;
  D.20000 = retry != 0;
  D.20001 = ms <= 10;
  D.20002 = D.20000 & D.20001;
  if (D.20002 != 0) goto <D.18971>; else goto <D.18972>;
  <D.18972>:
}


remove_wsq (struct MonoWSQ * wsq)
{
  _Bool D.20008;
  long int D.20009;
  long int D.20010;
  struct GPtrArray * wsqs.40;
  _Bool D.20018;
  long int D.20019;
  long int D.20020;
  int D.20023;
  void * data.41;
  int D.20027;
  _Bool D.20030;
  long int D.20031;
  long int D.20032;
  void * data;

  try
    {
      if (wsq == 0B) goto <D.20004>; else goto <D.20005>;
      <D.20004>:
      return;
      <D.20005>:
      {
        int ret;

        ret = pthread_mutex_lock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.20006>; else goto <D.20007>;
        <D.20006>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20007>:
        D.20008 = ret != 0;
        D.20009 = (long int) D.20008;
        D.20010 = __builtin_expect (D.20009, 0);
        if (D.20010 != 0) goto <D.20011>; else goto <D.20012>;
        <D.20011>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1247, "ret == 0");
        <D.20012>:
      }
      wsqs.40 = wsqs;
      if (wsqs.40 == 0B) goto <D.20014>; else goto <D.20015>;
      <D.20014>:
      {
        int ret;

        ret = pthread_mutex_unlock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.20016>; else goto <D.20017>;
        <D.20016>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20017>:
        D.20018 = ret != 0;
        D.20019 = (long int) D.20018;
        D.20020 = __builtin_expect (D.20019, 0);
        if (D.20020 != 0) goto <D.20021>; else goto <D.20022>;
        <D.20021>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1249, "ret == 0");
        <D.20022>:
      }
      return;
      <D.20015>:
      wsqs.40 = wsqs;
      monoeg_g_ptr_array_remove_fast (wsqs.40, wsq);
      data = 0B;
      D.20023 = mono_runtime_is_shutting_down ();
      if (D.20023 != 0) goto <D.20024>; else goto <D.20025>;
      <D.20024>:
      goto <D.18953>;
      <D.18952>:
      data.41 = data;
      threadpool_jobs_dec (data.41);
      data = 0B;
      <D.18953>:
      D.20027 = mono_wsq_local_pop (&data);
      if (D.20027 != 0) goto <D.18952>; else goto <D.18954>;
      <D.18954>:
      <D.20025>:
      mono_wsq_destroy (wsq);
      {
        int ret;

        ret = pthread_mutex_unlock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.20028>; else goto <D.20029>;
        <D.20028>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20029>:
        D.20030 = ret != 0;
        D.20031 = (long int) D.20030;
        D.20032 = __builtin_expect (D.20031, 0);
        if (D.20032 != 0) goto <D.20033>; else goto <D.20034>;
        <D.20033>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1265, "ret == 0");
        <D.20034>:
      }
    }
  finally
    {
      data = {CLOBBER};
    }
}


fire_profiler_thread_end ()
{
  long unsigned int D.20038;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.20038 = thread->tid;
  mono_profiler_thread_end (D.20038);
}


atoi (const char * __nptr)
{
  int D.20039;
  long int D.20040;

  D.20040 = strtol (__nptr, 0B, 10);
  D.20039 = (int) D.20040;
  return D.20039;
}


threadpool_init (struct ThreadPool * tp, int min_threads, int max_threads, void (*<Tbd4>) (void *) async_invoke)
{
  struct MonoCQ * D.20042;
  union MonoSemType * D.20043;

  memset (tp, 0, 184);
  tp->min_threads = min_threads;
  tp->max_threads = max_threads;
  tp->async_invoke = async_invoke;
  D.20042 = mono_cq_create ();
  tp->queue = D.20042;
  D.20043 = &tp->new_job;
  sem_init (D.20043, 0, 0);
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.20046;
  int D.20051;
  void * D.20053;
  long unsigned int D.20054;

  D.20046 = __builtin_constant_p (__len);
  if (D.20046 != 0) goto <D.20047>; else goto <D.20048>;
  <D.20047>:
  if (__len == 0) goto <D.20049>; else goto <D.20050>;
  <D.20049>:
  D.20051 = __builtin_constant_p (__ch);
  if (D.20051 == 0) goto <D.20044>; else goto <D.20052>;
  <D.20052>:
  if (__ch != 0) goto <D.20044>; else goto <D.20045>;
  <D.20044>:
  __warn_memset_zero_len ();
  D.20053 = __dest;
  return D.20053;
  <D.20045>:
  <D.20050>:
  <D.20048>:
  D.20054 = __builtin_object_size (__dest, 0);
  D.20053 = __builtin___memset_chk (__dest, __ch, __len, D.20054);
  return D.20053;
}


init_perf_counter (const char * category, const char * counter)
{
  _Bool D.20056;
  _Bool D.20057;
  _Bool D.20058;
  void * D.20061;
  struct MonoString * category_str;
  struct MonoString * counter_str;
  struct MonoString * machine;
  struct MonoDomain * root;
  MonoBoolean custom;
  int type;

  try
    {
      D.20056 = category == 0B;
      D.20057 = counter == 0B;
      D.20058 = D.20056 | D.20057;
      if (D.20058 != 0) goto <D.20059>; else goto <D.20060>;
      <D.20059>:
      D.20061 = 0B;
      return D.20061;
      <D.20060>:
      root = mono_get_root_domain ();
      category_str = mono_string_new (root, category);
      counter_str = mono_string_new (root, counter);
      machine = mono_string_new (root, ".");
      D.20061 = mono_perfcounter_get_impl (category_str, counter_str, 0B, machine, &type, &custom);
      return D.20061;
    }
  finally
    {
      custom = {CLOBBER};
      type = {CLOBBER};
    }
}


icall_append_io_job (struct MonoObject * target, struct MonoSocketAsyncResult * state)
{
  struct MonoAsyncResult * ares;

  ares = create_simple_asyncresult (target, state);
  socket_io_add (ares, state);
}


socket_io_add (struct MonoAsyncResult * ares, struct MonoSocketAsyncResult * state)
{
  int D.20066;
  int D.20068;
  struct MonoGHashTable * D.20070;
  int D.20071;
  struct MonoAsyncResult * * D.20074;
  void * D.20075;
  long int D.20076;
  union mono_mutex_t * D.20077;
  _Bool D.20080;
  long int D.20081;
  long int D.20082;
  _Bool D.20089;
  long int D.20090;
  long int D.20091;
  long int D.20094;
  const void * D.20095;
  void (*<T2f81>) (void *, int, int, int, gboolean) D.20099;
  int D.20100;
  struct MonoMList * list;
  struct SocketIOData * data;
  int fd;
  gboolean is_new;
  int ievt;

  data = &socket_io_data;
  socket_io_init (&socket_io_data);
  D.20066 = mono_runtime_is_shutting_down ();
  if (D.20066 != 0) goto <D.20064>; else goto <D.20067>;
  <D.20067>:
  D.20068 = data->inited;
  if (D.20068 == 3) goto <D.20064>; else goto <D.20069>;
  <D.20069>:
  D.20070 = data->sock_to_state;
  if (D.20070 == 0B) goto <D.20064>; else goto <D.20065>;
  <D.20064>:
  return;
  <D.20065>:
  D.20071 = async_tp.pool_status;
  if (D.20071 == 2) goto <D.20072>; else goto <D.20073>;
  <D.20072>:
  return;
  <D.20073>:
  D.20074 = &state->ares;
  mono_gc_wbarrier_set_field (state, D.20074, ares);
  D.20075 = state->handle;
  D.20076 = (long int) D.20075;
  fd = (int) D.20076;
  {
    int ret;

    D.20077 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20077);
    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", "threadpool.c", 546, "ret == 0");
    <D.20084>:
  }
  D.20070 = data->sock_to_state;
  if (D.20070 == 0B) goto <D.20085>; else goto <D.20086>;
  <D.20085>:
  {
    int ret;

    D.20077 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20077);
    if (ret != 0) goto <D.20087>; else goto <D.20088>;
    <D.20087>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20088>:
    D.20089 = ret != 0;
    D.20090 = (long int) D.20089;
    D.20091 = __builtin_expect (D.20090, 0);
    if (D.20091 != 0) goto <D.20092>; else goto <D.20093>;
    <D.20092>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 548, "ret == 0");
    <D.20093>:
  }
  return;
  <D.20086>:
  D.20094 = (long int) fd;
  D.20095 = (const void *) D.20094;
  D.20070 = data->sock_to_state;
  list = mono_g_hash_table_lookup (D.20070, D.20095);
  if (list == 0B) goto <D.20096>; else goto <D.20097>;
  <D.20096>:
  list = mono_mlist_alloc (state);
  is_new = 1;
  goto <D.20098>;
  <D.20097>:
  list = mono_mlist_append (list, state);
  is_new = 0;
  <D.20098>:
  D.20075 = state->handle;
  D.20070 = data->sock_to_state;
  mono_g_hash_table_replace (D.20070, D.20075, list);
  ievt = get_events_from_list (list);
  D.20099 = data->modify;
  D.20100 = state->operation;
  D.20099 (data, fd, D.20100, ievt, is_new);
}


socket_io_init (struct SocketIOData * data)
{
  int D.20102;
  int * D.20105;
  union mono_mutex_t * D.20110;
  _Bool D.20113;
  long int D.20114;
  long int D.20115;
  struct MonoGHashTable * D.20118;
  const gchar * D.20119;
  void (*<Tbd4>) (void *) D.20122;
  struct MonoDomain * D.20123;
  _Bool D.20126;
  long int D.20127;
  long int D.20128;
  int inited;

  D.20102 = data->inited;
  if (D.20102 > 1) goto <D.20103>; else goto <D.20104>;
  <D.20103>:
  return;
  <D.20104>:
  D.20105 = &data->inited;
  inited = InterlockedCompareExchange (D.20105, 1, 0);
  if (inited > 0) goto <D.20106>; else goto <D.20107>;
  <D.20106>:
  <D.18723>:
  D.20102 = data->inited;
  if (D.20102 > 1) goto <D.20108>; else goto <D.20109>;
  <D.20108>:
  return;
  <D.20109>:
  SleepEx (1, 0);
  goto <D.18723>;
  <D.20107>:
  {
    int ret;

    D.20110 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20110);
    if (ret != 0) goto <D.20111>; else goto <D.20112>;
    <D.20111>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20112>:
    D.20113 = ret != 0;
    D.20114 = (long int) D.20113;
    D.20115 = __builtin_expect (D.20114, 0);
    if (D.20115 != 0) goto <D.20116>; else goto <D.20117>;
    <D.20116>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 509, "ret == 0");
    <D.20117>:
  }
  D.20118 = mono_g_hash_table_new_type (monoeg_g_direct_hash, monoeg_g_direct_equal, 2);
  data->sock_to_state = D.20118;
  data->event_system = 1;
  D.20119 = monoeg_g_getenv ("MONO_DISABLE_AIO");
  if (D.20119 != 0B) goto <D.20120>; else goto <D.20121>;
  <D.20120>:
  data->event_system = 0;
  <D.20121>:
  init_event_system (data);
  D.20122 = data->wait;
  D.20123 = mono_get_root_domain ();
  mono_thread_create_internal (D.20123, D.20122, data, 1, 0, 262144);
  {
    int ret;

    D.20110 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20110);
    if (ret != 0) goto <D.20124>; else goto <D.20125>;
    <D.20124>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20125>:
    D.20126 = ret != 0;
    D.20127 = (long int) D.20126;
    D.20128 = __builtin_expect (D.20127, 0);
    if (D.20128 != 0) goto <D.20129>; else goto <D.20130>;
    <D.20129>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 523, "ret == 0");
    <D.20130>:
  }
  data->inited = 2;
  threadpool_start_thread (&async_io_tp);
}


init_event_system (struct SocketIOData * data)
{
  int D.20132;
  void * D.20135;
  void * D.20136;
  const gchar * D.20139;
  void * D.20144;

  D.20132 = data->event_system;
  if (D.20132 == 1) goto <D.20133>; else goto <D.20134>;
  <D.20133>:
  D.20135 = tp_epoll_init (data);
  data->event_data = D.20135;
  D.20136 = data->event_data;
  if (D.20136 == 0B) goto <D.20137>; else goto <D.20138>;
  <D.20137>:
  D.20139 = monoeg_g_getenv ("MONO_DEBUG");
  if (D.20139 != 0B) goto <D.20140>; else goto <D.20141>;
  <D.20140>:
  monoeg_g_log (0B, 32, "Falling back to poll()");
  <D.20141>:
  data->event_system = 0;
  <D.20138>:
  <D.20134>:
  D.20132 = data->event_system;
  if (D.20132 == 0) goto <D.20142>; else goto <D.20143>;
  <D.20142>:
  D.20144 = tp_poll_init (data);
  data->event_data = D.20144;
  <D.20143>:
}


tp_epoll_init (struct SocketIOData * data)
{
  int D.20145;
  int D.20146;
  int * D.20149;
  const gchar * D.20150;
  const gchar * D.20153;
  void * D.20154;
  struct tp_epoll_data * result;

  result = monoeg_malloc0 (4);
  D.20145 = epoll_create1 (524288);
  result->epollfd = D.20145;
  D.20146 = result->epollfd;
  if (D.20146 == -1) goto <D.20147>; else goto <D.20148>;
  <D.20147>:
  {
    int err;

    D.20149 = __errno_location ();
    err = *D.20149;
    D.20150 = monoeg_g_getenv ("MONO_DEBUG");
    if (D.20150 != 0B) goto <D.20151>; else goto <D.20152>;
    <D.20151>:
    D.20153 = monoeg_g_strerror (err);
    monoeg_g_log (0B, 32, "epoll_create1(EPOLL_CLOEXEC) failed: %d %s", err, D.20153);
    <D.20152>:
    D.20154 = 0B;
    return D.20154;
  }
  <D.20148>:
  data->shutdown = tp_epoll_shutdown;
  data->modify = tp_epoll_modify;
  data->wait = tp_epoll_wait;
  D.20154 = result;
  return D.20154;
}


tp_epoll_wait (void * p)
{
  int * D.20159;
  int D.20160;
  const gchar * D.20165;
  union mono_mutex_t * D.20166;
  _Bool D.20169;
  long int D.20170;
  long int D.20171;
  int D.20174;
  _Bool D.20179;
  long int D.20180;
  long int D.20181;
  long unsigned int D.20184;
  long unsigned int D.20185;
  long int D.20186;
  const void * D.20187;
  struct MonoGHashTable * D.20188;
  void * list.42;
  struct MonoMList * list.43;
  unsigned int D.20193;
  unsigned int D.20194;
  int nresults.44;
  unsigned int D.20202;
  int nresults.45;
  void * D.20210;
  unsigned int p.46;
  unsigned int D.20212;
  unsigned int D.20213;
  unsigned int D.20214;
  int D.20215;
  int D.20218;
  const gchar * D.20221;
  _Bool D.20225;
  long int D.20226;
  long int D.20227;
  long unsigned int D.20230;
  long unsigned int D.20231;
  struct SocketIOData * socket_io_data;
  int epollfd;
  struct epoll_event * events;
  struct epoll_event * evt;
  int ready;
  int i;
  void * async_results[256];
  gint nresults;
  struct tp_epoll_data * data;

  try
    {
      ready = 0;
      socket_io_data = p;
      data = socket_io_data->event_data;
      epollfd = data->epollfd;
      events = monoeg_malloc0 (1536);
      <D.18515>:
      mono_gc_set_skip_thread (1);
      <D.18501>:
      if (ready == -1) goto <D.20156>; else goto <D.20157>;
      <D.20156>:
      check_for_interruption_critical ();
      <D.20157>:
      ready = epoll_wait (epollfd, events, 128, -1);
      if (ready == -1) goto <D.20158>; else goto <D.18502>;
      <D.20158>:
      D.20159 = __errno_location ();
      D.20160 = *D.20159;
      if (D.20160 == 4) goto <D.18501>; else goto <D.18502>;
      <D.18502>:
      mono_gc_set_skip_thread (0);
      if (ready == -1) goto <D.20161>; else goto <D.20162>;
      <D.20161>:
      {
        int err;

        D.20159 = __errno_location ();
        err = *D.20159;
        monoeg_g_free (events);
        if (err != 9) goto <D.20163>; else goto <D.20164>;
        <D.20163>:
        D.20165 = monoeg_g_strerror (err);
        monoeg_g_log (0B, 16, "epoll_wait: %d %s", err, D.20165);
        <D.20164>:
        return;
      }
      <D.20162>:
      {
        int ret;

        D.20166 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_lock (D.20166);
        if (ret != 0) goto <D.20167>; else goto <D.20168>;
        <D.20167>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20168>:
        D.20169 = ret != 0;
        D.20170 = (long int) D.20169;
        D.20171 = __builtin_expect (D.20170, 0);
        if (D.20171 != 0) goto <D.20172>; else goto <D.20173>;
        <D.20172>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 132, "ret == 0");
        <D.20173>:
      }
      D.20174 = socket_io_data->inited;
      if (D.20174 == 3) goto <D.20175>; else goto <D.20176>;
      <D.20175>:
      monoeg_g_free (events);
      {
        int ret;

        D.20166 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20166);
        if (ret != 0) goto <D.20177>; else goto <D.20178>;
        <D.20177>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20178>:
        D.20179 = ret != 0;
        D.20180 = (long int) D.20179;
        D.20181 = __builtin_expect (D.20180, 0);
        if (D.20181 != 0) goto <D.20182>; else goto <D.20183>;
        <D.20182>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 135, "ret == 0");
        <D.20183>:
      }
      return;
      <D.20176>:
      nresults = 0;
      i = 0;
      goto <D.18512>;
      <D.18511>:
      {
        int fd;
        struct MonoMList * list;
        struct MonoObject * ares;

        try
          {
            D.20184 = (long unsigned int) i;
            D.20185 = D.20184 * 12;
            evt = events + D.20185;
            fd = evt->data.fd;
            D.20186 = (long int) fd;
            D.20187 = (const void *) D.20186;
            D.20188 = socket_io_data->sock_to_state;
            list.42 = mono_g_hash_table_lookup (D.20188, D.20187);
            list = list.42;
            list.43 = list;
            if (list.43 != 0B) goto <D.20191>; else goto <D.20192>;
            <D.20191>:
            D.20193 = evt->events;
            D.20194 = D.20193 & 25;
            if (D.20194 != 0) goto <D.20195>; else goto <D.20196>;
            <D.20195>:
            ares = get_io_event (&list, 1);
            if (ares != 0B) goto <D.20197>; else goto <D.20198>;
            <D.20197>:
            nresults.44 = nresults;
            nresults = nresults.44 + 1;
            async_results[nresults.44] = ares;
            <D.20198>:
            <D.20196>:
            <D.20192>:
            list.43 = list;
            if (list.43 != 0B) goto <D.20200>; else goto <D.20201>;
            <D.20200>:
            D.20193 = evt->events;
            D.20202 = D.20193 & 28;
            if (D.20202 != 0) goto <D.20203>; else goto <D.20204>;
            <D.20203>:
            ares = get_io_event (&list, 4);
            if (ares != 0B) goto <D.20205>; else goto <D.20206>;
            <D.20205>:
            nresults.45 = nresults;
            nresults = nresults.45 + 1;
            async_results[nresults.45] = ares;
            <D.20206>:
            <D.20204>:
            <D.20201>:
            list.43 = list;
            if (list.43 != 0B) goto <D.20208>; else goto <D.20209>;
            <D.20208>:
            {
              int p;

              list.43 = list;
              D.20186 = (long int) fd;
              D.20210 = (void *) D.20186;
              D.20188 = socket_io_data->sock_to_state;
              mono_g_hash_table_replace (D.20188, D.20210, list.43);
              list.43 = list;
              p = get_events_from_list (list.43);
              p.46 = (unsigned int) p;
              D.20212 = p.46 & 4;
              evt->events = D.20212;
              D.20193 = evt->events;
              p.46 = (unsigned int) p;
              D.20213 = p.46 & 1;
              D.20214 = D.20193 | D.20213;
              evt->events = D.20214;
              D.20215 = epoll_ctl (epollfd, 3, fd, evt);
              if (D.20215 == -1) goto <D.20216>; else goto <D.20217>;
              <D.20216>:
              D.20218 = epoll_ctl (epollfd, 1, fd, evt);
              if (D.20218 == -1) goto <D.20219>; else goto <D.20220>;
              <D.20219>:
              {
                int err;

                D.20159 = __errno_location ();
                err = *D.20159;
                D.20221 = monoeg_g_strerror (err);
                monoeg_g_log (0B, 32, "epoll(ADD): %d %s", err, D.20221);
              }
              <D.20220>:
              <D.20217>:
            }
            goto <D.20222>;
            <D.20209>:
            D.20186 = (long int) fd;
            D.20187 = (const void *) D.20186;
            D.20188 = socket_io_data->sock_to_state;
            mono_g_hash_table_remove (D.20188, D.20187);
            epoll_ctl (epollfd, 2, fd, evt);
            <D.20222>:
          }
        finally
          {
            list = {CLOBBER};
          }
      }
      i = i + 1;
      <D.18512>:
      if (i < ready) goto <D.18511>; else goto <D.18513>;
      <D.18513>:
      {
        int ret;

        D.20166 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20166);
        if (ret != 0) goto <D.20223>; else goto <D.20224>;
        <D.20223>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20224>:
        D.20225 = ret != 0;
        D.20226 = (long int) D.20225;
        D.20227 = __builtin_expect (D.20226, 0);
        if (D.20227 != 0) goto <D.20228>; else goto <D.20229>;
        <D.20228>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 178, "ret == 0");
        <D.20229>:
      }
      threadpool_append_jobs (&async_io_tp, &async_results, nresults);
      D.20230 = (long unsigned int) nresults;
      D.20231 = D.20230 * 8;
      mono_gc_bzero_aligned (&async_results, D.20231);
      goto <D.18515>;
    }
  finally
    {
      async_results = {CLOBBER};
    }
}


tp_epoll_modify (void * p, int fd, int operation, int events, gboolean is_new)
{
  int D.20234;
  unsigned int D.20237;
  unsigned int D.20238;
  int D.20239;
  unsigned int D.20242;
  int iftmp.47;
  int D.20247;
  int D.20248;
  int * D.20251;
  _Bool D.20252;
  _Bool D.20253;
  _Bool D.20254;
  int D.20257;
  const gchar * D.20260;
  union mono_mutex_t * D.20261;
  _Bool D.20264;
  long int D.20265;
  long int D.20266;
  struct SocketIOData * socket_io_data;
  struct tp_epoll_data * data;
  struct epoll_event evt;
  int epoll_op;

  try
    {
      socket_io_data = p;
      data = socket_io_data->event_data;
      memset (&evt, 0, 12);
      evt.data.fd = fd;
      D.20234 = events & 1;
      if (D.20234 != 0) goto <D.20235>; else goto <D.20236>;
      <D.20235>:
      D.20237 = evt.events;
      D.20238 = D.20237 | 1;
      evt.events = D.20238;
      <D.20236>:
      D.20239 = events & 4;
      if (D.20239 != 0) goto <D.20240>; else goto <D.20241>;
      <D.20240>:
      D.20237 = evt.events;
      D.20242 = D.20237 | 4;
      evt.events = D.20242;
      <D.20241>:
      if (is_new != 0) goto <D.20244>; else goto <D.20245>;
      <D.20244>:
      iftmp.47 = 1;
      goto <D.20246>;
      <D.20245>:
      iftmp.47 = 3;
      <D.20246>:
      epoll_op = iftmp.47;
      D.20247 = data->epollfd;
      D.20248 = epoll_ctl (D.20247, epoll_op, fd, &evt);
      if (D.20248 == -1) goto <D.20249>; else goto <D.20250>;
      <D.20249>:
      {
        int err;

        D.20251 = __errno_location ();
        err = *D.20251;
        D.20252 = epoll_op == 1;
        D.20253 = err == 17;
        D.20254 = D.20252 & D.20253;
        if (D.20254 != 0) goto <D.20255>; else goto <D.20256>;
        <D.20255>:
        epoll_op = 3;
        D.20247 = data->epollfd;
        D.20257 = epoll_ctl (D.20247, epoll_op, fd, &evt);
        if (D.20257 == -1) goto <D.20258>; else goto <D.20259>;
        <D.20258>:
        D.20260 = monoeg_g_strerror (err);
        monoeg_g_log (0B, 32, "epoll_ctl(MOD): %d %s", err, D.20260);
        <D.20259>:
        <D.20256>:
      }
      <D.20250>:
      {
        int ret;

        D.20261 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20261);
        if (ret != 0) goto <D.20262>; else goto <D.20263>;
        <D.20262>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20263>:
        D.20264 = ret != 0;
        D.20265 = (long int) D.20264;
        D.20266 = __builtin_expect (D.20265, 0);
        if (D.20266 != 0) goto <D.20267>; else goto <D.20268>;
        <D.20267>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 81, "ret == 0");
        <D.20268>:
      }
    }
  finally
    {
      evt = {CLOBBER};
    }
}


tp_epoll_shutdown (void * event_data)
{
  int D.20269;
  struct tp_epoll_data * data;

  data = event_data;
  D.20269 = data->epollfd;
  close (D.20269);
  monoeg_g_free (data);
}


tp_poll_init (struct SocketIOData * data)
{
  int[2] * D.20270;
  int D.20271;
  int * D.20274;
  _Bool D.20275;
  long int D.20276;
  long int D.20277;
  union MonoSemType * D.20280;
  void * D.20281;
  struct tp_poll_data * result;

  result = monoeg_malloc0 (48);
  D.20270 = &result->pipe;
  D.20271 = pipe (D.20270);
  if (D.20271 != 0) goto <D.20272>; else goto <D.20273>;
  <D.20272>:
  {
    int err;

    D.20274 = __errno_location ();
    err = *D.20274;
    perror ("mono");
    D.20275 = err == 0;
    D.20276 = (long int) D.20275;
    D.20277 = __builtin_expect (D.20276, 0);
    if (D.20277 != 0) goto <D.20278>; else goto <D.20279>;
    <D.20278>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 41, "err");
    <D.20279>:
  }
  <D.20273>:
  D.20280 = &result->new_sem;
  sem_init (D.20280, 0, 1);
  data->shutdown = tp_poll_shutdown;
  data->modify = tp_poll_modify;
  data->wait = tp_poll_wait;
  D.20281 = result;
  return D.20281;
}


tp_poll_wait (void * p)
{
  long unsigned int D.20283;
  long unsigned int D.20284;
  int D.20285;
  int D.20286;
  void * iftmp.48;
  void * D.20290;
  long unsigned int D.20291;
  int D.20293;
  long unsigned int D.20294;
  long unsigned int D.20295;
  struct mono_pollfd * D.20296;
  unsigned int maxfd.49;
  int * D.20301;
  int D.20302;
  short int D.20307;
  int D.20308;
  int D.20309;
  int D.20312;
  void * * D.20315;
  int D.20316;
  int D.20319;
  int D.20320;
  long int D.20328;
  short int D.20333;
  struct mono_pollfd * D.20334;
  union MonoSemType * D.20335;
  union mono_mutex_t * D.20340;
  _Bool D.20343;
  long int D.20344;
  long int D.20345;
  int D.20348;
  _Bool D.20355;
  long int D.20356;
  long int D.20357;
  long unsigned int D.20360;
  long unsigned int D.20361;
  short int D.20365;
  long int D.20366;
  const void * D.20367;
  struct MonoGHashTable * D.20368;
  void * list.50;
  struct MonoMList * list.51;
  int D.20373;
  int D.20374;
  int D.20379;
  int D.20382;
  void * D.20383;
  long unsigned int D.20384;
  int D.20387;
  int D.20388;
  long unsigned int D.20389;
  long unsigned int D.20390;
  void * * D.20391;
  int D.20394;
  void * D.20401;
  int D.20404;
  int D.20405;
  long unsigned int D.20406;
  long unsigned int D.20407;
  void * * D.20408;
  void * D.20411;
  int D.20412;
  short int D.20413;
  int D.20415;
  _Bool D.20418;
  _Bool D.20419;
  _Bool D.20420;
  _Bool D.20423;
  long int D.20424;
  long int D.20425;
  struct mono_pollfd * pfds;
  gint maxfd;
  gint allocated;
  gint i;
  struct tp_poll_data * data;
  struct SocketIOData * socket_io_data;
  struct MonoPtrArray async_results;
  gint nresults;

  try
    {
      maxfd = 1;
      socket_io_data = p;
      data = socket_io_data->event_data;
      allocated = 1024;
      D.20283 = (long unsigned int) allocated;
      D.20284 = D.20283 * 8;
      pfds = monoeg_malloc0 (D.20284);
      async_results.size = 0;
      D.20285 = allocated * 2;
      D.20286 = MAX_EXPR <D.20285, 16>;
      async_results.capacity = D.20286;
      D.20285 = allocated * 2;
      if (D.20285 > 16) goto <D.20288>; else goto <D.20289>;
      <D.20288>:
      D.20285 = allocated * 2;
      D.20290 = mono_gc_make_root_descr_all_refs (D.20285);
      D.20283 = (long unsigned int) allocated;
      D.20291 = D.20283 * 16;
      iftmp.48 = mono_gc_alloc_fixed (D.20291, D.20290);
      goto <D.20292>;
      <D.20289>:
      iftmp.48 = __builtin_alloca (128);
      <D.20292>:
      async_results.data = iftmp.48;
      D.20293 = data->pipe[0];
      pfds->fd = D.20293;
      pfds->events = 1;
      pfds->revents = 0;
      i = 1;
      goto <D.18422>;
      <D.18421>:
      D.20294 = (long unsigned int) i;
      D.20295 = D.20294 * 8;
      D.20296 = pfds + D.20295;
      D.20296->fd = -1;
      D.20294 = (long unsigned int) i;
      D.20295 = D.20294 * 8;
      D.20296 = pfds + D.20295;
      D.20296->events = 0;
      D.20294 = (long unsigned int) i;
      D.20295 = D.20294 * 8;
      D.20296 = pfds + D.20295;
      D.20296->revents = 0;
      i = i + 1;
      <D.18422>:
      if (i < allocated) goto <D.18421>; else goto <D.18423>;
      <D.18423>:
      <D.18453>:
      {
        int nsock;
        struct mono_pollfd * pfd;
        char one[1];
        struct MonoMList * list;
        struct MonoObject * ares;

        try
          {
            nsock = 0;
            mono_gc_set_skip_thread (1);
            <D.18429>:
            if (nsock == -1) goto <D.20297>; else goto <D.20298>;
            <D.20297>:
            check_for_interruption_critical ();
            <D.20298>:
            maxfd.49 = (unsigned int) maxfd;
            nsock = mono_poll (pfds, maxfd.49, -1);
            if (nsock == -1) goto <D.20300>; else goto <D.18430>;
            <D.20300>:
            D.20301 = __errno_location ();
            D.20302 = *D.20301;
            if (D.20302 == 4) goto <D.18429>; else goto <D.18430>;
            <D.18430>:
            mono_gc_set_skip_thread (0);
            if (nsock == -1) goto <D.20303>; else goto <D.20304>;
            <D.20303>:
            D.20301 = __errno_location ();
            D.20302 = *D.20301;
            if (D.20302 == 9) goto <D.20305>; else goto <D.20306>;
            <D.20305>:
            pfds->revents = 0;
            nsock = mark_bad_fds (pfds, maxfd);
            <D.20306>:
            <D.20304>:
            D.20307 = pfds->revents;
            D.20308 = (int) D.20307;
            D.20309 = D.20308 & 56;
            if (D.20309 != 0) goto <D.20310>; else goto <D.20311>;
            <D.20310>:
            monoeg_g_free (pfds);
            D.20312 = async_results.capacity;
            if (D.20312 > 16) goto <D.20313>; else goto <D.20314>;
            <D.20313>:
            D.20315 = async_results.data;
            mono_gc_free_fixed (D.20315);
            <D.20314>:
            socket_io_cleanup (socket_io_data);
            return;
            <D.20311>:
            D.20307 = pfds->revents;
            D.20308 = (int) D.20307;
            D.20316 = D.20308 & 1;
            if (D.20316 != 0) goto <D.20317>; else goto <D.20318>;
            <D.20317>:
            {
              int nread;
              gboolean found;

              found = 0;
              i = 1;
              goto <D.18435>;
              <D.18434>:
              D.20294 = (long unsigned int) i;
              D.20295 = D.20294 * 8;
              pfd = pfds + D.20295;
              D.20319 = pfd->fd;
              D.20320 = data->newpfd.fd;
              if (D.20319 == D.20320) goto <D.20321>; else goto <D.20322>;
              <D.20321>:
              found = 1;
              goto <D.18433>;
              <D.20322>:
              i = i + 1;
              <D.18435>:
              if (i < allocated) goto <D.18434>; else goto <D.18433>;
              <D.18433>:
              if (found == 0) goto <D.20323>; else goto <D.20324>;
              <D.20323>:
              i = 1;
              goto <D.18438>;
              <D.18437>:
              D.20294 = (long unsigned int) i;
              D.20295 = D.20294 * 8;
              pfd = pfds + D.20295;
              D.20319 = pfd->fd;
              if (D.20319 == -1) goto <D.18436>; else goto <D.20325>;
              <D.20325>:
              i = i + 1;
              <D.18438>:
              if (i < allocated) goto <D.18437>; else goto <D.18436>;
              <D.18436>:
              <D.20324>:
              if (i == allocated) goto <D.20326>; else goto <D.20327>;
              <D.20326>:
              {
                struct mono_pollfd * oldfd;

                oldfd = pfds;
                i = allocated;
                allocated = allocated * 2;
                D.20283 = (long unsigned int) allocated;
                D.20284 = D.20283 * 8;
                pfds = monoeg_realloc (oldfd, D.20284);
                monoeg_g_free (oldfd);
                goto <D.18441>;
                <D.18440>:
                D.20294 = (long unsigned int) i;
                D.20295 = D.20294 * 8;
                D.20296 = pfds + D.20295;
                D.20296->fd = -1;
                D.20294 = (long unsigned int) i;
                D.20295 = D.20294 * 8;
                D.20296 = pfds + D.20295;
                D.20296->events = 0;
                D.20294 = (long unsigned int) i;
                D.20295 = D.20294 * 8;
                D.20296 = pfds + D.20295;
                D.20296->revents = 0;
                i = i + 1;
                <D.18441>:
                if (i < allocated) goto <D.18440>; else goto <D.18442>;
                <D.18442>:
              }
              <D.20327>:
              D.20293 = data->pipe[0];
              D.20328 = read (D.20293, &one, 1);
              nread = (int) D.20328;
              if (nread <= 0) goto <D.20329>; else goto <D.20330>;
              <D.20329>:
              monoeg_g_free (pfds);
              D.20312 = async_results.capacity;
              if (D.20312 > 16) goto <D.20331>; else goto <D.20332>;
              <D.20331>:
              D.20315 = async_results.data;
              mono_gc_free_fixed (D.20315);
              <D.20332>:
              return;
              <D.20330>:
              D.20294 = (long unsigned int) i;
              D.20295 = D.20294 * 8;
              D.20296 = pfds + D.20295;
              D.20320 = data->newpfd.fd;
              D.20296->fd = D.20320;
              D.20294 = (long unsigned int) i;
              D.20295 = D.20294 * 8;
              D.20296 = pfds + D.20295;
              D.20333 = data->newpfd.events;
              D.20296->events = D.20333;
              D.20294 = (long unsigned int) i;
              D.20295 = D.20294 * 8;
              D.20296 = pfds + D.20295;
              D.20296->revents = 0;
              D.20334 = &data->newpfd;
              memset (D.20334, 0, 8);
              D.20335 = &data->new_sem;
              mono_sem_post (D.20335);
              if (i >= maxfd) goto <D.20336>; else goto <D.20337>;
              <D.20336>:
              maxfd = i + 1;
              <D.20337>:
              nsock = nsock + -1;
            }
            <D.20318>:
            if (nsock == 0) goto <D.20338>; else goto <D.20339>;
            <D.20338>:
            // predicted unlikely by continue predictor.
            goto <D.18443>;
            <D.20339>:
            {
              int ret;

              D.20340 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_lock (D.20340);
              if (ret != 0) goto <D.20341>; else goto <D.20342>;
              <D.20341>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
              <D.20342>:
              D.20343 = ret != 0;
              D.20344 = (long int) D.20343;
              D.20345 = __builtin_expect (D.20344, 0);
              if (D.20345 != 0) goto <D.20346>; else goto <D.20347>;
              <D.20346>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 273, "ret == 0");
              <D.20347>:
            }
            D.20348 = socket_io_data->inited;
            if (D.20348 == 3) goto <D.20349>; else goto <D.20350>;
            <D.20349>:
            monoeg_g_free (pfds);
            D.20312 = async_results.capacity;
            if (D.20312 > 16) goto <D.20351>; else goto <D.20352>;
            <D.20351>:
            D.20315 = async_results.data;
            mono_gc_free_fixed (D.20315);
            <D.20352>:
            {
              int ret;

              D.20340 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_unlock (D.20340);
              if (ret != 0) goto <D.20353>; else goto <D.20354>;
              <D.20353>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
              <D.20354>:
              D.20355 = ret != 0;
              D.20356 = (long int) D.20355;
              D.20357 = __builtin_expect (D.20356, 0);
              if (D.20357 != 0) goto <D.20358>; else goto <D.20359>;
              <D.20358>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 277, "ret == 0");
              <D.20359>:
            }
            return;
            <D.20350>:
            nresults = 0;
            async_results.size = 0;
            D.20312 = async_results.capacity;
            D.20360 = (long unsigned int) D.20312;
            D.20361 = D.20360 * 8;
            D.20315 = async_results.data;
            mono_gc_bzero_aligned (D.20315, D.20361);
            i = 1;
            goto <D.18450>;
            <D.18449>:
            D.20294 = (long unsigned int) i;
            D.20295 = D.20294 * 8;
            pfd = pfds + D.20295;
            D.20319 = pfd->fd;
            if (D.20319 == -1) goto <D.20362>; else goto <D.20364>;
            <D.20364>:
            D.20365 = pfd->revents;
            if (D.20365 == 0) goto <D.20362>; else goto <D.20363>;
            <D.20362>:
            // predicted unlikely by continue predictor.
            goto <D.18446>;
            <D.20363>:
            nsock = nsock + -1;
            D.20319 = pfd->fd;
            D.20366 = (long int) D.20319;
            D.20367 = (const void *) D.20366;
            D.20368 = socket_io_data->sock_to_state;
            list.50 = mono_g_hash_table_lookup (D.20368, D.20367);
            list = list.50;
            list.51 = list;
            if (list.51 != 0B) goto <D.20371>; else goto <D.20372>;
            <D.20371>:
            D.20365 = pfd->revents;
            D.20373 = (int) D.20365;
            D.20374 = D.20373 & 57;
            if (D.20374 != 0) goto <D.20375>; else goto <D.20376>;
            <D.20375>:
            ares = get_io_event (&list, 1);
            if (ares != 0B) goto <D.20377>; else goto <D.20378>;
            <D.20377>:
            D.20379 = async_results.size;
            D.20312 = async_results.capacity;
            if (D.20379 >= D.20312) goto <D.20380>; else goto <D.20381>;
            <D.20380>:
            {
              void * __tmp;

              D.20312 = async_results.capacity;
              D.20382 = D.20312 * 2;
              D.20383 = mono_gc_make_root_descr_all_refs (D.20382);
              D.20312 = async_results.capacity;
              D.20360 = (long unsigned int) D.20312;
              D.20384 = D.20360 * 16;
              __tmp = mono_gc_alloc_fixed (D.20384, D.20383);
              D.20312 = async_results.capacity;
              D.20360 = (long unsigned int) D.20312;
              D.20361 = D.20360 * 8;
              D.20315 = async_results.data;
              mono_gc_memmove_aligned (__tmp, D.20315, D.20361);
              D.20312 = async_results.capacity;
              if (D.20312 > 16) goto <D.20385>; else goto <D.20386>;
              <D.20385>:
              D.20315 = async_results.data;
              mono_gc_free_fixed (D.20315);
              <D.20386>:
              async_results.data = __tmp;
              D.20312 = async_results.capacity;
              D.20382 = D.20312 * 2;
              async_results.capacity = D.20382;
            }
            <D.20381>:
            D.20315 = async_results.data;
            D.20379 = async_results.size;
            D.20387 = D.20379;
            D.20388 = D.20387 + 1;
            async_results.size = D.20388;
            D.20389 = (long unsigned int) D.20387;
            D.20390 = D.20389 * 8;
            D.20391 = D.20315 + D.20390;
            *D.20391 = ares;
            nresults = nresults + 1;
            <D.20378>:
            <D.20376>:
            <D.20372>:
            list.51 = list;
            if (list.51 != 0B) goto <D.20392>; else goto <D.20393>;
            <D.20392>:
            D.20365 = pfd->revents;
            D.20373 = (int) D.20365;
            D.20394 = D.20373 & 60;
            if (D.20394 != 0) goto <D.20395>; else goto <D.20396>;
            <D.20395>:
            ares = get_io_event (&list, 4);
            if (ares != 0B) goto <D.20397>; else goto <D.20398>;
            <D.20397>:
            D.20379 = async_results.size;
            D.20312 = async_results.capacity;
            if (D.20379 >= D.20312) goto <D.20399>; else goto <D.20400>;
            <D.20399>:
            {
              void * __tmp;

              D.20312 = async_results.capacity;
              D.20382 = D.20312 * 2;
              D.20401 = mono_gc_make_root_descr_all_refs (D.20382);
              D.20312 = async_results.capacity;
              D.20360 = (long unsigned int) D.20312;
              D.20384 = D.20360 * 16;
              __tmp = mono_gc_alloc_fixed (D.20384, D.20401);
              D.20312 = async_results.capacity;
              D.20360 = (long unsigned int) D.20312;
              D.20361 = D.20360 * 8;
              D.20315 = async_results.data;
              mono_gc_memmove_aligned (__tmp, D.20315, D.20361);
              D.20312 = async_results.capacity;
              if (D.20312 > 16) goto <D.20402>; else goto <D.20403>;
              <D.20402>:
              D.20315 = async_results.data;
              mono_gc_free_fixed (D.20315);
              <D.20403>:
              async_results.data = __tmp;
              D.20312 = async_results.capacity;
              D.20382 = D.20312 * 2;
              async_results.capacity = D.20382;
            }
            <D.20400>:
            D.20315 = async_results.data;
            D.20379 = async_results.size;
            D.20404 = D.20379;
            D.20405 = D.20404 + 1;
            async_results.size = D.20405;
            D.20406 = (long unsigned int) D.20404;
            D.20407 = D.20406 * 8;
            D.20408 = D.20315 + D.20407;
            *D.20408 = ares;
            nresults = nresults + 1;
            <D.20398>:
            <D.20396>:
            <D.20393>:
            list.51 = list;
            if (list.51 != 0B) goto <D.20409>; else goto <D.20410>;
            <D.20409>:
            list.51 = list;
            D.20319 = pfd->fd;
            D.20366 = (long int) D.20319;
            D.20411 = (void *) D.20366;
            D.20368 = socket_io_data->sock_to_state;
            mono_g_hash_table_replace (D.20368, D.20411, list.51);
            list.51 = list;
            D.20412 = get_events_from_list (list.51);
            D.20413 = (short int) D.20412;
            pfd->events = D.20413;
            goto <D.20414>;
            <D.20410>:
            D.20319 = pfd->fd;
            D.20366 = (long int) D.20319;
            D.20367 = (const void *) D.20366;
            D.20368 = socket_io_data->sock_to_state;
            mono_g_hash_table_remove (D.20368, D.20367);
            pfd->fd = -1;
            D.20415 = maxfd + -1;
            if (D.20415 == i) goto <D.20416>; else goto <D.20417>;
            <D.20416>:
            maxfd = maxfd + -1;
            <D.20417>:
            <D.20414>:
            <D.18446>:
            i = i + 1;
            <D.18450>:
            D.20418 = i < maxfd;
            D.20419 = nsock > 0;
            D.20420 = D.20418 & D.20419;
            if (D.20420 != 0) goto <D.18449>; else goto <D.18451>;
            <D.18451>:
            {
              int ret;

              D.20340 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_unlock (D.20340);
              if (ret != 0) goto <D.20421>; else goto <D.20422>;
              <D.20421>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
              <D.20422>:
              D.20423 = ret != 0;
              D.20424 = (long int) D.20423;
              D.20425 = __builtin_expect (D.20424, 0);
              if (D.20425 != 0) goto <D.20426>; else goto <D.20427>;
              <D.20426>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 317, "ret == 0");
              <D.20427>:
            }
            D.20315 = async_results.data;
            threadpool_append_jobs (&async_io_tp, D.20315, nresults);
            async_results.size = 0;
            D.20312 = async_results.capacity;
            D.20360 = (long unsigned int) D.20312;
            D.20361 = D.20360 * 8;
            D.20315 = async_results.data;
            mono_gc_bzero_aligned (D.20315, D.20361);
          }
        finally
          {
            one = {CLOBBER};
            list = {CLOBBER};
          }
      }
      <D.18443>:
      goto <D.18453>;
    }
  finally
    {
      async_results = {CLOBBER};
    }
}


mark_bad_fds (struct mono_pollfd * pfds, int nfds)
{
  long unsigned int D.20433;
  long unsigned int D.20434;
  int D.20435;
  int * D.20441;
  int D.20442;
  short int D.20444;
  short int D.20445;
  int D.20448;
  int i;
  int ret;
  struct mono_pollfd * pfd;
  int count;

  count = 0;
  i = 0;
  goto <D.18408>;
  <D.18407>:
  D.20433 = (long unsigned int) i;
  D.20434 = D.20433 * 8;
  pfd = pfds + D.20434;
  D.20435 = pfd->fd;
  if (D.20435 == -1) goto <D.20436>; else goto <D.20437>;
  <D.20436>:
  // predicted unlikely by continue predictor.
  goto <D.18406>;
  <D.20437>:
  ret = mono_poll (pfd, 1, 0);
  if (ret == -1) goto <D.20440>; else goto <D.20438>;
  <D.20440>:
  D.20441 = __errno_location ();
  D.20442 = *D.20441;
  if (D.20442 == 9) goto <D.20443>; else goto <D.20438>;
  <D.20443>:
  D.20444 = pfd->revents;
  D.20445 = D.20444 | 32;
  pfd->revents = D.20445;
  count = count + 1;
  goto <D.20439>;
  <D.20438>:
  if (ret == 1) goto <D.20446>; else goto <D.20447>;
  <D.20446>:
  count = count + 1;
  <D.20447>:
  <D.20439>:
  <D.18406>:
  i = i + 1;
  <D.18408>:
  if (i < nfds) goto <D.18407>; else goto <D.18409>;
  <D.18409>:
  D.20448 = count;
  return D.20448;
}


socket_io_cleanup (struct SocketIOData * data)
{
  union mono_mutex_t * D.20450;
  _Bool D.20453;
  long int D.20454;
  long int D.20455;
  int D.20458;
  _Bool D.20463;
  long int D.20464;
  long int D.20465;
  void (*<Tbd4>) (void *) D.20468;
  void * D.20469;
  _Bool D.20472;
  long int D.20473;
  long int D.20474;

  {
    int ret;

    D.20450 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20450);
    if (ret != 0) goto <D.20451>; else goto <D.20452>;
    <D.20451>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20452>:
    D.20453 = ret != 0;
    D.20454 = (long int) D.20453;
    D.20455 = __builtin_expect (D.20454, 0);
    if (D.20455 != 0) goto <D.20456>; else goto <D.20457>;
    <D.20456>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 317, "ret == 0");
    <D.20457>:
  }
  D.20458 = data->inited;
  if (D.20458 != 2) goto <D.20459>; else goto <D.20460>;
  <D.20459>:
  {
    int ret;

    D.20450 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20450);
    if (ret != 0) goto <D.20461>; else goto <D.20462>;
    <D.20461>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20462>:
    D.20463 = ret != 0;
    D.20464 = (long int) D.20463;
    D.20465 = __builtin_expect (D.20464, 0);
    if (D.20465 != 0) goto <D.20466>; else goto <D.20467>;
    <D.20466>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 319, "ret == 0");
    <D.20467>:
  }
  return;
  <D.20460>:
  data->inited = 3;
  D.20468 = data->shutdown;
  D.20469 = data->event_data;
  D.20468 (D.20469);
  {
    int ret;

    D.20450 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20450);
    if (ret != 0) goto <D.20470>; else goto <D.20471>;
    <D.20470>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20471>:
    D.20472 = ret != 0;
    D.20473 = (long int) D.20472;
    D.20474 = __builtin_expect (D.20473, 0);
    if (D.20474 != 0) goto <D.20475>; else goto <D.20476>;
    <D.20475>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 324, "ret == 0");
    <D.20476>:
  }
}


read (int __fd, void * __buf, size_t __nbytes)
{
  long unsigned int D.20478;
  int D.20481;
  ssize_t D.20484;
  long unsigned int D.20485;
  long unsigned int D.20486;
  long unsigned int D.20489;

  D.20478 = __builtin_object_size (__buf, 0);
  if (D.20478 != 18446744073709551615) goto <D.20479>; else goto <D.20480>;
  <D.20479>:
  D.20481 = __builtin_constant_p (__nbytes);
  if (D.20481 == 0) goto <D.20482>; else goto <D.20483>;
  <D.20482>:
  D.20485 = __builtin_object_size (__buf, 0);
  D.20484 = __read_chk (__fd, __buf, __nbytes, D.20485);
  return D.20484;
  <D.20483>:
  D.20486 = __builtin_object_size (__buf, 0);
  if (D.20486 < __nbytes) goto <D.20487>; else goto <D.20488>;
  <D.20487>:
  D.20489 = __builtin_object_size (__buf, 0);
  D.20484 = __read_chk_warn (__fd, __buf, __nbytes, D.20489);
  return D.20484;
  <D.20488>:
  <D.20480>:
  D.20484 = __read_alias (__fd, __buf, __nbytes);
  return D.20484;
}


tp_poll_modify (void * p, int fd, int operation, int events, gboolean is_new)
{
  union mono_mutex_t * D.20491;
  _Bool D.20494;
  long int D.20495;
  long int D.20496;
  union MonoSemType * D.20499;
  short int D.20500;
  char D.20501;
  int D.20502;
  long int D.20503;
  struct SocketIOData * socket_io_data;
  struct tp_poll_data * data;
  char msg[1];
  int unused;

  try
    {
      socket_io_data = p;
      data = socket_io_data->event_data;
      {
        int ret;

        D.20491 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20491);
        if (ret != 0) goto <D.20492>; else goto <D.20493>;
        <D.20492>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20493>:
        D.20494 = ret != 0;
        D.20495 = (long int) D.20494;
        D.20496 = __builtin_expect (D.20495, 0);
        if (D.20496 != 0) goto <D.20497>; else goto <D.20498>;
        <D.20497>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 87, "ret == 0");
        <D.20498>:
      }
      D.20499 = &data->new_sem;
      mono_sem_wait (D.20499, 0);
      data->newpfd.fd = fd;
      D.20500 = (short int) events;
      data->newpfd.events = D.20500;
      data->newpfd.revents = 0;
      D.20501 = (char) operation;
      msg[0] = D.20501;
      D.20502 = data->pipe[1];
      D.20503 = write (D.20502, &msg, 1);
      unused = (int) D.20503;
    }
  finally
    {
      msg = {CLOBBER};
    }
}


tp_poll_shutdown (void * event_data)
{
  int D.20504;
  int D.20507;
  union MonoSemType * D.20510;
  struct tp_poll_data * data;

  data = event_data;
  D.20504 = data->pipe[0];
  if (D.20504 >= 0) goto <D.20505>; else goto <D.20506>;
  <D.20505>:
  D.20504 = data->pipe[0];
  close (D.20504);
  <D.20506>:
  D.20507 = data->pipe[1];
  if (D.20507 >= 0) goto <D.20508>; else goto <D.20509>;
  <D.20508>:
  D.20507 = data->pipe[1];
  close (D.20507);
  <D.20509>:
  data->pipe[0] = -1;
  data->pipe[1] = -1;
  D.20510 = &data->new_sem;
  sem_destroy (D.20510);
}


get_events_from_list (struct MonoMList * list)
{
  int D.20511;
  int D.20513;
  struct MonoSocketAsyncResult * state;
  int events;

  events = 0;
  goto <D.18684>;
  <D.18683>:
  D.20511 = get_event_from_state (state);
  events = D.20511 | events;
  list = mono_mlist_next (list);
  <D.18684>:
  if (list != 0B) goto <D.20512>; else goto <D.18685>;
  <D.20512>:
  state = mono_mlist_get_data (list);
  if (state != 0B) goto <D.18683>; else goto <D.18685>;
  <D.18685>:
  D.20513 = events;
  return D.20513;
}


mono_thread_pool_add (struct MonoObject * target, struct MonoMethodMessage * msg, struct MonoDelegate * async_callback, struct MonoObject * state)
{
  struct MonoClass * async_call_klass.52;
  struct MonoMethodMessage * * D.20516;
  struct MonoObject * * D.20517;
  struct MonoVTable * D.20520;
  struct MonoClass * D.20521;
  struct MonoMethod * D.20522;
  struct MonoDelegate * * D.20523;
  struct MonoObject * D.20524;
  struct MonoObject * * D.20525;
  int D.20526;
  struct MonoAsyncResult * D.20529;
  struct MonoDomain * domain;
  struct MonoAsyncResult * ares;
  struct ASyncCall * ac;

  domain = mono_domain_get ();
  async_call_klass.52 = async_call_klass;
  ac = mono_object_new (domain, async_call_klass.52);
  D.20516 = &ac->msg;
  mono_gc_wbarrier_set_field (ac, D.20516, msg);
  D.20517 = &ac->state;
  mono_gc_wbarrier_set_field (ac, D.20517, state);
  if (async_callback != 0B) goto <D.20518>; else goto <D.20519>;
  <D.20518>:
  D.20520 = MEM[(struct MonoObject *)async_callback].vtable;
  D.20521 = D.20520->klass;
  D.20522 = mono_get_delegate_invoke (D.20521);
  ac->cb_method = D.20522;
  D.20523 = &ac->cb_target;
  mono_gc_wbarrier_set_field (ac, D.20523, async_callback);
  <D.20519>:
  D.20524 = ac->state;
  ares = mono_async_result_new (domain, 0B, D.20524, 0B, ac);
  D.20525 = &ares->async_delegate;
  mono_gc_wbarrier_set_field (ares, D.20525, target);
  D.20526 = socket_io_filter (target, state);
  if (D.20526 != 0) goto <D.20527>; else goto <D.20528>;
  <D.20527>:
  socket_io_add (ares, state);
  D.20529 = ares;
  return D.20529;
  <D.20528>:
  threadpool_append_job (&async_tp, ares);
  D.20529 = ares;
  return D.20529;
}


socket_io_filter (struct MonoObject * target, struct MonoObject * state)
{
  _Bool D.20531;
  _Bool D.20532;
  _Bool D.20533;
  gboolean D.20536;
  struct MonoVTable * D.20537;
  struct MonoClass * socket_async_call_klass.53;
  int D.20541;
  struct MonoClass * process_async_call_klass.54;
  int D.20547;
  unsigned int op.55;
  gint op;
  struct MonoSocketAsyncResult * sock_res;
  struct MonoClass * klass;
  struct MonoDomain * domain;

  D.20531 = target == 0B;
  D.20532 = state == 0B;
  D.20533 = D.20531 | D.20532;
  if (D.20533 != 0) goto <D.20534>; else goto <D.20535>;
  <D.20534>:
  D.20536 = 0;
  return D.20536;
  <D.20535>:
  D.20537 = target->vtable;
  domain = D.20537->domain;
  D.20537 = target->vtable;
  klass = D.20537->klass;
  socket_async_call_klass.53 = socket_async_call_klass;
  if (socket_async_call_klass.53 == 0B) goto <D.20539>; else goto <D.20540>;
  <D.20539>:
  D.20541 = is_socketasynccall (domain, klass);
  if (D.20541 != 0) goto <D.20542>; else goto <D.20543>;
  <D.20542>:
  socket_async_call_klass = klass;
  <D.20543>:
  <D.20540>:
  process_async_call_klass.54 = process_async_call_klass;
  if (process_async_call_klass.54 == 0B) goto <D.20545>; else goto <D.20546>;
  <D.20545>:
  D.20547 = is_sdp_asyncreadhandler (domain, klass);
  if (D.20547 != 0) goto <D.20548>; else goto <D.20549>;
  <D.20548>:
  process_async_call_klass = klass;
  <D.20549>:
  <D.20546>:
  socket_async_call_klass.53 = socket_async_call_klass;
  if (klass != socket_async_call_klass.53) goto <D.20550>; else goto <D.20551>;
  <D.20550>:
  process_async_call_klass.54 = process_async_call_klass;
  if (klass != process_async_call_klass.54) goto <D.20552>; else goto <D.20553>;
  <D.20552>:
  D.20536 = 0;
  return D.20536;
  <D.20553>:
  <D.20551>:
  sock_res = state;
  op = sock_res->operation;
  op.55 = (unsigned int) op;
  if (op.55 > 13) goto <D.20555>; else goto <D.20556>;
  <D.20555>:
  D.20536 = 0;
  return D.20536;
  <D.20556>:
  D.20536 = 1;
  return D.20536;
}


is_socketasynccall (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.20558;
  int iftmp.56;
  struct MonoClass * D.20562;
  int D.20564;
  int D.18597;
  int iftmp.57;
  int D.18596;
  const char[16] * D.20569;
  unsigned char D.20570;
  int D.20571;
  unsigned char D.20572;
  int D.20573;
  _Bool D.20574;
  _Bool D.20575;
  _Bool D.20576;
  const unsigned char * D.20579;
  unsigned char D.20580;
  int D.20581;
  const unsigned char * D.20582;
  unsigned char D.20583;
  int D.20584;
  _Bool D.20585;
  _Bool D.20586;
  const unsigned char * D.20589;
  unsigned char D.20590;
  int D.20591;
  const unsigned char * D.20592;
  unsigned char D.20593;
  int D.20594;
  _Bool D.20595;
  _Bool D.20596;
  const unsigned char * D.20599;
  unsigned char D.20600;
  int D.20601;
  const unsigned char * D.20602;
  unsigned char D.20603;
  int D.20604;
  const char * D.20606;

  D.20562 = klass->nested_in;
  if (D.20562 != 0B) goto <D.20563>; else goto <D.20560>;
  <D.20563>:
  D.20562 = klass->nested_in;
  D.20564 = is_socket (domain, D.20562);
  if (D.20564 != 0) goto <D.20565>; else goto <D.20560>;
  <D.20565>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 15;
    if (__s2_len <= 3) goto <D.20567>; else goto <D.20568>;
    <D.20567>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.20569 = "SocketAsyncCall";
      D.20570 = MEM[(const unsigned char *)D.20569];
      D.20571 = (int) D.20570;
      D.20572 = *__s2;
      D.20573 = (int) D.20572;
      __result = D.20571 - D.20573;
      {
        D.20574 = __s2_len != 0;
        D.20575 = __result == 0;
        D.20576 = D.20574 & D.20575;
        if (D.20576 != 0) goto <D.20577>; else goto <D.20578>;
        <D.20577>:
        D.20579 = &MEM[(void *)"SocketAsyncCall" + 1B];
        D.20580 = *D.20579;
        D.20581 = (int) D.20580;
        D.20582 = __s2 + 1;
        D.20583 = *D.20582;
        D.20584 = (int) D.20583;
        __result = D.20581 - D.20584;
        D.20585 = __s2_len > 1;
        D.20575 = __result == 0;
        D.20586 = D.20585 & D.20575;
        if (D.20586 != 0) goto <D.20587>; else goto <D.20588>;
        <D.20587>:
        D.20589 = &MEM[(void *)"SocketAsyncCall" + 2B];
        D.20590 = *D.20589;
        D.20591 = (int) D.20590;
        D.20592 = __s2 + 2;
        D.20593 = *D.20592;
        D.20594 = (int) D.20593;
        __result = D.20591 - D.20594;
        D.20595 = __s2_len > 2;
        D.20575 = __result == 0;
        D.20596 = D.20595 & D.20575;
        if (D.20596 != 0) goto <D.20597>; else goto <D.20598>;
        <D.20597>:
        D.20599 = &MEM[(void *)"SocketAsyncCall" + 3B];
        D.20600 = *D.20599;
        D.20601 = (int) D.20600;
        D.20602 = __s2 + 3;
        D.20603 = *D.20602;
        D.20604 = (int) D.20603;
        __result = D.20601 - D.20604;
        <D.20598>:
        <D.20588>:
        <D.20578>:
      }
      D.18596 = __result;
    }
    iftmp.57 = -D.18596;
    goto <D.20605>;
    <D.20568>:
    D.20606 = klass->name;
    iftmp.57 = __builtin_strcmp (D.20606, "SocketAsyncCall");
    <D.20605>:
    D.18597 = iftmp.57;
  }
  if (D.18597 == 0) goto <D.20607>; else goto <D.20560>;
  <D.20607>:
  iftmp.56 = 1;
  goto <D.20561>;
  <D.20560>:
  iftmp.56 = 0;
  <D.20561>:
  D.20558 = iftmp.56;
  return D.20558;
}


is_sdp_asyncreadhandler (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.20609;
  int iftmp.58;
  struct MonoClass * D.20613;
  int D.20615;
  int D.18654;
  int iftmp.59;
  int D.18653;
  const char[17] * D.20620;
  unsigned char D.20621;
  int D.20622;
  unsigned char D.20623;
  int D.20624;
  _Bool D.20625;
  _Bool D.20626;
  _Bool D.20627;
  const unsigned char * D.20630;
  unsigned char D.20631;
  int D.20632;
  const unsigned char * D.20633;
  unsigned char D.20634;
  int D.20635;
  _Bool D.20636;
  _Bool D.20637;
  const unsigned char * D.20640;
  unsigned char D.20641;
  int D.20642;
  const unsigned char * D.20643;
  unsigned char D.20644;
  int D.20645;
  _Bool D.20646;
  _Bool D.20647;
  const unsigned char * D.20650;
  unsigned char D.20651;
  int D.20652;
  const unsigned char * D.20653;
  unsigned char D.20654;
  int D.20655;
  const char * D.20657;

  D.20613 = klass->nested_in;
  if (D.20613 != 0B) goto <D.20614>; else goto <D.20611>;
  <D.20614>:
  D.20613 = klass->nested_in;
  D.20615 = is_sd_process (domain, D.20613);
  if (D.20615 != 0) goto <D.20616>; else goto <D.20611>;
  <D.20616>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 16;
    if (__s2_len <= 3) goto <D.20618>; else goto <D.20619>;
    <D.20618>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.20620 = "AsyncReadHandler";
      D.20621 = MEM[(const unsigned char *)D.20620];
      D.20622 = (int) D.20621;
      D.20623 = *__s2;
      D.20624 = (int) D.20623;
      __result = D.20622 - D.20624;
      {
        D.20625 = __s2_len != 0;
        D.20626 = __result == 0;
        D.20627 = D.20625 & D.20626;
        if (D.20627 != 0) goto <D.20628>; else goto <D.20629>;
        <D.20628>:
        D.20630 = &MEM[(void *)"AsyncReadHandler" + 1B];
        D.20631 = *D.20630;
        D.20632 = (int) D.20631;
        D.20633 = __s2 + 1;
        D.20634 = *D.20633;
        D.20635 = (int) D.20634;
        __result = D.20632 - D.20635;
        D.20636 = __s2_len > 1;
        D.20626 = __result == 0;
        D.20637 = D.20636 & D.20626;
        if (D.20637 != 0) goto <D.20638>; else goto <D.20639>;
        <D.20638>:
        D.20640 = &MEM[(void *)"AsyncReadHandler" + 2B];
        D.20641 = *D.20640;
        D.20642 = (int) D.20641;
        D.20643 = __s2 + 2;
        D.20644 = *D.20643;
        D.20645 = (int) D.20644;
        __result = D.20642 - D.20645;
        D.20646 = __s2_len > 2;
        D.20626 = __result == 0;
        D.20647 = D.20646 & D.20626;
        if (D.20647 != 0) goto <D.20648>; else goto <D.20649>;
        <D.20648>:
        D.20650 = &MEM[(void *)"AsyncReadHandler" + 3B];
        D.20651 = *D.20650;
        D.20652 = (int) D.20651;
        D.20653 = __s2 + 3;
        D.20654 = *D.20653;
        D.20655 = (int) D.20654;
        __result = D.20652 - D.20655;
        <D.20649>:
        <D.20639>:
        <D.20629>:
      }
      D.18653 = __result;
    }
    iftmp.59 = -D.18653;
    goto <D.20656>;
    <D.20619>:
    D.20657 = klass->name;
    iftmp.59 = __builtin_strcmp (D.20657, "AsyncReadHandler");
    <D.20656>:
    D.18654 = iftmp.59;
  }
  if (D.18654 == 0) goto <D.20658>; else goto <D.20611>;
  <D.20658>:
  iftmp.58 = 1;
  goto <D.20612>;
  <D.20611>:
  iftmp.58 = 0;
  <D.20612>:
  D.20609 = iftmp.58;
  return D.20609;
}


is_sd_process (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.20660;
  gboolean D.20663;
  _Bool D.20664;
  int D.20665;
  int D.18632;
  int iftmp.60;
  int D.18628;
  const char[8] * D.20671;
  unsigned char D.20672;
  int D.20673;
  unsigned char D.20674;
  int D.20675;
  _Bool D.20676;
  _Bool D.20677;
  _Bool D.20678;
  const unsigned char * D.20681;
  unsigned char D.20682;
  int D.20683;
  const unsigned char * D.20684;
  unsigned char D.20685;
  int D.20686;
  _Bool D.20687;
  _Bool D.20688;
  const unsigned char * D.20691;
  unsigned char D.20692;
  int D.20693;
  const unsigned char * D.20694;
  unsigned char D.20695;
  int D.20696;
  _Bool D.20697;
  _Bool D.20698;
  const unsigned char * D.20701;
  unsigned char D.20702;
  int D.20703;
  const unsigned char * D.20704;
  unsigned char D.20705;
  int D.20706;
  const char * D.20708;
  int D.18641;
  int iftmp.61;
  int D.18637;
  const char[19] * D.20714;
  unsigned char D.20715;
  int D.20716;
  unsigned char D.20717;
  int D.20718;
  _Bool D.20719;
  _Bool D.20720;
  _Bool D.20721;
  const unsigned char * D.20724;
  unsigned char D.20725;
  int D.20726;
  const unsigned char * D.20727;
  unsigned char D.20728;
  int D.20729;
  _Bool D.20730;
  _Bool D.20731;
  const unsigned char * D.20734;
  unsigned char D.20735;
  int D.20736;
  const unsigned char * D.20737;
  unsigned char D.20738;
  int D.20739;
  _Bool D.20740;
  _Bool D.20741;
  const unsigned char * D.20744;
  unsigned char D.20745;
  int D.20746;
  const unsigned char * D.20747;
  unsigned char D.20748;
  int D.20749;
  const char * D.20751;

  D.20660 = domain->process_class;
  if (D.20660 != 0B) goto <D.20661>; else goto <D.20662>;
  <D.20661>:
  D.20660 = domain->process_class;
  D.20664 = D.20660 == klass;
  D.20663 = (gboolean) D.20664;
  return D.20663;
  <D.20662>:
  D.20665 = is_system_type (domain, klass);
  if (D.20665 != 0) goto <D.20666>; else goto <D.20667>;
  <D.20666>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 7;
    if (__s1_len <= 3) goto <D.20669>; else goto <D.20670>;
    <D.20669>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.20671 = "Process";
      D.20672 = MEM[(const unsigned char *)D.20671];
      D.20673 = (int) D.20672;
      D.20674 = *__s2;
      D.20675 = (int) D.20674;
      __result = D.20673 - D.20675;
      {
        D.20676 = __s1_len != 0;
        D.20677 = __result == 0;
        D.20678 = D.20676 & D.20677;
        if (D.20678 != 0) goto <D.20679>; else goto <D.20680>;
        <D.20679>:
        D.20681 = &MEM[(void *)"Process" + 1B];
        D.20682 = *D.20681;
        D.20683 = (int) D.20682;
        D.20684 = __s2 + 1;
        D.20685 = *D.20684;
        D.20686 = (int) D.20685;
        __result = D.20683 - D.20686;
        D.20687 = __s1_len > 1;
        D.20677 = __result == 0;
        D.20688 = D.20687 & D.20677;
        if (D.20688 != 0) goto <D.20689>; else goto <D.20690>;
        <D.20689>:
        D.20691 = &MEM[(void *)"Process" + 2B];
        D.20692 = *D.20691;
        D.20693 = (int) D.20692;
        D.20694 = __s2 + 2;
        D.20695 = *D.20694;
        D.20696 = (int) D.20695;
        __result = D.20693 - D.20696;
        D.20697 = __s1_len > 2;
        D.20677 = __result == 0;
        D.20698 = D.20697 & D.20677;
        if (D.20698 != 0) goto <D.20699>; else goto <D.20700>;
        <D.20699>:
        D.20701 = &MEM[(void *)"Process" + 3B];
        D.20702 = *D.20701;
        D.20703 = (int) D.20702;
        D.20704 = __s2 + 3;
        D.20705 = *D.20704;
        D.20706 = (int) D.20705;
        __result = D.20703 - D.20706;
        <D.20700>:
        <D.20690>:
        <D.20680>:
      }
      D.18628 = __result;
    }
    iftmp.60 = D.18628;
    goto <D.20707>;
    <D.20670>:
    D.20708 = klass->name;
    iftmp.60 = __builtin_strcmp ("Process", D.20708);
    <D.20707>:
    D.18632 = iftmp.60;
  }
  if (D.18632 == 0) goto <D.20709>; else goto <D.20710>;
  <D.20709>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 18;
    if (__s1_len <= 3) goto <D.20712>; else goto <D.20713>;
    <D.20712>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name_space;
      D.20714 = "System.Diagnostics";
      D.20715 = MEM[(const unsigned char *)D.20714];
      D.20716 = (int) D.20715;
      D.20717 = *__s2;
      D.20718 = (int) D.20717;
      __result = D.20716 - D.20718;
      {
        D.20719 = __s1_len != 0;
        D.20720 = __result == 0;
        D.20721 = D.20719 & D.20720;
        if (D.20721 != 0) goto <D.20722>; else goto <D.20723>;
        <D.20722>:
        D.20724 = &MEM[(void *)"System.Diagnostics" + 1B];
        D.20725 = *D.20724;
        D.20726 = (int) D.20725;
        D.20727 = __s2 + 1;
        D.20728 = *D.20727;
        D.20729 = (int) D.20728;
        __result = D.20726 - D.20729;
        D.20730 = __s1_len > 1;
        D.20720 = __result == 0;
        D.20731 = D.20730 & D.20720;
        if (D.20731 != 0) goto <D.20732>; else goto <D.20733>;
        <D.20732>:
        D.20734 = &MEM[(void *)"System.Diagnostics" + 2B];
        D.20735 = *D.20734;
        D.20736 = (int) D.20735;
        D.20737 = __s2 + 2;
        D.20738 = *D.20737;
        D.20739 = (int) D.20738;
        __result = D.20736 - D.20739;
        D.20740 = __s1_len > 2;
        D.20720 = __result == 0;
        D.20741 = D.20740 & D.20720;
        if (D.20741 != 0) goto <D.20742>; else goto <D.20743>;
        <D.20742>:
        D.20744 = &MEM[(void *)"System.Diagnostics" + 3B];
        D.20745 = *D.20744;
        D.20746 = (int) D.20745;
        D.20747 = __s2 + 3;
        D.20748 = *D.20747;
        D.20749 = (int) D.20748;
        __result = D.20746 - D.20749;
        <D.20743>:
        <D.20733>:
        <D.20723>:
      }
      D.18637 = __result;
    }
    iftmp.61 = D.18637;
    goto <D.20750>;
    <D.20713>:
    D.20751 = klass->name_space;
    iftmp.61 = __builtin_strcmp ("System.Diagnostics", D.20751);
    <D.20750>:
    D.18641 = iftmp.61;
  }
  if (D.18641 == 0) goto <D.20752>; else goto <D.20753>;
  <D.20752>:
  domain->process_class = klass;
  D.20663 = 1;
  return D.20663;
  <D.20753>:
  <D.20710>:
  <D.20667>:
  D.20663 = 0;
  return D.20663;
}


mono_thread_pool_finish (struct MonoAsyncResult * ares, struct MonoArray * * out_args, struct MonoObject * * exc)
{
  unsigned char D.20755;
  struct MonoException * D.20758;
  struct MonoObject * D.20759;
  unsigned char D.20760;
  struct MonoObject * D.20763;
  _Bool D.20766;
  long int D.20767;
  long int D.20768;
  struct MonoVTable * D.20771;
  struct MonoDomain * D.20772;
  struct MonoWaitHandle * D.20773;
  struct MonoObject * * D.20774;
  _Bool D.20777;
  long int D.20778;
  long int D.20779;
  struct MonoMethodMessage * D.20782;
  struct MonoObject * D.20783;
  struct MonoArray * D.20784;
  struct ASyncCall * ac;
  void * wait_event;

  *exc = 0B;
  *out_args = 0B;
  mono_monitor_enter (ares);
  D.20755 = ares->endinvoke_called;
  if (D.20755 != 0) goto <D.20756>; else goto <D.20757>;
  <D.20756>:
  D.20758 = mono_get_exception_invalid_operation (0B);
  *exc = D.20758;
  mono_monitor_exit (ares);
  D.20759 = 0B;
  return D.20759;
  <D.20757>:
  ares->endinvoke_called = 1;
  D.20760 = ares->completed;
  if (D.20760 == 0) goto <D.20761>; else goto <D.20762>;
  <D.20761>:
  D.20763 = ares->handle;
  if (D.20763 == 0B) goto <D.20764>; else goto <D.20765>;
  <D.20764>:
  wait_event = CreateEvent (0B, 1, 0, 0B);
  D.20766 = wait_event == 0B;
  D.20767 = (long int) D.20766;
  D.20768 = __builtin_expect (D.20767, 0);
  if (D.20768 != 0) goto <D.20769>; else goto <D.20770>;
  <D.20769>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 958, "wait_event != 0");
  <D.20770>:
  D.20771 = MEM[(struct MonoObject *)ares].vtable;
  D.20772 = D.20771->domain;
  D.20773 = mono_wait_handle_new (D.20772, wait_event);
  D.20774 = &ares->handle;
  mono_gc_wbarrier_set_field (ares, D.20774, D.20773);
  goto <D.20775>;
  <D.20765>:
  D.20763 = ares->handle;
  wait_event = mono_wait_handle_get_handle (D.20763);
  <D.20775>:
  mono_monitor_exit (ares);
  WaitForSingleObjectEx (wait_event, 4294967295, 1);
  goto <D.20776>;
  <D.20762>:
  mono_monitor_exit (ares);
  <D.20776>:
  ac = ares->object_data;
  D.20777 = ac == 0B;
  D.20778 = (long int) D.20777;
  D.20779 = __builtin_expect (D.20778, 0);
  if (D.20779 != 0) goto <D.20780>; else goto <D.20781>;
  <D.20780>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 970, "ac != NULL");
  <D.20781>:
  D.20782 = ac->msg;
  D.20783 = D.20782->exc;
  *exc = D.20783;
  D.20784 = ac->out_args;
  *out_args = D.20784;
  D.20759 = ac->res;
  return D.20759;
}


mono_thread_pool_cleanup ()
{
  int D.20786;
  struct MonoCQ * D.20789;
  int D.20792;
  struct GPtrArray * wsqs.62;
  _Bool D.20800;
  long int D.20801;
  long int D.20802;
  _Bool D.20809;
  long int D.20810;
  long int D.20811;

  D.20786 = InterlockedExchange (&async_io_tp.pool_status, 2);
  if (D.20786 == 1) goto <D.20787>; else goto <D.20788>;
  <D.20787>:
  socket_io_cleanup (&socket_io_data);
  threadpool_kill_idle_threads (&async_io_tp);
  <D.20788>:
  D.20789 = async_io_tp.queue;
  if (D.20789 != 0B) goto <D.20790>; else goto <D.20791>;
  <D.20790>:
  sem_destroy (&async_io_tp.new_job);
  threadpool_free_queue (&async_io_tp);
  <D.20791>:
  D.20792 = InterlockedExchange (&async_tp.pool_status, 2);
  if (D.20792 == 1) goto <D.20793>; else goto <D.20794>;
  <D.20793>:
  threadpool_kill_idle_threads (&async_tp);
  threadpool_free_queue (&async_tp);
  <D.20794>:
  wsqs.62 = wsqs;
  if (wsqs.62 != 0B) goto <D.20796>; else goto <D.20797>;
  <D.20796>:
  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20798>; else goto <D.20799>;
    <D.20798>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20799>:
    D.20800 = ret != 0;
    D.20801 = (long int) D.20800;
    D.20802 = __builtin_expect (D.20801, 0);
    if (D.20802 != 0) goto <D.20803>; else goto <D.20804>;
    <D.20803>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1009, "ret == 0");
    <D.20804>:
  }
  mono_wsq_cleanup ();
  wsqs.62 = wsqs;
  if (wsqs.62 != 0B) goto <D.20805>; else goto <D.20806>;
  <D.20805>:
  wsqs.62 = wsqs;
  monoeg_g_ptr_array_free (wsqs.62, 1);
  <D.20806>:
  wsqs = 0B;
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20807>; else goto <D.20808>;
    <D.20807>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20808>:
    D.20809 = ret != 0;
    D.20810 = (long int) D.20809;
    D.20811 = __builtin_expect (D.20810, 0);
    if (D.20811 != 0) goto <D.20812>; else goto <D.20813>;
    <D.20812>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1014, "ret == 0");
    <D.20813>:
  }
  sem_destroy (&async_tp.new_job);
  <D.20797>:
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int new_val.63;
  unsigned int old_val.64;
  unsigned int D.20816;
  int D.20817;
  gint32 D.20818;
  gint32 old_val;

  <D.17307>:
  old_val = *val;
  new_val.63 = (unsigned int) new_val;
  old_val.64 = (unsigned int) old_val;
  D.20816 = __sync_val_compare_and_swap_4 (val, old_val.64, new_val.63);
  D.20817 = (int) D.20816;
  if (D.20817 != old_val) goto <D.17307>; else goto <D.17308>;
  <D.17308>:
  D.20818 = old_val;
  return D.20818;
}


threadpool_kill_idle_threads (struct ThreadPool * tp)
{
  volatile gint * D.20820;
  union MonoSemType * D.20821;
  gint n;

  D.20820 = &tp->max_threads;
  n = InterlockedCompareExchange (D.20820, 0, -1);
  goto <D.18851>;
  <D.18850>:
  n = n + -1;
  D.20821 = &tp->new_job;
  mono_sem_post (D.20821);
  <D.18851>:
  if (n != 0) goto <D.18850>; else goto <D.18852>;
  <D.18852>:
}


threadpool_free_queue (struct ThreadPool * tp)
{
  struct MonoCQ * D.20822;

  D.20822 = tp->queue;
  mono_cq_destroy (D.20822);
  tp->queue = 0B;
}


icall_append_job (struct MonoObject * ar)
{
  threadpool_append_jobs (&async_tp, &ar, 1);
}


mono_thread_pool_remove_domain_jobs (struct MonoDomain * domain, int timeout)
{
  unsigned int D.20823;
  _Bool D.20824;
  long int D.20825;
  long int D.20826;
  _Bool D.20831;
  long int D.20832;
  long int D.20833;
  struct MonoGHashTable * D.20836;
  _Bool D.20841;
  long int D.20842;
  long int D.20843;
  int D.20846;
  unsigned int timeout.65;
  unsigned int D.20854;
  unsigned int D.20855;
  int D.20858;
  gboolean D.20859;
  void * sem_handle;
  int result;
  guint32 start_time;

  result = 1;
  start_time = 0;
  D.20823 = domain->state;
  D.20824 = D.20823 != 2;
  D.20825 = (long int) D.20824;
  D.20826 = __builtin_expect (D.20825, 0);
  if (D.20826 != 0) goto <D.20827>; else goto <D.20828>;
  <D.20827>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1159, "domain->state == MONO_APPDOMAIN_UNLOADING");
  <D.20828>:
  threadpool_clear_queue (&async_tp, domain);
  threadpool_clear_queue (&async_io_tp, domain);
  {
    int ret;

    ret = pthread_mutex_lock (&socket_io_data.io_lock.mutex);
    if (ret != 0) goto <D.20829>; else goto <D.20830>;
    <D.20829>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20830>:
    D.20831 = ret != 0;
    D.20832 = (long int) D.20831;
    D.20833 = __builtin_expect (D.20832, 0);
    if (D.20833 != 0) goto <D.20834>; else goto <D.20835>;
    <D.20834>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1164, "ret == 0");
    <D.20835>:
  }
  D.20836 = socket_io_data.sock_to_state;
  if (D.20836 != 0B) goto <D.20837>; else goto <D.20838>;
  <D.20837>:
  D.20836 = socket_io_data.sock_to_state;
  mono_g_hash_table_foreach_remove (D.20836, remove_sockstate_for_domain, domain);
  <D.20838>:
  {
    int ret;

    ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
    if (ret != 0) goto <D.20839>; else goto <D.20840>;
    <D.20839>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20840>:
    D.20841 = ret != 0;
    D.20842 = (long int) D.20841;
    D.20843 = __builtin_expect (D.20842, 0);
    if (D.20843 != 0) goto <D.20844>; else goto <D.20845>;
    <D.20844>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1168, "ret == 0");
    <D.20845>:
  }
  sem_handle = CreateSemaphore (0B, 0, 1, 0B);
  domain->cleanup_semaphore = sem_handle;
  mono_memory_write_barrier ();
  D.20846 = domain->threadpool_jobs;
  if (D.20846 != 0) goto <D.20847>; else goto <D.20848>;
  <D.20847>:
  if (timeout != -1) goto <D.20849>; else goto <D.20850>;
  <D.20849>:
  start_time = mono_msec_ticks ();
  <D.20850>:
  <D.20848>:
  goto <D.18927>;
  <D.18926>:
  timeout.65 = (unsigned int) timeout;
  WaitForSingleObject (sem_handle, timeout.65);
  if (timeout != -1) goto <D.20852>; else goto <D.20853>;
  <D.20852>:
  D.20854 = mono_msec_ticks ();
  D.20855 = D.20854 - start_time;
  timeout.65 = (unsigned int) timeout;
  if (D.20855 > timeout.65) goto <D.20856>; else goto <D.20857>;
  <D.20856>:
  result = 0;
  goto <D.18925>;
  <D.20857>:
  <D.20853>:
  <D.18927>:
  D.20858 = domain->threadpool_jobs;
  if (D.20858 != 0) goto <D.18926>; else goto <D.18925>;
  <D.18925>:
  domain->cleanup_semaphore = 0B;
  CloseHandle (sem_handle);
  D.20859 = result;
  return D.20859;
}


remove_sockstate_for_domain (void * key, void * value, void * user_data)
{
  struct MonoVTable * D.20861;
  struct MonoDomain * D.20862;
  gboolean D.20865;
  struct MonoMList * list;
  gboolean remove;

  list = value;
  remove = 0;
  goto <D.18914>;
  <D.18913>:
  {
    struct MonoObject * data;

    data = mono_mlist_get_data (list);
    D.20861 = data->vtable;
    D.20862 = D.20861->domain;
    if (D.20862 == user_data) goto <D.20863>; else goto <D.20864>;
    <D.20863>:
    remove = 1;
    mono_mlist_set_data (list, 0B);
    <D.20864>:
    list = mono_mlist_next (list);
  }
  <D.18914>:
  if (list != 0B) goto <D.18913>; else goto <D.18915>;
  <D.18915>:
  D.20865 = remove;
  return D.20865;
}


threadpool_clear_queue (struct ThreadPool * tp, struct MonoDomain * domain)
{
  struct MonoObject * obj.66;
  struct MonoVTable * D.20872;
  struct MonoDomain * D.20873;
  int D.20876;
  int D.20877;
  struct MonoObject * D.20880;
  struct MonoObject * obj;
  struct MonoMList * other;
  struct MonoCQ * queue;

  try
    {
      other = 0B;
      queue = tp->queue;
      if (queue == 0B) goto <D.20867>; else goto <D.20868>;
      <D.20867>:
      return;
      <D.20868>:
      goto <D.18899>;
      <D.18900>:
      obj.66 = obj;
      if (obj.66 == 0B) goto <D.20870>; else goto <D.20871>;
      <D.20870>:
      // predicted unlikely by continue predictor.
      goto <D.18899>;
      <D.20871>:
      obj.66 = obj;
      D.20872 = obj.66->vtable;
      D.20873 = D.20872->domain;
      if (D.20873 != domain) goto <D.20874>; else goto <D.20875>;
      <D.20874>:
      obj.66 = obj;
      other = mono_mlist_prepend (other, obj.66);
      <D.20875>:
      obj.66 = obj;
      threadpool_jobs_dec (obj.66);
      <D.18899>:
      D.20876 = mono_cq_dequeue (queue, &obj);
      if (D.20876 != 0) goto <D.18900>; else goto <D.18901>;
      <D.18901>:
      D.20877 = mono_runtime_is_shutting_down ();
      if (D.20877 != 0) goto <D.20878>; else goto <D.20879>;
      <D.20878>:
      return;
      <D.20879>:
      goto <D.18903>;
      <D.18902>:
      D.20880 = mono_mlist_get_data (other);
      threadpool_append_job (tp, D.20880);
      other = mono_mlist_next (other);
      <D.18903>:
      if (other != 0B) goto <D.18902>; else goto <D.18904>;
      <D.18904>:
    }
  finally
    {
      obj = {CLOBBER};
    }
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_thread_pool_is_queue_array (struct MonoArray * o)
{
  gboolean D.20884;

  D.20884 = 0;
  return D.20884;
}


ves_icall_System_Threading_ThreadPool_GetAvailableThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.20886;
  int D.20887;
  int D.20888;
  int D.20889;
  int D.20890;
  int D.20891;

  D.20886 = async_tp.max_threads;
  D.20887 = async_tp.busy_threads;
  D.20888 = D.20886 - D.20887;
  *workerThreads = D.20888;
  D.20889 = async_io_tp.max_threads;
  D.20890 = async_io_tp.busy_threads;
  D.20891 = D.20889 - D.20890;
  *completionPortThreads = D.20891;
}


ves_icall_System_Threading_ThreadPool_GetMaxThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.20892;
  int D.20893;

  D.20892 = async_tp.max_threads;
  *workerThreads = D.20892;
  D.20893 = async_io_tp.max_threads;
  *completionPortThreads = D.20893;
}


ves_icall_System_Threading_ThreadPool_GetMinThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.20894;
  int D.20895;

  D.20894 = async_tp.min_threads;
  *workerThreads = D.20894;
  D.20895 = async_io_tp.min_threads;
  *completionPortThreads = D.20895;
}


ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, gint completionPortThreads)
{
  _Bool D.20896;
  _Bool D.20897;
  _Bool D.20898;
  MonoBoolean D.20901;
  _Bool D.20902;
  _Bool D.20903;
  _Bool D.20904;
  int D.20907;
  struct MonoDomain * D.20910;
  int D.20911;
  struct MonoDomain * D.20914;
  gint max_threads;
  gint max_io_threads;

  max_threads = async_tp.max_threads;
  D.20896 = workerThreads <= 0;
  D.20897 = workerThreads > max_threads;
  D.20898 = D.20896 | D.20897;
  if (D.20898 != 0) goto <D.20899>; else goto <D.20900>;
  <D.20899>:
  D.20901 = 0;
  return D.20901;
  <D.20900>:
  max_io_threads = async_io_tp.max_threads;
  D.20902 = completionPortThreads <= 0;
  D.20903 = completionPortThreads > max_io_threads;
  D.20904 = D.20902 | D.20903;
  if (D.20904 != 0) goto <D.20905>; else goto <D.20906>;
  <D.20905>:
  D.20901 = 0;
  return D.20901;
  <D.20906>:
  InterlockedExchange (&async_tp.min_threads, workerThreads);
  InterlockedExchange (&async_io_tp.min_threads, completionPortThreads);
  D.20907 = async_tp.nthreads;
  if (D.20907 < workerThreads) goto <D.20908>; else goto <D.20909>;
  <D.20908>:
  D.20910 = mono_get_root_domain ();
  mono_thread_create_internal (D.20910, threadpool_start_idle_threads, &async_tp, 1, 0, 262144);
  <D.20909>:
  D.20911 = async_io_tp.nthreads;
  if (D.20911 < completionPortThreads) goto <D.20912>; else goto <D.20913>;
  <D.20912>:
  D.20914 = mono_get_root_domain ();
  mono_thread_create_internal (D.20914, threadpool_start_idle_threads, &async_io_tp, 1, 0, 262144);
  <D.20913>:
  D.20901 = 1;
  return D.20901;
}


ves_icall_System_Threading_ThreadPool_SetMaxThreads (gint workerThreads, gint completionPortThreads)
{
  _Bool D.20916;
  _Bool D.20917;
  _Bool D.20918;
  MonoBoolean D.20921;
  _Bool D.20922;
  _Bool D.20923;
  _Bool D.20924;
  gint min_threads;
  gint min_io_threads;
  gint cpu_count;

  cpu_count = mono_cpu_count ();
  min_threads = async_tp.min_threads;
  D.20916 = workerThreads < min_threads;
  D.20917 = workerThreads < cpu_count;
  D.20918 = D.20916 | D.20917;
  if (D.20918 != 0) goto <D.20919>; else goto <D.20920>;
  <D.20919>:
  D.20921 = 0;
  return D.20921;
  <D.20920>:
  min_io_threads = async_io_tp.min_threads;
  D.20922 = completionPortThreads < min_io_threads;
  D.20923 = completionPortThreads < cpu_count;
  D.20924 = D.20922 | D.20923;
  if (D.20924 != 0) goto <D.20925>; else goto <D.20926>;
  <D.20925>:
  D.20921 = 0;
  return D.20921;
  <D.20926>:
  InterlockedExchange (&async_tp.max_threads, workerThreads);
  InterlockedExchange (&async_io_tp.max_threads, completionPortThreads);
  D.20921 = 1;
  return D.20921;
}


mono_install_threadpool_thread_hooks (void (*MonoThreadPoolFunc) (void *) start_func, void (*MonoThreadPoolFunc) (void *) finish_func, void * user_data)
{
  tp_start_func = start_func;
  tp_finish_func = finish_func;
  tp_hooks_user_data = user_data;
}


mono_install_threadpool_item_hooks (void (*MonoThreadPoolItemFunc) (void *) begin_func, void (*MonoThreadPoolItemFunc) (void *) end_func, void * user_data)
{
  tp_item_begin_func = begin_func;
  tp_item_end_func = end_func;
  tp_item_user_data = user_data;
}


mono_internal_thread_unhandled_exception (struct MonoObject * exc)
{
  <unnamed type> D.20928;
  struct MonoVTable * D.20931;
  struct MonoDomain * D.20932;
  struct MonoClass * D.20935;
  int D.20938;
  struct MonoInternalThread * D.20943;

  D.20928 = mono_runtime_unhandled_exception_policy_get ();
  if (D.20928 == 1) goto <D.20929>; else goto <D.20930>;
  <D.20929>:
  {
    gboolean unloaded;
    struct MonoClass * klass;

    D.20931 = exc->vtable;
    klass = D.20931->klass;
    D.20931 = exc->vtable;
    D.20932 = D.20931->domain;
    unloaded = is_appdomainunloaded_exception (D.20932, klass);
    if (unloaded == 0) goto <D.20933>; else goto <D.20934>;
    <D.20933>:
    D.20935 = mono_defaults.threadabortexception_class;
    if (D.20935 != klass) goto <D.20936>; else goto <D.20937>;
    <D.20936>:
    mono_unhandled_exception (exc);
    D.20938 = mono_environment_exitcode_get ();
    if (D.20938 == 1) goto <D.20939>; else goto <D.20940>;
    <D.20939>:
    exit (255);
    <D.20940>:
    <D.20937>:
    <D.20934>:
    D.20935 = mono_defaults.threadabortexception_class;
    if (D.20935 == klass) goto <D.20941>; else goto <D.20942>;
    <D.20941>:
    D.20943 = mono_thread_internal_current ();
    mono_thread_internal_reset_abort (D.20943);
    <D.20942>:
  }
  <D.20930>:
}


is_appdomainunloaded_exception (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.20944;
  gboolean D.20947;
  _Bool D.20948;
  int D.20949;
  int D.18610;
  int iftmp.67;
  int D.18606;
  const char[27] * D.20955;
  unsigned char D.20956;
  int D.20957;
  unsigned char D.20958;
  int D.20959;
  _Bool D.20960;
  _Bool D.20961;
  _Bool D.20962;
  const unsigned char * D.20965;
  unsigned char D.20966;
  int D.20967;
  const unsigned char * D.20968;
  unsigned char D.20969;
  int D.20970;
  _Bool D.20971;
  _Bool D.20972;
  const unsigned char * D.20975;
  unsigned char D.20976;
  int D.20977;
  const unsigned char * D.20978;
  unsigned char D.20979;
  int D.20980;
  _Bool D.20981;
  _Bool D.20982;
  const unsigned char * D.20985;
  unsigned char D.20986;
  int D.20987;
  const unsigned char * D.20988;
  unsigned char D.20989;
  int D.20990;
  const char * D.20992;
  int D.18619;
  int iftmp.68;
  int D.18615;
  const char[7] * D.20998;
  unsigned char D.20999;
  int D.21000;
  unsigned char D.21001;
  int D.21002;
  _Bool D.21003;
  _Bool D.21004;
  _Bool D.21005;
  const unsigned char * D.21008;
  unsigned char D.21009;
  int D.21010;
  const unsigned char * D.21011;
  unsigned char D.21012;
  int D.21013;
  _Bool D.21014;
  _Bool D.21015;
  const unsigned char * D.21018;
  unsigned char D.21019;
  int D.21020;
  const unsigned char * D.21021;
  unsigned char D.21022;
  int D.21023;
  _Bool D.21024;
  _Bool D.21025;
  const unsigned char * D.21028;
  unsigned char D.21029;
  int D.21030;
  const unsigned char * D.21031;
  unsigned char D.21032;
  int D.21033;
  const char * D.21035;

  D.20944 = domain->ad_unloaded_ex_class;
  if (D.20944 != 0B) goto <D.20945>; else goto <D.20946>;
  <D.20945>:
  D.20944 = domain->ad_unloaded_ex_class;
  D.20948 = D.20944 == klass;
  D.20947 = (gboolean) D.20948;
  return D.20947;
  <D.20946>:
  D.20949 = is_corlib_type (domain, klass);
  if (D.20949 != 0) goto <D.20950>; else goto <D.20951>;
  <D.20950>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 26;
    if (__s1_len <= 3) goto <D.20953>; else goto <D.20954>;
    <D.20953>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name;
      D.20955 = "AppDomainUnloadedException";
      D.20956 = MEM[(const unsigned char *)D.20955];
      D.20957 = (int) D.20956;
      D.20958 = *__s2;
      D.20959 = (int) D.20958;
      __result = D.20957 - D.20959;
      {
        D.20960 = __s1_len != 0;
        D.20961 = __result == 0;
        D.20962 = D.20960 & D.20961;
        if (D.20962 != 0) goto <D.20963>; else goto <D.20964>;
        <D.20963>:
        D.20965 = &MEM[(void *)"AppDomainUnloadedException" + 1B];
        D.20966 = *D.20965;
        D.20967 = (int) D.20966;
        D.20968 = __s2 + 1;
        D.20969 = *D.20968;
        D.20970 = (int) D.20969;
        __result = D.20967 - D.20970;
        D.20971 = __s1_len > 1;
        D.20961 = __result == 0;
        D.20972 = D.20971 & D.20961;
        if (D.20972 != 0) goto <D.20973>; else goto <D.20974>;
        <D.20973>:
        D.20975 = &MEM[(void *)"AppDomainUnloadedException" + 2B];
        D.20976 = *D.20975;
        D.20977 = (int) D.20976;
        D.20978 = __s2 + 2;
        D.20979 = *D.20978;
        D.20980 = (int) D.20979;
        __result = D.20977 - D.20980;
        D.20981 = __s1_len > 2;
        D.20961 = __result == 0;
        D.20982 = D.20981 & D.20961;
        if (D.20982 != 0) goto <D.20983>; else goto <D.20984>;
        <D.20983>:
        D.20985 = &MEM[(void *)"AppDomainUnloadedException" + 3B];
        D.20986 = *D.20985;
        D.20987 = (int) D.20986;
        D.20988 = __s2 + 3;
        D.20989 = *D.20988;
        D.20990 = (int) D.20989;
        __result = D.20987 - D.20990;
        <D.20984>:
        <D.20974>:
        <D.20964>:
      }
      D.18606 = __result;
    }
    iftmp.67 = D.18606;
    goto <D.20991>;
    <D.20954>:
    D.20992 = klass->name;
    iftmp.67 = __builtin_strcmp ("AppDomainUnloadedException", D.20992);
    <D.20991>:
    D.18610 = iftmp.67;
  }
  if (D.18610 == 0) goto <D.20993>; else goto <D.20994>;
  <D.20993>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s1_len = 6;
    if (__s1_len <= 3) goto <D.20996>; else goto <D.20997>;
    <D.20996>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = klass->name_space;
      D.20998 = "System";
      D.20999 = MEM[(const unsigned char *)D.20998];
      D.21000 = (int) D.20999;
      D.21001 = *__s2;
      D.21002 = (int) D.21001;
      __result = D.21000 - D.21002;
      {
        D.21003 = __s1_len != 0;
        D.21004 = __result == 0;
        D.21005 = D.21003 & D.21004;
        if (D.21005 != 0) goto <D.21006>; else goto <D.21007>;
        <D.21006>:
        D.21008 = &MEM[(void *)"System" + 1B];
        D.21009 = *D.21008;
        D.21010 = (int) D.21009;
        D.21011 = __s2 + 1;
        D.21012 = *D.21011;
        D.21013 = (int) D.21012;
        __result = D.21010 - D.21013;
        D.21014 = __s1_len > 1;
        D.21004 = __result == 0;
        D.21015 = D.21014 & D.21004;
        if (D.21015 != 0) goto <D.21016>; else goto <D.21017>;
        <D.21016>:
        D.21018 = &MEM[(void *)"System" + 2B];
        D.21019 = *D.21018;
        D.21020 = (int) D.21019;
        D.21021 = __s2 + 2;
        D.21022 = *D.21021;
        D.21023 = (int) D.21022;
        __result = D.21020 - D.21023;
        D.21024 = __s1_len > 2;
        D.21004 = __result == 0;
        D.21025 = D.21024 & D.21004;
        if (D.21025 != 0) goto <D.21026>; else goto <D.21027>;
        <D.21026>:
        D.21028 = &MEM[(void *)"System" + 3B];
        D.21029 = *D.21028;
        D.21030 = (int) D.21029;
        D.21031 = __s2 + 3;
        D.21032 = *D.21031;
        D.21033 = (int) D.21032;
        __result = D.21030 - D.21033;
        <D.21027>:
        <D.21017>:
        <D.21007>:
      }
      D.18615 = __result;
    }
    iftmp.68 = D.18615;
    goto <D.21034>;
    <D.20997>:
    D.21035 = klass->name_space;
    iftmp.68 = __builtin_strcmp ("System", D.21035);
    <D.21034>:
    D.18619 = iftmp.68;
  }
  if (D.18619 == 0) goto <D.21036>; else goto <D.21037>;
  <D.21036>:
  domain->ad_unloaded_ex_class = klass;
  D.20947 = 1;
  return D.20947;
  <D.21037>:
  <D.20994>:
  <D.20951>:
  D.20947 = 0;
  return D.20947;
}


mono_thread_pool_suspend ()
{
  suspended = 1;
}


mono_thread_pool_resume ()
{
  suspended = 0;
}


