mono_thread_pool_remove_socket (int sock)
{
  int D.18712;
  _Bool D.18717;
  long int D.18718;
  long int D.18719;
  struct MonoGHashTable * D.18722;
  _Bool D.18727;
  long int D.18728;
  long int D.18729;
  const void * sock.0;
  void * list.1;
  struct MonoMList * list.2;
  _Bool D.18739;
  long int D.18740;
  long int D.18741;
  int D.18744;
  struct MonoMList * list;
  struct MonoSocketAsyncResult * state;
  struct MonoObject * ares;

  try
    {
      D.18712 = socket_io_data.inited;
      if (D.18712 == 0) goto <D.18713>; else goto <D.18714>;
      <D.18713>:
      return;
      <D.18714>:
      {
        int ret;

        ret = pthread_mutex_lock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.18715>; else goto <D.18716>;
        <D.18715>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.18716>:
        D.18717 = ret != 0;
        D.18718 = (long int) D.18717;
        D.18719 = __builtin_expect (D.18718, 0);
        if (D.18719 != 0) goto <D.18720>; else goto <D.18721>;
        <D.18720>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 446, "ret == 0");
        <D.18721>:
      }
      D.18722 = socket_io_data.sock_to_state;
      if (D.18722 == 0B) goto <D.18723>; else goto <D.18724>;
      <D.18723>:
      {
        int ret;

        ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.18725>; else goto <D.18726>;
        <D.18725>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.18726>:
        D.18727 = ret != 0;
        D.18728 = (long int) D.18727;
        D.18729 = __builtin_expect (D.18728, 0);
        if (D.18729 != 0) goto <D.18730>; else goto <D.18731>;
        <D.18730>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 448, "ret == 0");
        <D.18731>:
      }
      return;
      <D.18724>:
      D.18722 = socket_io_data.sock_to_state;
      sock.0 = (const void *) sock;
      list.1 = mono_g_hash_table_lookup (D.18722, sock.0);
      list = list.1;
      list.2 = list;
      if (list.2 != 0B) goto <D.18735>; else goto <D.18736>;
      <D.18735>:
      D.18722 = socket_io_data.sock_to_state;
      sock.0 = (const void *) sock;
      mono_g_hash_table_remove (D.18722, sock.0);
      <D.18736>:
      {
        int ret;

        ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.18737>; else goto <D.18738>;
        <D.18737>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.18738>:
        D.18739 = ret != 0;
        D.18740 = (long int) D.18739;
        D.18741 = __builtin_expect (D.18740, 0);
        if (D.18741 != 0) goto <D.18742>; else goto <D.18743>;
        <D.18742>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 454, "ret == 0");
        <D.18743>:
      }
      goto <D.18335>;
      <D.18334>:
      list.2 = list;
      state = mono_mlist_get_data (list.2);
      D.18744 = state->operation;
      if (D.18744 == 2) goto <D.18745>; else goto <D.18746>;
      <D.18745>:
      state->operation = 6;
      goto <D.18747>;
      <D.18746>:
      D.18744 = state->operation;
      if (D.18744 == 4) goto <D.18748>; else goto <D.18749>;
      <D.18748>:
      state->operation = 7;
      <D.18749>:
      <D.18747>:
      ares = get_io_event (&list, 1);
      threadpool_append_job (&async_io_tp, ares);
      list.2 = list;
      if (list.2 != 0B) goto <D.18750>; else goto <D.18751>;
      <D.18750>:
      ares = get_io_event (&list, 4);
      threadpool_append_job (&async_io_tp, ares);
      <D.18751>:
      <D.18335>:
      list.2 = list;
      if (list.2 != 0B) goto <D.18334>; else goto <D.18336>;
      <D.18336>:
    }
  finally
    {
      list = {CLOBBER};
    }
}


get_io_event (struct MonoMList * * list, gint event)
{
  int D.18755;
  struct MonoMList * D.18761;
  struct MonoMList * D.18763;
  struct MonoMList * D.18764;
  struct MonoObject * D.18765;
  struct MonoObject * state;
  struct MonoMList * current;
  struct MonoMList * prev;

  current = *list;
  prev = 0B;
  state = 0B;
  goto <D.18324>;
  <D.18323>:
  state = mono_mlist_get_data (current);
  D.18755 = get_event_from_state (state);
  if (D.18755 == event) goto <D.18322>; else goto <D.18756>;
  <D.18756>:
  state = 0B;
  prev = current;
  current = mono_mlist_next (current);
  <D.18324>:
  if (current != 0B) goto <D.18323>; else goto <D.18322>;
  <D.18322>:
  if (current != 0B) goto <D.18757>; else goto <D.18758>;
  <D.18757>:
  if (prev != 0B) goto <D.18759>; else goto <D.18760>;
  <D.18759>:
  D.18761 = mono_mlist_next (current);
  mono_mlist_set_next (prev, D.18761);
  goto <D.18762>;
  <D.18760>:
  D.18763 = *list;
  D.18764 = mono_mlist_next (D.18763);
  *list = D.18764;
  <D.18762>:
  <D.18758>:
  D.18765 = state;
  return D.18765;
}


get_event_from_state (struct MonoSocketAsyncResult * state)
{
  int D.18767;
  int D.18768;

  D.18767 = state->operation;
  switch (D.18767) <default: <D.18298>, case 0: <D.18285>, case 1: <D.18295>, case 2: <D.18286>, case 3: <D.18288>, case 4: <D.18292>, case 5: <D.18294>, case 6: <D.18287>, case 7: <D.18293>, case 8: <D.18289>, case 10: <D.18297>, case 11: <D.18290>, case 12: <D.18291>, case 13: <D.18296>>
  <D.18285>:
  <D.18286>:
  <D.18287>:
  <D.18288>:
  <D.18289>:
  <D.18290>:
  <D.18291>:
  D.18768 = 1;
  return D.18768;
  <D.18292>:
  <D.18293>:
  <D.18294>:
  <D.18295>:
  <D.18296>:
  <D.18297>:
  D.18768 = 4;
  return D.18768;
  <D.18298>:
  monoeg_g_log (0B, 32, "get_event_from_state: unknown value in switch!!!");
  D.18768 = 0;
  return D.18768;
}


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.18770;
  int D.18773;
  volatile gint * D.18776;
  int D.18777;
  int D.18780;
  struct MonoDomain * D.18783;
  int D.18784;
  struct MonoDomain * D.18787;
  unsigned int i.3;
  unsigned int D.18789;
  struct MonoObject * * D.18790;
  struct MonoVTable * D.18794;
  struct MonoDomain * D.18795;
  int D.18796;
  int D.18799;
  int D.18800;
  long long int D.18803;
  void * D.18804;
  int D.18807;
  struct MonoCQ * D.18810;
  int D.18811;
  int iftmp.4;
  int D.18814;
  static int job_counter;
  struct MonoObject * ar;
  gint i;

  D.18770 = mono_runtime_is_shutting_down ();
  if (D.18770 != 0) goto <D.18771>; else goto <D.18772>;
  <D.18771>:
  return;
  <D.18772>:
  D.18773 = tp->pool_status;
  if (D.18773 == 0) goto <D.18774>; else goto <D.18775>;
  <D.18774>:
  D.18776 = &tp->pool_status;
  D.18777 = InterlockedCompareExchange (D.18776, 1, 0);
  if (D.18777 == 0) goto <D.18778>; else goto <D.18779>;
  <D.18778>:
  D.18780 = tp->is_io;
  if (D.18780 == 0) goto <D.18781>; else goto <D.18782>;
  <D.18781>:
  D.18783 = mono_get_root_domain ();
  mono_thread_create_internal (D.18783, monitor_thread, 0B, 1, 0, 131072);
  threadpool_start_thread (tp);
  <D.18782>:
  D.18784 = mono_config_is_server_mode ();
  if (D.18784 != 0) goto <D.18785>; else goto <D.18786>;
  <D.18785>:
  D.18787 = mono_get_root_domain ();
  mono_thread_create_internal (D.18787, threadpool_start_idle_threads, tp, 1, 0, 131072);
  <D.18786>:
  <D.18779>:
  <D.18775>:
  i = 0;
  goto <D.18508>;
  <D.18507>:
  i.3 = (unsigned int) i;
  D.18789 = i.3 * 4;
  D.18790 = jobs + D.18789;
  ar = *D.18790;
  if (ar == 0B) goto <D.18791>; else goto <D.18793>;
  <D.18793>:
  D.18794 = ar->vtable;
  D.18795 = D.18794->domain;
  D.18796 = mono_domain_is_unloading (D.18795);
  if (D.18796 != 0) goto <D.18791>; else goto <D.18792>;
  <D.18791>:
  // predicted unlikely by continue predictor.
  goto <D.18505>;
  <D.18792>:
  D.18780 = tp->is_io;
  if (D.18780 == 0) goto <D.18797>; else goto <D.18798>;
  <D.18797>:
  D.18799 = InterlockedIncrement (&job_counter);
  D.18800 = D.18799 % 10;
  if (D.18800 == 0) goto <D.18801>; else goto <D.18802>;
  <D.18801>:
  {
    struct MonoAsyncResult * o;

    o = ar;
    D.18803 = mono_100ns_ticks ();
    o->add_time = D.18803;
  }
  <D.18802>:
  <D.18798>:
  threadpool_jobs_inc (ar);
  D.18804 = tp->pc_nitems;
  mono_perfcounter_update_value (D.18804, 1, 1);
  D.18780 = tp->is_io;
  if (D.18780 == 0) goto <D.18805>; else goto <D.18806>;
  <D.18805>:
  D.18807 = mono_wsq_local_push (ar);
  if (D.18807 != 0) goto <D.18808>; else goto <D.18809>;
  <D.18808>:
  // predicted unlikely by continue predictor.
  goto <D.18505>;
  <D.18809>:
  <D.18806>:
  D.18810 = tp->queue;
  mono_cq_enqueue (D.18810, ar);
  <D.18505>:
  i = i + 1;
  <D.18508>:
  if (i < njobs) goto <D.18507>; else goto <D.18509>;
  <D.18509>:
  i = 0;
  goto <D.18511>;
  <D.18510>:
  pulse_on_new_job (tp);
  i = i + 1;
  <D.18511>:
  D.18811 = tp->waiting;
  if (D.18811 > 0) goto <D.18812>; else goto <D.18512>;
  <D.18812>:
  D.18814 = tp->max_threads;
  if (D.18814 <= njobs) goto <D.18815>; else goto <D.18816>;
  <D.18815>:
  iftmp.4 = tp->max_threads;
  goto <D.18817>;
  <D.18816>:
  iftmp.4 = njobs;
  <D.18817>:
  if (iftmp.4 > i) goto <D.18510>; else goto <D.18512>;
  <D.18512>:
}


threadpool_start_idle_threads (struct ThreadPool * tp)
{
  unsigned int iftmp.5;
  int D.18820;
  int D.18824;
  volatile gint * D.18827;
  int D.18828;
  int D.18829;
  void * D.18831;
  struct MonoDomain * D.18832;
  void (*<Tb30>) (void *) D.18833;
  int n;
  guint32 stack_size;

  D.18820 = tp->is_io;
  if (D.18820 == 0) goto <D.18821>; else goto <D.18822>;
  <D.18821>:
  iftmp.5 = 0;
  goto <D.18823>;
  <D.18822>:
  iftmp.5 = 131072;
  <D.18823>:
  stack_size = iftmp.5;
  <D.18386>:
  <D.18385>:
  n = tp->nthreads;
  D.18824 = tp->min_threads;
  if (D.18824 <= n) goto <D.18825>; else goto <D.18826>;
  <D.18825>:
  return;
  <D.18826>:
  D.18827 = &tp->nthreads;
  D.18828 = n + 1;
  D.18829 = InterlockedCompareExchange (D.18827, D.18828, n);
  if (D.18829 == n) goto <D.18384>; else goto <D.18830>;
  <D.18830>:
  goto <D.18385>;
  <D.18384>:
  D.18831 = tp->pc_nthreads;
  mono_perfcounter_update_value (D.18831, 1, 1);
  D.18832 = mono_get_root_domain ();
  D.18833 = tp->async_invoke;
  mono_thread_create_internal (D.18832, D.18833, tp, 1, 0, stack_size);
  SleepEx (100, 1);
  goto <D.18386>;
}


monitor_thread (void * unused)
{
  struct MonoDomain * D.18835;
  struct MonoString * D.18836;
  unsigned int D.18837;
  unsigned int D.18839;
  unsigned int D.18840;
  int D.18841;
  unsigned int D.18843;
  unsigned int D.18844;
  int i.6;
  int D.18849;
  int suspended.7;
  int D.18854;
  struct MonoCQ * D.18857;
  int D.18858;
  _Bool D.18859;
  int D.18862;
  _Bool D.18867;
  long int D.18868;
  long int D.18869;
  struct GPtrArray * wsqs.8;
  void * * D.18873;
  unsigned int i.9;
  unsigned int D.18875;
  void * * D.18876;
  int D.18877;
  unsigned int i.10;
  unsigned int D.18882;
  _Bool D.18885;
  long int D.18886;
  long int D.18887;
  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.18835 = mono_domain_get ();
      D.18836 = mono_string_new (D.18835, "Threadpool monitor");
      ves_icall_System_Threading_Thread_SetName_internal (thread, D.18836);
      <D.18428>:
      ms = 500;
      i = 10;
      <D.18414>:
      {
        guint32 ts;

        ts = mono_msec_ticks ();
        D.18837 = SleepEx (ms, 1);
        if (D.18837 == 0) goto <D.18413>; else goto <D.18838>;
        <D.18838>:
        D.18839 = mono_msec_ticks ();
        D.18840 = D.18839 - ts;
        ms = ms - D.18840;
        D.18841 = mono_runtime_is_shutting_down ();
        if (D.18841 != 0) goto <D.18413>; else goto <D.18842>;
        <D.18842>:
        D.18843 = thread->state;
        D.18844 = D.18843 & 3;
        if (D.18844 != 0) goto <D.18845>; else goto <D.18846>;
        <D.18845>:
        mono_thread_interruption_checkpoint ();
        <D.18846>:
      }
      if (ms != 0) goto <D.18847>; else goto <D.18413>;
      <D.18847>:
      i.6 = i;
      i = i.6 + -1;
      if (i.6 != 0) goto <D.18414>; else goto <D.18413>;
      <D.18413>:
      D.18849 = mono_runtime_is_shutting_down ();
      if (D.18849 != 0) goto <D.18415>; else goto <D.18850>;
      <D.18850>:
      suspended.7 = suspended;
      if (suspended.7 != 0) goto <D.18852>; else goto <D.18853>;
      <D.18852>:
      // predicted unlikely by continue predictor.
      goto <D.18416>;
      <D.18853>:
      i = 0;
      goto <D.18426>;
      <D.18425>:
      {
        struct ThreadPool * tp;

        tp = pools[i];
        D.18854 = tp->waiting;
        if (D.18854 > 0) goto <D.18855>; else goto <D.18856>;
        <D.18855>:
        // predicted unlikely by continue predictor.
        goto <D.18418>;
        <D.18856>:
        D.18857 = tp->queue;
        D.18858 = mono_cq_count (D.18857);
        D.18859 = D.18858 > 0;
        need_one = (gboolean) D.18859;
        if (need_one == 0) goto <D.18860>; else goto <D.18861>;
        <D.18860>:
        D.18862 = tp->is_io;
        if (D.18862 == 0) goto <D.18863>; else goto <D.18864>;
        <D.18863>:
        {
          int ret;

          ret = pthread_mutex_lock (&wsqs_lock.mutex);
          if (ret != 0) goto <D.18865>; else goto <D.18866>;
          <D.18865>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.18866>:
          D.18867 = ret != 0;
          D.18868 = (long int) D.18867;
          D.18869 = __builtin_expect (D.18868, 0);
          if (D.18869 != 0) goto <D.18870>; else goto <D.18871>;
          <D.18870>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 801, "ret == 0");
          <D.18871>:
        }
        i = 0;
        goto <D.18423>;
        <D.18422>:
        {
          struct MonoWSQ * wsq;

          wsqs.8 = wsqs;
          D.18873 = wsqs.8->pdata;
          i.9 = (unsigned int) i;
          D.18875 = i.9 * 4;
          D.18876 = D.18873 + D.18875;
          wsq = *D.18876;
          D.18877 = mono_wsq_count (wsq);
          if (D.18877 != 0) goto <D.18878>; else goto <D.18879>;
          <D.18878>:
          need_one = 1;
          goto <D.18421>;
          <D.18879>:
        }
        i = i + 1;
        <D.18423>:
        wsqs.8 = wsqs;
        if (wsqs.8 != 0B) goto <D.18880>; else goto <D.18421>;
        <D.18880>:
        i.10 = (unsigned int) i;
        wsqs.8 = wsqs;
        D.18882 = wsqs.8->len;
        if (i.10 < D.18882) goto <D.18422>; else goto <D.18421>;
        <D.18421>:
        {
          int ret;

          ret = pthread_mutex_unlock (&wsqs_lock.mutex);
          if (ret != 0) goto <D.18883>; else goto <D.18884>;
          <D.18883>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.18884>:
          D.18885 = ret != 0;
          D.18886 = (long int) D.18885;
          D.18887 = __builtin_expect (D.18886, 0);
          if (D.18887 != 0) goto <D.18888>; else goto <D.18889>;
          <D.18888>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 810, "ret == 0");
          <D.18889>:
        }
        <D.18864>:
        <D.18861>:
        if (need_one != 0) goto <D.18890>; else goto <D.18891>;
        <D.18890>:
        threadpool_start_thread (tp);
        <D.18891>:
      }
      <D.18418>:
      i = i + 1;
      <D.18426>:
      if (i <= 1) goto <D.18425>; else goto <D.18427>;
      <D.18427>:
      <D.18416>:
      goto <D.18428>;
      <D.18415>:
    }
  finally
    {
      pools = {CLOBBER};
    }
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.18892;
  unsigned int comp.11;
  unsigned int exch.12;
  unsigned int D.18895;

  comp.11 = (unsigned int) comp;
  exch.12 = (unsigned int) exch;
  D.18895 = __sync_val_compare_and_swap_4 (dest, comp.11, exch.12);
  D.18892 = (gint32) D.18895;
  return D.18892;
}


threadpool_start_thread (struct ThreadPool * tp)
{
  unsigned int iftmp.13;
  int D.18898;
  volatile gint * D.18902;
  int D.18903;
  int D.18904;
  void * D.18907;
  struct MonoDomain * D.18908;
  void (*<Tb30>) (void *) D.18909;
  gboolean D.18910;
  int D.18911;
  int D.18913;
  gint n;
  guint32 stack_size;

  D.18898 = tp->is_io;
  if (D.18898 == 0) goto <D.18899>; else goto <D.18900>;
  <D.18899>:
  iftmp.13 = 0;
  goto <D.18901>;
  <D.18900>:
  iftmp.13 = 131072;
  <D.18901>:
  stack_size = iftmp.13;
  goto <D.18485>;
  <D.18484>:
  D.18902 = &tp->nthreads;
  D.18903 = n + 1;
  D.18904 = InterlockedCompareExchange (D.18902, D.18903, n);
  if (D.18904 == n) goto <D.18905>; else goto <D.18906>;
  <D.18905>:
  D.18907 = tp->pc_nthreads;
  mono_perfcounter_update_value (D.18907, 1, 1);
  D.18908 = mono_get_root_domain ();
  D.18909 = tp->async_invoke;
  mono_thread_create_internal (D.18908, D.18909, tp, 1, 0, stack_size);
  D.18910 = 1;
  return D.18910;
  <D.18906>:
  <D.18485>:
  D.18911 = mono_runtime_is_shutting_down ();
  if (D.18911 == 0) goto <D.18912>; else goto <D.18486>;
  <D.18912>:
  n = tp->nthreads;
  D.18913 = tp->max_threads;
  if (n < D.18913) goto <D.18484>; else goto <D.18486>;
  <D.18486>:
  D.18910 = 0;
  return D.18910;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.18915;
  unsigned int D.18916;

  D.18916 = __sync_add_and_fetch_4 (val, 1);
  D.18915 = (gint32) D.18916;
  return D.18915;
}


threadpool_jobs_inc (struct MonoObject * obj)
{
  struct MonoVTable * D.18920;
  struct MonoDomain * D.18921;
  volatile int * D.18922;

  if (obj != 0B) goto <D.18918>; else goto <D.18919>;
  <D.18918>:
  D.18920 = obj->vtable;
  D.18921 = D.18920->domain;
  D.18922 = &D.18921->threadpool_jobs;
  InterlockedIncrement (D.18922);
  <D.18919>:
}


pulse_on_new_job (struct ThreadPool * tp)
{
  int D.18923;
  union MonoSemType * D.18926;

  D.18923 = tp->waiting;
  if (D.18923 != 0) goto <D.18924>; else goto <D.18925>;
  <D.18924>:
  D.18926 = &tp->new_job;
  mono_sem_post (D.18926);
  <D.18925>:
}


mono_thread_pool_init_tls ()
{
  mono_wsq_init ();
}


mono_thread_pool_init ()
{
  int tp_inited.14;
  int tp_inited.15;
  int D.18935;
  const gchar * D.18938;
  const gchar * D.18941;
  int D.18944;
  int D.18945;
  int D.18946;
  int D.18947;
  int D.18948;
  struct MonoImage * D.18949;
  struct MonoClass * async_call_klass.16;
  struct MonoClass * async_call_klass.17;
  _Bool D.18952;
  long int D.18953;
  long int D.18954;
  unsigned int D.18957;
  struct GPtrArray * wsqs.18;
  void * D.18959;
  void * D.18960;
  _Bool D.18961;
  long int D.18962;
  long int D.18963;
  void * D.18966;
  void * D.18967;
  _Bool D.18968;
  long int D.18969;
  long int D.18970;
  void * D.18973;
  void * D.18974;
  _Bool D.18975;
  long int D.18976;
  long int D.18977;
  void * D.18980;
  void * D.18981;
  _Bool D.18982;
  long int D.18983;
  long int D.18984;
  gint threads_per_cpu;
  gint thread_count;
  gint cpu_count;
  int result;

  threads_per_cpu = 1;
  cpu_count = mono_cpu_count ();
  tp_inited.14 = tp_inited;
  if (tp_inited.14 == 2) goto <D.18928>; else goto <D.18929>;
  <D.18928>:
  return;
  <D.18929>:
  result = InterlockedCompareExchange (&tp_inited, 1, 0);
  if (result == 1) goto <D.18930>; else goto <D.18931>;
  <D.18930>:
  <D.18439>:
  SleepEx (1, 0);
  tp_inited.15 = tp_inited;
  if (tp_inited.15 == 2) goto <D.18933>; else goto <D.18934>;
  <D.18933>:
  return;
  <D.18934>:
  goto <D.18439>;
  <D.18931>:
  D.18935 = mono_gc_is_moving ();
  if (D.18935 == 0) goto <D.18936>; else goto <D.18937>;
  <D.18936>:
  mono_gc_register_root (&socket_io_data.sock_to_state, 4, 0B);
  <D.18937>:
  InitializeCriticalSection (&socket_io_data.io_lock);
  D.18938 = monoeg_g_getenv ("MONO_THREADS_PER_CPU");
  if (D.18938 != 0B) goto <D.18939>; else goto <D.18940>;
  <D.18939>:
  D.18941 = monoeg_g_getenv ("MONO_THREADS_PER_CPU");
  threads_per_cpu = atoi (D.18941);
  if (threads_per_cpu <= 0) goto <D.18942>; else goto <D.18943>;
  <D.18942>:
  threads_per_cpu = 1;
  <D.18943>:
  <D.18940>:
  D.18944 = cpu_count * 100;
  D.18945 = cpu_count * threads_per_cpu;
  thread_count = MIN_EXPR <D.18944, D.18945>;
  D.18944 = cpu_count * 100;
  D.18946 = MAX_EXPR <D.18944, thread_count>;
  threadpool_init (&async_tp, thread_count, D.18946, async_invoke_thread);
  D.18947 = cpu_count * 2;
  D.18948 = cpu_count * 4;
  threadpool_init (&async_io_tp, D.18947, D.18948, async_invoke_thread);
  async_io_tp.is_io = 1;
  D.18949 = mono_defaults.corlib;
  async_call_klass.16 = mono_class_from_name (D.18949, "System", "MonoAsyncCall");
  async_call_klass = async_call_klass.16;
  async_call_klass.17 = async_call_klass;
  D.18952 = async_call_klass.17 == 0B;
  D.18953 = (long int) D.18952;
  D.18954 = __builtin_expect (D.18953, 0);
  if (D.18954 != 0) goto <D.18955>; else goto <D.18956>;
  <D.18955>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 858, "async_call_klass");
  <D.18956>:
  InitializeCriticalSection (&wsqs_lock);
  D.18944 = cpu_count * 100;
  D.18946 = MAX_EXPR <D.18944, thread_count>;
  D.18957 = (unsigned int) D.18946;
  wsqs.18 = monoeg_g_ptr_array_sized_new (D.18957);
  wsqs = wsqs.18;
  D.18959 = init_perf_counter ("Mono Threadpool", "Work Items Added");
  async_tp.pc_nitems = D.18959;
  D.18960 = async_tp.pc_nitems;
  D.18961 = D.18960 == 0B;
  D.18962 = (long int) D.18961;
  D.18963 = __builtin_expect (D.18962, 0);
  if (D.18963 != 0) goto <D.18964>; else goto <D.18965>;
  <D.18964>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 865, "async_tp.pc_nitems");
  <D.18965>:
  D.18966 = init_perf_counter ("Mono Threadpool", "IO Work Items Added");
  async_io_tp.pc_nitems = D.18966;
  D.18967 = async_io_tp.pc_nitems;
  D.18968 = D.18967 == 0B;
  D.18969 = (long int) D.18968;
  D.18970 = __builtin_expect (D.18969, 0);
  if (D.18970 != 0) goto <D.18971>; else goto <D.18972>;
  <D.18971>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 868, "async_io_tp.pc_nitems");
  <D.18972>:
  D.18973 = init_perf_counter ("Mono Threadpool", "# of Threads");
  async_tp.pc_nthreads = D.18973;
  D.18974 = async_tp.pc_nthreads;
  D.18975 = D.18974 == 0B;
  D.18976 = (long int) D.18975;
  D.18977 = __builtin_expect (D.18976, 0);
  if (D.18977 != 0) goto <D.18978>; else goto <D.18979>;
  <D.18978>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 871, "async_tp.pc_nthreads");
  <D.18979>:
  D.18980 = init_perf_counter ("Mono Threadpool", "# of IO Threads");
  async_io_tp.pc_nthreads = D.18980;
  D.18981 = async_io_tp.pc_nthreads;
  D.18982 = D.18981 == 0B;
  D.18983 = (long int) D.18982;
  D.18984 = __builtin_expect (D.18983, 0);
  if (D.18984 != 0) goto <D.18985>; else goto <D.18986>;
  <D.18985>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 874, "async_io_tp.pc_nthreads");
  <D.18986>:
  tp_inited = 2;
}


async_invoke_thread (void * data)
{
  int D.18988;
  void (*<Tb30>) (void *) tp_start_func.19;
  void * tp_hooks_user_data.20;
  volatile gint * D.18997;
  struct MonoVTable * D.18998;
  void * data.21;
  struct MonoVTable * D.19000;
  int D.19001;
  _Bool D.19002;
  int D.19005;
  void * D.19006;
  unsigned int D.19007;
  struct MonoArray * D.19008;
  int D.19009;
  int D.19010;
  int D.19011;
  gint * D.19012;
  int D.19013;
  int D.19014;
  _Bool D.19016;
  long int D.19017;
  long int D.19018;
  int D.19024;
  int D.19026;
  volatile gint * D.19027;
  int D.19028;
  volatile gint * D.19031;
  int D.19032;
  void (*<Tb30>) (void *) tp_item_begin_func.22;
  void * tp_item_user_data.23;
  long long int D.19041;
  void (*<Tb30>) (void *) tp_item_end_func.24;
  unsigned char D.19053;
  struct MonoDelegate * D.19056;
  struct MonoDomain * D.19059;
  volatile gint * D.19060;
  int D.19066;
  volatile gint * D.19067;
  volatile gint * D.19070;
  int D.19071;
  struct MonoCQ * D.19073;
  int D.19074;
  union MonoSemType * D.19076;
  volatile gint * D.19077;
  int D.19078;
  int D.19086;
  volatile gint * D.19093;
  int D.19098;
  volatile gint * D.19103;
  int D.19104;
  int D.19105;
  void * D.19106;
  void (*<Tb30>) (void *) tp_finish_func.25;
  struct MonoDomain * domain;
  struct MonoWSQ * wsq;
  struct ThreadPool * tp;
  gboolean must_die;

  tp = data;
  wsq = 0B;
  D.18988 = tp->is_io;
  if (D.18988 == 0) goto <D.18989>; else goto <D.18990>;
  <D.18989>:
  wsq = add_wsq ();
  <D.18990>:
  set_tp_thread_info (tp);
  tp_start_func.19 = tp_start_func;
  if (tp_start_func.19 != 0B) goto <D.18992>; else goto <D.18993>;
  <D.18992>:
  tp_start_func.19 = tp_start_func;
  tp_hooks_user_data.20 = tp_hooks_user_data;
  tp_start_func.19 (tp_hooks_user_data.20);
  <D.18993>:
  data = 0B;
  <D.18664>:
  {
    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.18995>; else goto <D.18996>;
    <D.18995>:
    D.18997 = &tp->busy_threads;
    InterlockedIncrement (D.18997);
    D.18998 = MEM[(struct MonoObject *)ar].vtable;
    domain = D.18998->domain;
    data.21 = data;
    D.19000 = MEM[(struct MonoObject *)data.21].vtable;
    klass = D.19000->klass;
    D.19001 = is_corlib_asyncresult (domain, klass);
    D.19002 = D.19001 == 0;
    is_io_task = (gboolean) D.19002;
    is_socket = 0;
    if (is_io_task != 0) goto <D.19003>; else goto <D.19004>;
    <D.19003>:
    {
      struct MonoSocketAsyncResult * state;

      state = data;
      is_socket = is_socketasyncresult (domain, klass);
      ar = state->ares;
      D.19005 = state->operation;
      switch (D.19005) <default: <D.19015>, case 2: <D.18646>, case 4: <D.18648>>
      <D.18646>:
      D.19006 = state->handle;
      D.19007 = (unsigned int) D.19006;
      D.19008 = state->buffer;
      D.19009 = state->offset;
      D.19010 = state->size;
      D.19011 = state->socket_flags;
      D.19012 = &state->error;
      D.19013 = ves_icall_System_Net_Sockets_Socket_Receive_internal (D.19007, D.19008, D.19009, D.19010, D.19011, D.19012);
      state->total = D.19013;
      goto <D.18647>;
      <D.18648>:
      D.19006 = state->handle;
      D.19007 = (unsigned int) D.19006;
      D.19008 = state->buffer;
      D.19009 = state->offset;
      D.19010 = state->size;
      D.19011 = state->socket_flags;
      D.19012 = &state->error;
      D.19014 = ves_icall_System_Net_Sockets_Socket_Send_internal (D.19007, D.19008, D.19009, D.19010, D.19011, D.19012);
      state->total = D.19014;
      goto <D.18647>;
      <D.19015>:
      <D.18647>:
    }
    <D.19004>:
    D.19016 = domain == 0B;
    D.19017 = (long int) D.19016;
    D.19018 = __builtin_expect (D.19017, 0);
    if (D.19018 != 0) goto <D.19019>; else goto <D.19020>;
    <D.19019>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1492, "domain");
    <D.19020>:
    D.19024 = mono_domain_is_unloading (domain);
    if (D.19024 != 0) goto <D.19021>; else goto <D.19025>;
    <D.19025>:
    D.19026 = mono_runtime_is_shutting_down ();
    if (D.19026 != 0) goto <D.19021>; else goto <D.19022>;
    <D.19021>:
    threadpool_jobs_dec (ar);
    data = 0B;
    ar = 0B;
    D.19027 = &tp->busy_threads;
    InterlockedDecrement (D.19027);
    goto <D.19023>;
    <D.19022>:
    mono_thread_push_appdomain_ref (domain);
    D.19028 = threadpool_jobs_dec (ar);
    if (D.19028 != 0) goto <D.19029>; else goto <D.19030>;
    <D.19029>:
    data = 0B;
    ar = 0B;
    mono_thread_pop_appdomain_ref ();
    D.19031 = &tp->busy_threads;
    InterlockedDecrement (D.19031);
    // predicted unlikely by continue predictor.
    goto <D.18649>;
    <D.19030>:
    D.19032 = mono_domain_set (domain, 0);
    if (D.19032 != 0) goto <D.19033>; else goto <D.19034>;
    <D.19033>:
    {
      struct MonoObject * exc;

      tp_item_begin_func.22 = tp_item_begin_func;
      if (tp_item_begin_func.22 != 0B) goto <D.19036>; else goto <D.19037>;
      <D.19036>:
      tp_item_begin_func.22 = tp_item_begin_func;
      tp_item_user_data.23 = tp_item_user_data;
      tp_item_begin_func.22 (tp_item_user_data.23);
      <D.19037>:
      if (is_io_task == 0) goto <D.19039>; else goto <D.19040>;
      <D.19039>:
      D.19041 = ar->add_time;
      if (D.19041 > 0) goto <D.19042>; else goto <D.19043>;
      <D.19042>:
      D.19041 = ar->add_time;
      process_idle_times (tp, D.19041);
      <D.19043>:
      <D.19040>:
      exc = mono_async_invoke (tp, ar);
      tp_item_end_func.24 = tp_item_end_func;
      if (tp_item_end_func.24 != 0B) goto <D.19045>; else goto <D.19046>;
      <D.19045>:
      tp_item_end_func.24 = tp_item_end_func;
      tp_item_user_data.23 = tp_item_user_data;
      tp_item_end_func.24 (tp_item_user_data.23);
      <D.19046>:
      if (exc != 0B) goto <D.19047>; else goto <D.19048>;
      <D.19047>:
      mono_internal_thread_unhandled_exception (exc);
      <D.19048>:
      if (is_socket != 0) goto <D.19049>; else goto <D.19050>;
      <D.19049>:
      D.18988 = tp->is_io;
      if (D.18988 != 0) goto <D.19051>; else goto <D.19052>;
      <D.19051>:
      {
        struct MonoSocketAsyncResult * state;

        state = data;
        D.19053 = state->completed;
        if (D.19053 != 0) goto <D.19054>; else goto <D.19055>;
        <D.19054>:
        D.19056 = state->callback;
        if (D.19056 != 0B) goto <D.19057>; else goto <D.19058>;
        <D.19057>:
        {
          struct MonoAsyncResult * cb_ares;

          D.19056 = state->callback;
          cb_ares = create_simple_asyncresult (D.19056, state);
          icall_append_job (cb_ares);
        }
        <D.19058>:
        <D.19055>:
      }
      <D.19052>:
      <D.19050>:
      D.19059 = mono_get_root_domain ();
      mono_domain_set (D.19059, 1);
    }
    <D.19034>:
    mono_thread_pop_appdomain_ref ();
    D.19060 = &tp->busy_threads;
    InterlockedDecrement (D.19060);
    clear_thread_state ();
    <D.19023>:
    <D.18996>:
    ar = 0B;
    data = 0B;
    must_die = should_i_die (tp);
    if (must_die == 0) goto <D.19063>; else goto <D.19064>;
    <D.19063>:
    D.18988 = tp->is_io;
    if (D.18988 != 0) goto <D.19061>; else goto <D.19065>;
    <D.19065>:
    D.19066 = mono_wsq_local_pop (&data);
    if (D.19066 == 0) goto <D.19061>; else goto <D.19062>;
    <D.19061>:
    dequeue_or_steal (tp, &data, wsq);
    <D.19062>:
    <D.19064>:
    n_naps = 0;
    goto <D.18659>;
    <D.18658>:
    {
      gboolean res;

      D.19067 = &tp->waiting;
      InterlockedIncrement (D.19067);
      dequeue_or_steal (tp, &data, wsq);
      data.21 = data;
      if (data.21 != 0B) goto <D.19068>; else goto <D.19069>;
      <D.19068>:
      D.19070 = &tp->waiting;
      InterlockedDecrement (D.19070);
      goto <D.18654>;
      <D.19069>:
      mono_gc_set_skip_thread (1);
      goto <D.18657>;
      <D.18656>:
      D.19071 = mono_runtime_is_shutting_down ();
      if (D.19071 != 0) goto <D.18655>; else goto <D.19072>;
      <D.19072>:
      check_for_interruption_critical ();
      <D.18657>:
      D.19073 = tp->queue;
      D.19074 = mono_cq_count (D.19073);
      if (D.19074 == 0) goto <D.19075>; else goto <D.18655>;
      <D.19075>:
      D.19076 = &tp->new_job;
      res = mono_sem_timedwait (D.19076, 2000, 1);
      if (res == -1) goto <D.18656>; else goto <D.18655>;
      <D.18655>:
      D.19077 = &tp->waiting;
      InterlockedDecrement (D.19077);
      mono_gc_set_skip_thread (0);
      D.19078 = mono_runtime_is_shutting_down ();
      if (D.19078 != 0) goto <D.18654>; else goto <D.19079>;
      <D.19079>:
      must_die = should_i_die (tp);
      dequeue_or_steal (tp, &data, wsq);
      n_naps = n_naps + 1;
    }
    <D.18659>:
    if (must_die == 0) goto <D.19080>; else goto <D.18654>;
    <D.19080>:
    data.21 = data;
    if (data.21 == 0B) goto <D.19081>; else goto <D.18654>;
    <D.19081>:
    if (n_naps <= 3) goto <D.18658>; else goto <D.18654>;
    <D.18654>:
    data.21 = data;
    if (data.21 == 0B) goto <D.19082>; else goto <D.19083>;
    <D.19082>:
    D.18988 = tp->is_io;
    if (D.18988 == 0) goto <D.19084>; else goto <D.19085>;
    <D.19084>:
    D.19086 = mono_runtime_is_shutting_down ();
    if (D.19086 == 0) goto <D.19087>; else goto <D.19088>;
    <D.19087>:
    mono_wsq_local_pop (&data);
    data.21 = data;
    if (data.21 != 0B) goto <D.19089>; else goto <D.19090>;
    <D.19089>:
    if (must_die != 0) goto <D.19091>; else goto <D.19092>;
    <D.19091>:
    D.19093 = &tp->destroy_thread;
    InterlockedCompareExchange (D.19093, 1, 0);
    pulse_on_new_job (tp);
    <D.19092>:
    <D.19090>:
    <D.19088>:
    <D.19085>:
    <D.19083>:
    data.21 = data;
    if (data.21 == 0B) goto <D.19094>; else goto <D.19095>;
    <D.19094>:
    {
      gint nt;
      gboolean down;

      <D.18663>:
      nt = tp->nthreads;
      down = mono_runtime_is_shutting_down ();
      if (down == 0) goto <D.19096>; else goto <D.19097>;
      <D.19096>:
      D.19098 = tp->min_threads;
      if (D.19098 >= nt) goto <D.18662>; else goto <D.19099>;
      <D.19099>:
      <D.19097>:
      if (down != 0) goto <D.19100>; else goto <D.19102>;
      <D.19102>:
      D.19103 = &tp->nthreads;
      D.19104 = nt + -1;
      D.19105 = InterlockedCompareExchange (D.19103, D.19104, nt);
      if (D.19105 == nt) goto <D.19100>; else goto <D.19101>;
      <D.19100>:
      D.19106 = tp->pc_nthreads;
      mono_perfcounter_update_value (D.19106, 1, -1);
      D.18988 = tp->is_io;
      if (D.18988 == 0) goto <D.19107>; else goto <D.19108>;
      <D.19107>:
      remove_wsq (wsq);
      <D.19108>:
      fire_profiler_thread_end ();
      tp_finish_func.25 = tp_finish_func;
      if (tp_finish_func.25 != 0B) goto <D.19110>; else goto <D.19111>;
      <D.19110>:
      tp_finish_func.25 = tp_finish_func;
      tp_hooks_user_data.20 = tp_hooks_user_data;
      tp_finish_func.25 (tp_hooks_user_data.20);
      <D.19111>:
      return;
      <D.19101>:
      goto <D.18663>;
      <D.18662>:
    }
    <D.19095>:
  }
  <D.18649>:
  goto <D.18664>;
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "threadpool.c", 1616);
}


add_wsq ()
{
  _Bool D.19115;
  long int D.19116;
  long int D.19117;
  struct GPtrArray * wsqs.26;
  _Bool D.19125;
  long int D.19126;
  long int D.19127;
  struct MonoWSQ * D.19130;
  void * * D.19131;
  unsigned int i.27;
  unsigned int D.19133;
  void * * D.19134;
  void * D.19135;
  _Bool D.19140;
  long int D.19141;
  long int D.19142;
  unsigned int i.28;
  unsigned int D.19146;
  _Bool D.19149;
  long int D.19150;
  long int D.19151;
  int i;
  struct MonoWSQ * wsq;

  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19113>; else goto <D.19114>;
    <D.19113>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19114>:
    D.19115 = ret != 0;
    D.19116 = (long int) D.19115;
    D.19117 = __builtin_expect (D.19116, 0);
    if (D.19117 != 0) goto <D.19118>; else goto <D.19119>;
    <D.19118>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1221, "ret == 0");
    <D.19119>:
  }
  wsq = mono_wsq_create ();
  wsqs.26 = wsqs;
  if (wsqs.26 == 0B) goto <D.19121>; else goto <D.19122>;
  <D.19121>:
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19123>; else goto <D.19124>;
    <D.19123>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19124>:
    D.19125 = ret != 0;
    D.19126 = (long int) D.19125;
    D.19127 = __builtin_expect (D.19126, 0);
    if (D.19127 != 0) goto <D.19128>; else goto <D.19129>;
    <D.19128>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1224, "ret == 0");
    <D.19129>:
  }
  D.19130 = 0B;
  return D.19130;
  <D.19122>:
  i = 0;
  goto <D.18564>;
  <D.18563>:
  wsqs.26 = wsqs;
  D.19131 = wsqs.26->pdata;
  i.27 = (unsigned int) i;
  D.19133 = i.27 * 4;
  D.19134 = D.19131 + D.19133;
  D.19135 = *D.19134;
  if (D.19135 == 0B) goto <D.19136>; else goto <D.19137>;
  <D.19136>:
  wsqs.26 = wsqs;
  D.19131 = wsqs.26->pdata;
  i.27 = (unsigned int) i;
  D.19133 = i.27 * 4;
  D.19134 = D.19131 + D.19133;
  *D.19134 = wsq;
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19138>; else goto <D.19139>;
    <D.19138>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19139>:
    D.19140 = ret != 0;
    D.19141 = (long int) D.19140;
    D.19142 = __builtin_expect (D.19141, 0);
    if (D.19142 != 0) goto <D.19143>; else goto <D.19144>;
    <D.19143>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1230, "ret == 0");
    <D.19144>:
  }
  D.19130 = wsq;
  return D.19130;
  <D.19137>:
  i = i + 1;
  <D.18564>:
  i.28 = (unsigned int) i;
  wsqs.26 = wsqs;
  D.19146 = wsqs.26->len;
  if (i.28 < D.19146) goto <D.18563>; else goto <D.18565>;
  <D.18565>:
  wsqs.26 = wsqs;
  monoeg_g_ptr_array_add (wsqs.26, wsq);
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19147>; else goto <D.19148>;
    <D.19147>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19148>:
    D.19149 = ret != 0;
    D.19150 = (long int) D.19149;
    D.19151 = __builtin_expect (D.19150, 0);
    if (D.19151 != 0) goto <D.19152>; else goto <D.19153>;
    <D.19152>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1235, "ret == 0");
    <D.19153>:
  }
  D.19130 = wsq;
  return D.19130;
}


set_tp_thread_info (struct ThreadPool * tp)
{
  long long unsigned int D.19155;
  unsigned int D.19156;
  const gchar * iftmp.29;
  int D.19158;
  struct MonoDomain * D.19162;
  struct MonoString * D.19163;
  const gchar * name;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.19155 = thread->tid;
  D.19156 = (unsigned int) D.19155;
  mono_profiler_thread_start (D.19156);
  D.19158 = tp->is_io;
  if (D.19158 != 0) goto <D.19159>; else goto <D.19160>;
  <D.19159>:
  iftmp.29 = "IO Threadpool worker";
  goto <D.19161>;
  <D.19160>:
  iftmp.29 = "Threadpool worker";
  <D.19161>:
  name = iftmp.29;
  D.19162 = mono_domain_get ();
  D.19163 = mono_string_new (D.19162, name);
  mono_thread_set_name_internal (thread, D.19163, 0);
}


is_corlib_asyncresult (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.19164;
  gboolean D.19167;
  _Bool D.19168;
  int D.19169;
  int D.18161;
  int iftmp.30;
  int D.18157;
  const char[12] * D.19175;
  unsigned char D.19176;
  int D.19177;
  unsigned char D.19178;
  int D.19179;
  const unsigned char * D.19184;
  unsigned char D.19185;
  int D.19186;
  const unsigned char * D.19187;
  unsigned char D.19188;
  int D.19189;
  const unsigned char * D.19194;
  unsigned char D.19195;
  int D.19196;
  const unsigned char * D.19197;
  unsigned char D.19198;
  int D.19199;
  const unsigned char * D.19204;
  unsigned char D.19205;
  int D.19206;
  const unsigned char * D.19207;
  unsigned char D.19208;
  int D.19209;
  const char * D.19211;
  int D.18170;
  int iftmp.31;
  int D.18166;
  const char[34] * D.19217;
  unsigned char D.19218;
  int D.19219;
  unsigned char D.19220;
  int D.19221;
  const unsigned char * D.19226;
  unsigned char D.19227;
  int D.19228;
  const unsigned char * D.19229;
  unsigned char D.19230;
  int D.19231;
  const unsigned char * D.19236;
  unsigned char D.19237;
  int D.19238;
  const unsigned char * D.19239;
  unsigned char D.19240;
  int D.19241;
  const unsigned char * D.19246;
  unsigned char D.19247;
  int D.19248;
  const unsigned char * D.19249;
  unsigned char D.19250;
  int D.19251;
  const char * D.19253;

  D.19164 = domain->corlib_asyncresult_class;
  if (D.19164 != 0B) goto <D.19165>; else goto <D.19166>;
  <D.19165>:
  D.19164 = domain->corlib_asyncresult_class;
  D.19168 = D.19164 == klass;
  D.19167 = (gboolean) D.19168;
  return D.19167;
  <D.19166>:
  D.19169 = is_corlib_type (domain, klass);
  if (D.19169 != 0) goto <D.19170>; else goto <D.19171>;
  <D.19170>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.19175 = "AsyncResult";
      D.19176 = MEM[(const unsigned char *)D.19175];
      D.19177 = (int) D.19176;
      D.19178 = *__s2;
      D.19179 = (int) D.19178;
      __result = D.19177 - D.19179;
      {
        if (__s1_len != 0) goto <D.19180>; else goto <D.19181>;
        <D.19180>:
        if (__result == 0) goto <D.19182>; else goto <D.19183>;
        <D.19182>:
        D.19184 = &MEM[(void *)"AsyncResult" + 1B];
        D.19185 = *D.19184;
        D.19186 = (int) D.19185;
        D.19187 = __s2 + 1;
        D.19188 = *D.19187;
        D.19189 = (int) D.19188;
        __result = D.19186 - D.19189;
        if (__s1_len > 1) goto <D.19190>; else goto <D.19191>;
        <D.19190>:
        if (__result == 0) goto <D.19192>; else goto <D.19193>;
        <D.19192>:
        D.19194 = &MEM[(void *)"AsyncResult" + 2B];
        D.19195 = *D.19194;
        D.19196 = (int) D.19195;
        D.19197 = __s2 + 2;
        D.19198 = *D.19197;
        D.19199 = (int) D.19198;
        __result = D.19196 - D.19199;
        if (__s1_len > 2) goto <D.19200>; else goto <D.19201>;
        <D.19200>:
        if (__result == 0) goto <D.19202>; else goto <D.19203>;
        <D.19202>:
        D.19204 = &MEM[(void *)"AsyncResult" + 3B];
        D.19205 = *D.19204;
        D.19206 = (int) D.19205;
        D.19207 = __s2 + 3;
        D.19208 = *D.19207;
        D.19209 = (int) D.19208;
        __result = D.19206 - D.19209;
        <D.19203>:
        <D.19201>:
        <D.19193>:
        <D.19191>:
        <D.19183>:
        <D.19181>:
      }
      D.18157 = __result;
    }
    iftmp.30 = D.18157;
    goto <D.19210>;
    <D.19174>:
    D.19211 = klass->name;
    iftmp.30 = __builtin_strcmp ("AsyncResult", D.19211);
    <D.19210>:
    D.18161 = iftmp.30;
  }
  if (D.18161 == 0) goto <D.19212>; else goto <D.19213>;
  <D.19212>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.19217 = "System.Runtime.Remoting.Messaging";
      D.19218 = MEM[(const unsigned char *)D.19217];
      D.19219 = (int) D.19218;
      D.19220 = *__s2;
      D.19221 = (int) D.19220;
      __result = D.19219 - D.19221;
      {
        if (__s1_len != 0) goto <D.19222>; else goto <D.19223>;
        <D.19222>:
        if (__result == 0) goto <D.19224>; else goto <D.19225>;
        <D.19224>:
        D.19226 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 1B];
        D.19227 = *D.19226;
        D.19228 = (int) D.19227;
        D.19229 = __s2 + 1;
        D.19230 = *D.19229;
        D.19231 = (int) D.19230;
        __result = D.19228 - D.19231;
        if (__s1_len > 1) goto <D.19232>; else goto <D.19233>;
        <D.19232>:
        if (__result == 0) goto <D.19234>; else goto <D.19235>;
        <D.19234>:
        D.19236 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 2B];
        D.19237 = *D.19236;
        D.19238 = (int) D.19237;
        D.19239 = __s2 + 2;
        D.19240 = *D.19239;
        D.19241 = (int) D.19240;
        __result = D.19238 - D.19241;
        if (__s1_len > 2) goto <D.19242>; else goto <D.19243>;
        <D.19242>:
        if (__result == 0) goto <D.19244>; else goto <D.19245>;
        <D.19244>:
        D.19246 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 3B];
        D.19247 = *D.19246;
        D.19248 = (int) D.19247;
        D.19249 = __s2 + 3;
        D.19250 = *D.19249;
        D.19251 = (int) D.19250;
        __result = D.19248 - D.19251;
        <D.19245>:
        <D.19243>:
        <D.19235>:
        <D.19233>:
        <D.19225>:
        <D.19223>:
      }
      D.18166 = __result;
    }
    iftmp.31 = D.18166;
    goto <D.19252>;
    <D.19216>:
    D.19253 = klass->name_space;
    iftmp.31 = __builtin_strcmp ("System.Runtime.Remoting.Messaging", D.19253);
    <D.19252>:
    D.18170 = iftmp.31;
  }
  if (D.18170 == 0) goto <D.19254>; else goto <D.19255>;
  <D.19254>:
  domain->corlib_asyncresult_class = klass;
  D.19167 = 1;
  return D.19167;
  <D.19255>:
  <D.19213>:
  <D.19171>:
  D.19167 = 0;
  return D.19167;
}


is_corlib_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.19257;
  struct MonoImage * D.19258;
  struct MonoImage * D.19259;
  _Bool D.19260;

  D.19258 = klass->image;
  D.19259 = mono_defaults.corlib;
  D.19260 = D.19258 == D.19259;
  D.19257 = (gboolean) D.19260;
  return D.19257;
}


is_socketasyncresult (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.19262;
  int iftmp.32;
  struct MonoClass * D.19266;
  int D.19268;
  int D.18205;
  int iftmp.33;
  int D.18204;
  const char[18] * D.19273;
  unsigned char D.19274;
  int D.19275;
  unsigned char D.19276;
  int D.19277;
  const unsigned char * D.19282;
  unsigned char D.19283;
  int D.19284;
  const unsigned char * D.19285;
  unsigned char D.19286;
  int D.19287;
  const unsigned char * D.19292;
  unsigned char D.19293;
  int D.19294;
  const unsigned char * D.19295;
  unsigned char D.19296;
  int D.19297;
  const unsigned char * D.19302;
  unsigned char D.19303;
  int D.19304;
  const unsigned char * D.19305;
  unsigned char D.19306;
  int D.19307;
  const char * D.19309;

  D.19266 = klass->nested_in;
  if (D.19266 != 0B) goto <D.19267>; else goto <D.19264>;
  <D.19267>:
  D.19266 = klass->nested_in;
  D.19268 = is_socket (domain, D.19266);
  if (D.19268 != 0) goto <D.19269>; else goto <D.19264>;
  <D.19269>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.19273 = "SocketAsyncResult";
      D.19274 = MEM[(const unsigned char *)D.19273];
      D.19275 = (int) D.19274;
      D.19276 = *__s2;
      D.19277 = (int) D.19276;
      __result = D.19275 - D.19277;
      {
        if (__s2_len != 0) goto <D.19278>; else goto <D.19279>;
        <D.19278>:
        if (__result == 0) goto <D.19280>; else goto <D.19281>;
        <D.19280>:
        D.19282 = &MEM[(void *)"SocketAsyncResult" + 1B];
        D.19283 = *D.19282;
        D.19284 = (int) D.19283;
        D.19285 = __s2 + 1;
        D.19286 = *D.19285;
        D.19287 = (int) D.19286;
        __result = D.19284 - D.19287;
        if (__s2_len > 1) goto <D.19288>; else goto <D.19289>;
        <D.19288>:
        if (__result == 0) goto <D.19290>; else goto <D.19291>;
        <D.19290>:
        D.19292 = &MEM[(void *)"SocketAsyncResult" + 2B];
        D.19293 = *D.19292;
        D.19294 = (int) D.19293;
        D.19295 = __s2 + 2;
        D.19296 = *D.19295;
        D.19297 = (int) D.19296;
        __result = D.19294 - D.19297;
        if (__s2_len > 2) goto <D.19298>; else goto <D.19299>;
        <D.19298>:
        if (__result == 0) goto <D.19300>; else goto <D.19301>;
        <D.19300>:
        D.19302 = &MEM[(void *)"SocketAsyncResult" + 3B];
        D.19303 = *D.19302;
        D.19304 = (int) D.19303;
        D.19305 = __s2 + 3;
        D.19306 = *D.19305;
        D.19307 = (int) D.19306;
        __result = D.19304 - D.19307;
        <D.19301>:
        <D.19299>:
        <D.19291>:
        <D.19289>:
        <D.19281>:
        <D.19279>:
      }
      D.18204 = __result;
    }
    iftmp.33 = -D.18204;
    goto <D.19308>;
    <D.19272>:
    D.19309 = klass->name;
    iftmp.33 = __builtin_strcmp (D.19309, "SocketAsyncResult");
    <D.19308>:
    D.18205 = iftmp.33;
  }
  if (D.18205 == 0) goto <D.19310>; else goto <D.19264>;
  <D.19310>:
  iftmp.32 = 1;
  goto <D.19265>;
  <D.19264>:
  iftmp.32 = 0;
  <D.19265>:
  D.19262 = iftmp.32;
  return D.19262;
}


is_socket (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.19312;
  gboolean D.19315;
  _Bool D.19316;
  int D.19317;
  int D.18183;
  int iftmp.34;
  int D.18179;
  const char[7] * D.19323;
  unsigned char D.19324;
  int D.19325;
  unsigned char D.19326;
  int D.19327;
  const unsigned char * D.19332;
  unsigned char D.19333;
  int D.19334;
  const unsigned char * D.19335;
  unsigned char D.19336;
  int D.19337;
  const unsigned char * D.19342;
  unsigned char D.19343;
  int D.19344;
  const unsigned char * D.19345;
  unsigned char D.19346;
  int D.19347;
  const unsigned char * D.19352;
  unsigned char D.19353;
  int D.19354;
  const unsigned char * D.19355;
  unsigned char D.19356;
  int D.19357;
  const char * D.19359;
  int D.18192;
  int iftmp.35;
  int D.18188;
  const char[19] * D.19365;
  unsigned char D.19366;
  int D.19367;
  unsigned char D.19368;
  int D.19369;
  const unsigned char * D.19374;
  unsigned char D.19375;
  int D.19376;
  const unsigned char * D.19377;
  unsigned char D.19378;
  int D.19379;
  const unsigned char * D.19384;
  unsigned char D.19385;
  int D.19386;
  const unsigned char * D.19387;
  unsigned char D.19388;
  int D.19389;
  const unsigned char * D.19394;
  unsigned char D.19395;
  int D.19396;
  const unsigned char * D.19397;
  unsigned char D.19398;
  int D.19399;
  const char * D.19401;

  D.19312 = domain->socket_class;
  if (D.19312 != 0B) goto <D.19313>; else goto <D.19314>;
  <D.19313>:
  D.19312 = domain->socket_class;
  D.19316 = D.19312 == klass;
  D.19315 = (gboolean) D.19316;
  return D.19315;
  <D.19314>:
  D.19317 = is_socket_type (domain, klass);
  if (D.19317 != 0) goto <D.19318>; else goto <D.19319>;
  <D.19318>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.19323 = "Socket";
      D.19324 = MEM[(const unsigned char *)D.19323];
      D.19325 = (int) D.19324;
      D.19326 = *__s2;
      D.19327 = (int) D.19326;
      __result = D.19325 - D.19327;
      {
        if (__s1_len != 0) goto <D.19328>; else goto <D.19329>;
        <D.19328>:
        if (__result == 0) goto <D.19330>; else goto <D.19331>;
        <D.19330>:
        D.19332 = &MEM[(void *)"Socket" + 1B];
        D.19333 = *D.19332;
        D.19334 = (int) D.19333;
        D.19335 = __s2 + 1;
        D.19336 = *D.19335;
        D.19337 = (int) D.19336;
        __result = D.19334 - D.19337;
        if (__s1_len > 1) goto <D.19338>; else goto <D.19339>;
        <D.19338>:
        if (__result == 0) goto <D.19340>; else goto <D.19341>;
        <D.19340>:
        D.19342 = &MEM[(void *)"Socket" + 2B];
        D.19343 = *D.19342;
        D.19344 = (int) D.19343;
        D.19345 = __s2 + 2;
        D.19346 = *D.19345;
        D.19347 = (int) D.19346;
        __result = D.19344 - D.19347;
        if (__s1_len > 2) goto <D.19348>; else goto <D.19349>;
        <D.19348>:
        if (__result == 0) goto <D.19350>; else goto <D.19351>;
        <D.19350>:
        D.19352 = &MEM[(void *)"Socket" + 3B];
        D.19353 = *D.19352;
        D.19354 = (int) D.19353;
        D.19355 = __s2 + 3;
        D.19356 = *D.19355;
        D.19357 = (int) D.19356;
        __result = D.19354 - D.19357;
        <D.19351>:
        <D.19349>:
        <D.19341>:
        <D.19339>:
        <D.19331>:
        <D.19329>:
      }
      D.18179 = __result;
    }
    iftmp.34 = D.18179;
    goto <D.19358>;
    <D.19322>:
    D.19359 = klass->name;
    iftmp.34 = __builtin_strcmp ("Socket", D.19359);
    <D.19358>:
    D.18183 = iftmp.34;
  }
  if (D.18183 == 0) goto <D.19360>; else goto <D.19361>;
  <D.19360>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.19365 = "System.Net.Sockets";
      D.19366 = MEM[(const unsigned char *)D.19365];
      D.19367 = (int) D.19366;
      D.19368 = *__s2;
      D.19369 = (int) D.19368;
      __result = D.19367 - D.19369;
      {
        if (__s1_len != 0) goto <D.19370>; else goto <D.19371>;
        <D.19370>:
        if (__result == 0) goto <D.19372>; else goto <D.19373>;
        <D.19372>:
        D.19374 = &MEM[(void *)"System.Net.Sockets" + 1B];
        D.19375 = *D.19374;
        D.19376 = (int) D.19375;
        D.19377 = __s2 + 1;
        D.19378 = *D.19377;
        D.19379 = (int) D.19378;
        __result = D.19376 - D.19379;
        if (__s1_len > 1) goto <D.19380>; else goto <D.19381>;
        <D.19380>:
        if (__result == 0) goto <D.19382>; else goto <D.19383>;
        <D.19382>:
        D.19384 = &MEM[(void *)"System.Net.Sockets" + 2B];
        D.19385 = *D.19384;
        D.19386 = (int) D.19385;
        D.19387 = __s2 + 2;
        D.19388 = *D.19387;
        D.19389 = (int) D.19388;
        __result = D.19386 - D.19389;
        if (__s1_len > 2) goto <D.19390>; else goto <D.19391>;
        <D.19390>:
        if (__result == 0) goto <D.19392>; else goto <D.19393>;
        <D.19392>:
        D.19394 = &MEM[(void *)"System.Net.Sockets" + 3B];
        D.19395 = *D.19394;
        D.19396 = (int) D.19395;
        D.19397 = __s2 + 3;
        D.19398 = *D.19397;
        D.19399 = (int) D.19398;
        __result = D.19396 - D.19399;
        <D.19393>:
        <D.19391>:
        <D.19383>:
        <D.19381>:
        <D.19373>:
        <D.19371>:
      }
      D.18188 = __result;
    }
    iftmp.35 = D.18188;
    goto <D.19400>;
    <D.19364>:
    D.19401 = klass->name_space;
    iftmp.35 = __builtin_strcmp ("System.Net.Sockets", D.19401);
    <D.19400>:
    D.18192 = iftmp.35;
  }
  if (D.18192 == 0) goto <D.19402>; else goto <D.19403>;
  <D.19402>:
  domain->socket_class = klass;
  D.19315 = 1;
  return D.19315;
  <D.19403>:
  <D.19361>:
  <D.19319>:
  D.19315 = 0;
  return D.19315;
}


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

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


is_system_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoImage * D.19407;
  struct MonoImage * D.19410;
  gboolean D.19411;
  struct MonoImage * D.19412;
  _Bool D.19413;

  D.19407 = domain->system_image;
  if (D.19407 == 0B) goto <D.19408>; else goto <D.19409>;
  <D.19408>:
  D.19410 = mono_image_loaded ("System");
  domain->system_image = D.19410;
  <D.19409>:
  D.19412 = klass->image;
  D.19407 = domain->system_image;
  D.19413 = D.19412 == D.19407;
  D.19411 = (gboolean) D.19413;
  return D.19411;
}


threadpool_jobs_dec (struct MonoObject * obj)
{
  gboolean D.19417;
  struct MonoVTable * D.19418;
  volatile int * D.19419;
  void * D.19422;
  struct MonoDomain * domain;
  int remaining_jobs;

  if (obj == 0B) goto <D.19415>; else goto <D.19416>;
  <D.19415>:
  D.19417 = 0;
  return D.19417;
  <D.19416>:
  D.19418 = obj->vtable;
  domain = D.19418->domain;
  D.19419 = &domain->threadpool_jobs;
  remaining_jobs = InterlockedDecrement (D.19419);
  if (remaining_jobs == 0) goto <D.19420>; else goto <D.19421>;
  <D.19420>:
  D.19422 = domain->cleanup_semaphore;
  if (D.19422 != 0B) goto <D.19423>; else goto <D.19424>;
  <D.19423>:
  D.19422 = domain->cleanup_semaphore;
  ReleaseSemaphore (D.19422, 1, 0B);
  D.19417 = 1;
  return D.19417;
  <D.19424>:
  <D.19421>:
  D.19417 = 0;
  return D.19417;
}


process_idle_times (struct ThreadPool * tp, gint64 t)
{
  int D.19428;
  volatile gint * D.19430;
  int D.19431;
  int D.19433;
  long long int D.19436;
  long long int D.19437;
  int D.19438;
  int D.19439;
  long long int D.19440;
  long long int D.19444;
  long long int D.19447;
  long long int D.19448;
  long long int D.19453;
  int D.19454;
  long long int D.19455;
  long long int D.19456;
  long long int D.19460;
  long long int D.19461;
  long long int D.19462;
  long long int D.19467;
  int D.19477;
  int D.19480;
  int D.19485;
  volatile gint * D.19488;
  int D.19489;
  gint64 ticks;
  gint64 avg;
  gboolean compute_avg;
  gint new_threads;
  gint64 per1;

  D.19428 = tp->ignore_times;
  if (D.19428 != 0) goto <D.19426>; else goto <D.19429>;
  <D.19429>:
  if (t <= 0) goto <D.19426>; else goto <D.19427>;
  <D.19426>:
  return;
  <D.19427>:
  compute_avg = 0;
  ticks = mono_100ns_ticks ();
  t = ticks - t;
  <D.18609>:
  D.19430 = &tp->sp_lock;
  D.19431 = InterlockedCompareExchange (D.19430, 1, 0);
  if (D.19431 == 0) goto <D.18608>; else goto <D.19432>;
  <D.19432>:
  goto <D.18609>;
  <D.18608>:
  D.19433 = tp->ignore_times;
  if (D.19433 != 0) goto <D.19434>; else goto <D.19435>;
  <D.19434>:
  tp->sp_lock = 0;
  return;
  <D.19435>:
  D.19436 = tp->time_sum;
  D.19437 = D.19436 + t;
  tp->time_sum = D.19437;
  D.19438 = tp->n_sum;
  D.19439 = D.19438 + 1;
  tp->n_sum = D.19439;
  D.19440 = tp->last_check;
  if (D.19440 == 0) goto <D.19441>; else goto <D.19442>;
  <D.19441>:
  tp->last_check = ticks;
  goto <D.19443>;
  <D.19442>:
  D.19444 = tp->last_check;
  if (D.19444 > 0) goto <D.19445>; else goto <D.19446>;
  <D.19445>:
  D.19447 = tp->last_check;
  D.19448 = ticks - D.19447;
  if (D.19448 > 5000000) goto <D.19449>; else goto <D.19450>;
  <D.19449>:
  tp->ignore_times = 1;
  compute_avg = 1;
  <D.19450>:
  <D.19446>:
  <D.19443>:
  tp->sp_lock = 0;
  if (compute_avg == 0) goto <D.19451>; else goto <D.19452>;
  <D.19451>:
  return;
  <D.19452>:
  tp->last_check = ticks;
  new_threads = 0;
  D.19453 = tp->time_sum;
  D.19454 = tp->n_sum;
  D.19455 = (long long int) D.19454;
  avg = D.19453 / D.19455;
  D.19456 = tp->averages[1];
  if (D.19456 == 0) goto <D.19457>; else goto <D.19458>;
  <D.19457>:
  tp->averages[1] = avg;
  goto <D.19459>;
  <D.19458>:
  D.19456 = tp->averages[1];
  D.19460 = avg - D.19456;
  D.19461 = ABS_EXPR <D.19460>;
  D.19462 = D.19461 * 100;
  D.19456 = tp->averages[1];
  per1 = D.19462 / D.19456;
  if (per1 > 5) goto <D.19463>; else goto <D.19464>;
  <D.19463>:
  D.19456 = tp->averages[1];
  if (D.19456 < avg) goto <D.19465>; else goto <D.19466>;
  <D.19465>:
  D.19456 = tp->averages[1];
  D.19467 = tp->averages[0];
  if (D.19456 < D.19467) goto <D.19468>; else goto <D.19469>;
  <D.19468>:
  new_threads = -1;
  goto <D.19470>;
  <D.19469>:
  new_threads = 1;
  <D.19470>:
  goto <D.19471>;
  <D.19466>:
  D.19456 = tp->averages[1];
  if (D.19456 > avg) goto <D.19472>; else goto <D.19473>;
  <D.19472>:
  D.19456 = tp->averages[1];
  D.19467 = tp->averages[0];
  if (D.19456 < D.19467) goto <D.19474>; else goto <D.19475>;
  <D.19474>:
  new_threads = 1;
  <D.19475>:
  <D.19473>:
  <D.19471>:
  goto <D.19476>;
  <D.19464>:
  {
    int min;
    int n;

    min = tp->min_threads;
    n = tp->nthreads;
    D.19477 = n - min;
    if (D.19477 < min) goto <D.19478>; else goto <D.19479>;
    <D.19478>:
    D.19480 = tp->busy_threads;
    if (D.19480 == n) goto <D.19481>; else goto <D.19482>;
    <D.19481>:
    new_threads = 1;
    <D.19482>:
    <D.19479>:
  }
  <D.19476>:
  <D.19459>:
  tp->time_sum = 0;
  tp->n_sum = 0;
  D.19456 = tp->averages[1];
  tp->averages[0] = D.19456;
  tp->averages[1] = avg;
  tp->ignore_times = 0;
  if (new_threads == -1) goto <D.19483>; else goto <D.19484>;
  <D.19483>:
  D.19485 = tp->destroy_thread;
  if (D.19485 == 0) goto <D.19486>; else goto <D.19487>;
  <D.19486>:
  D.19488 = &tp->destroy_thread;
  D.19489 = InterlockedCompareExchange (D.19488, 1, 0);
  if (D.19489 == 0) goto <D.19490>; else goto <D.19491>;
  <D.19490>:
  pulse_on_new_job (tp);
  <D.19491>:
  <D.19487>:
  <D.19484>:
}


mono_async_invoke (struct ThreadPool * tp, struct MonoAsyncResult * ares)
{
  struct MonoAsyncResult * ares.36;
  struct MonoObject * D.19494;
  struct MonoObject * * D.19497;
  struct MonoObject * D.19498;
  struct MonoObject * pa.37;
  struct MonoObject * D.19503;
  struct MonoMethod * D.19504;
  struct MonoMethodMessage * D.19506;
  struct MonoObject * * D.19507;
  struct MonoObject * * D.19508;
  struct MonoObject * exc.38;
  struct MonoArray * * D.19510;
  struct MonoArray * out_args.39;
  struct MonoObject * D.19512;
  struct MonoMethod * D.19520;
  struct MonoDelegate * D.19522;
  struct MonoObject * cb_exc.40;
  struct MonoObject * D.19524;
  struct MonoObject * D.19527;
  struct ASyncCall * ac;
  struct MonoObject * res;
  struct MonoObject * exc;
  struct MonoArray * out_args;
  void * wait_event;
  struct MonoInternalThread * thread;

  try
    {
      ares.36 = ares;
      ac = ares.36->object_data;
      exc = 0B;
      out_args = 0B;
      wait_event = 0B;
      thread = mono_thread_internal_current ();
      ares.36 = ares;
      D.19494 = ares.36->execution_context;
      if (D.19494 != 0B) goto <D.19495>; else goto <D.19496>;
      <D.19495>:
      ares.36 = ares;
      ares.36 = ares;
      D.19497 = &ares.36->original_context;
      D.19498 = mono_thread_get_execution_context ();
      mono_gc_wbarrier_set_field (ares.36, D.19497, D.19498);
      ares.36 = ares;
      D.19494 = ares.36->execution_context;
      mono_thread_set_execution_context (D.19494);
      goto <D.19499>;
      <D.19496>:
      ares.36 = ares;
      ares.36->original_context = 0B;
      <D.19499>:
      if (ac == 0B) goto <D.19500>; else goto <D.19501>;
      <D.19500>:
      {
        void * pa;

        try
          {
            ares.36 = ares;
            pa.37 = ares.36->async_state;
            pa = pa.37;
            ares.36 = ares;
            D.19503 = ares.36->async_delegate;
            D.19504 = MEM[(struct MonoDelegate *)D.19503].method;
            thread->async_invoke_method = D.19504;
            ares.36 = ares;
            D.19503 = ares.36->async_delegate;
            res = mono_runtime_delegate_invoke (D.19503, &pa, &exc);
            thread->async_invoke_method = 0B;
          }
        finally
          {
            pa = {CLOBBER};
          }
      }
      goto <D.19505>;
      <D.19501>:
      {
        struct MonoObject * cb_exc;

        try
          {
            cb_exc = 0B;
            D.19506 = ac->msg;
            D.19506->exc = 0B;
            ares.36 = ares;
            D.19503 = ares.36->async_delegate;
            D.19506 = ac->msg;
            res = mono_message_invoke (D.19503, D.19506, &exc, &out_args);
            D.19507 = &ac->res;
            mono_gc_wbarrier_set_field (ac, D.19507, res);
            D.19506 = ac->msg;
            D.19508 = &D.19506->exc;
            exc.38 = exc;
            mono_gc_wbarrier_set_field (ac, D.19508, exc.38);
            D.19510 = &ac->out_args;
            out_args.39 = out_args;
            mono_gc_wbarrier_set_field (ac, D.19510, out_args.39);
            ares.36 = ares;
            mono_monitor_enter (ares.36);
            ares.36 = ares;
            ares.36->completed = 1;
            ares.36 = ares;
            D.19512 = ares.36->handle;
            if (D.19512 != 0B) goto <D.19513>; else goto <D.19514>;
            <D.19513>:
            ares.36 = ares;
            D.19512 = ares.36->handle;
            wait_event = mono_wait_handle_get_handle (D.19512);
            <D.19514>:
            ares.36 = ares;
            mono_monitor_exit (ares.36);
            if (wait_event != 0B) goto <D.19515>; else goto <D.19516>;
            <D.19515>:
            SetEvent (wait_event);
            <D.19516>:
            if (ac != 0B) goto <D.19519>; else goto <D.19517>;
            <D.19519>:
            D.19520 = ac->cb_method;
            if (D.19520 != 0B) goto <D.19521>; else goto <D.19517>;
            <D.19521>:
            {
              void * pa;

              pa = &ares;
              cb_exc = 0B;
              D.19520 = ac->cb_method;
              thread->async_invoke_method = D.19520;
              D.19520 = ac->cb_method;
              D.19522 = ac->cb_target;
              mono_runtime_invoke (D.19520, D.19522, pa, &cb_exc);
              thread->async_invoke_method = 0B;
              cb_exc.40 = cb_exc;
              exc = cb_exc.40;
            }
            goto <D.19518>;
            <D.19517>:
            exc = 0B;
            <D.19518>:
          }
        finally
          {
            cb_exc = {CLOBBER};
          }
      }
      <D.19505>:
      ares.36 = ares;
      D.19524 = ares.36->original_context;
      if (D.19524 != 0B) goto <D.19525>; else goto <D.19526>;
      <D.19525>:
      ares.36 = ares;
      D.19524 = ares.36->original_context;
      mono_thread_set_execution_context (D.19524);
      ares.36 = ares;
      ares.36->original_context = 0B;
      <D.19526>:
      D.19527 = exc;
      return D.19527;
    }
  finally
    {
      exc = {CLOBBER};
      out_args = {CLOBBER};
    }
}


create_simple_asyncresult (struct MonoObject * target, struct MonoObject * state)
{
  struct MonoClass * D.19530;
  struct MonoObject * * D.19531;
  struct MonoObject * * D.19532;
  struct MonoAsyncResult * D.19533;
  struct MonoDomain * domain;
  struct MonoAsyncResult * ares;

  domain = mono_domain_get ();
  D.19530 = mono_defaults.asyncresult_class;
  ares = mono_object_new (domain, D.19530);
  D.19531 = &ares->async_delegate;
  mono_gc_wbarrier_set_field (ares, D.19531, target);
  D.19532 = &ares->async_state;
  mono_gc_wbarrier_set_field (ares, D.19532, state);
  D.19533 = ares;
  return D.19533;
}


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

  thread = mono_thread_internal_current ();
  mono_thread_clr_state (thread, 4294967291);
  D.19535 = mono_thread_test_state (thread, 4);
  if (D.19535 == 0) goto <D.19536>; else goto <D.19537>;
  <D.19536>:
  ves_icall_System_Threading_Thread_SetState (thread, 4);
  <D.19537>:
}


check_for_interruption_critical ()
{
  unsigned int D.19538;
  unsigned int D.19539;
  struct MonoInternalThread * thread;

  mono_gc_set_skip_thread (0);
  thread = mono_thread_internal_current ();
  D.19538 = thread->state;
  D.19539 = D.19538 & 3;
  if (D.19539 != 0) goto <D.19540>; else goto <D.19541>;
  <D.19540>:
  mono_thread_interruption_checkpoint ();
  <D.19541>:
  mono_gc_set_skip_thread (1);
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.19542;
  unsigned int D.19543;

  D.19543 = __sync_sub_and_fetch_4 (val, 1);
  D.19542 = (gint32) D.19543;
  return D.19542;
}


should_i_die (struct ThreadPool * tp)
{
  int D.19545;
  volatile gint * D.19548;
  int D.19549;
  int D.19552;
  int D.19553;
  _Bool D.19554;
  gboolean D.19555;
  gboolean result;

  result = 0;
  D.19545 = tp->destroy_thread;
  if (D.19545 == 1) goto <D.19546>; else goto <D.19547>;
  <D.19546>:
  D.19548 = &tp->destroy_thread;
  D.19549 = InterlockedCompareExchange (D.19548, 0, 1);
  if (D.19549 == 1) goto <D.19550>; else goto <D.19551>;
  <D.19550>:
  D.19552 = tp->nthreads;
  D.19553 = tp->min_threads;
  D.19554 = D.19552 > D.19553;
  result = (gboolean) D.19554;
  <D.19551>:
  <D.19547>:
  D.19555 = result;
  return D.19555;
}


dequeue_or_steal (struct ThreadPool * tp, void * * data, struct MonoWSQ * local_wsq)
{
  int D.19557;
  gboolean D.19560;
  struct MonoCQ * D.19561;
  int D.19562;
  void * D.19565;
  _Bool D.19568;

  D.19557 = mono_runtime_is_shutting_down ();
  if (D.19557 != 0) goto <D.19558>; else goto <D.19559>;
  <D.19558>:
  D.19560 = 0;
  return D.19560;
  <D.19559>:
  D.19561 = tp->queue;
  mono_cq_dequeue (D.19561, data);
  D.19562 = tp->is_io;
  if (D.19562 == 0) goto <D.19563>; else goto <D.19564>;
  <D.19563>:
  D.19565 = *data;
  if (D.19565 == 0B) goto <D.19566>; else goto <D.19567>;
  <D.19566>:
  try_steal (local_wsq, data, 0);
  <D.19567>:
  <D.19564>:
  D.19565 = *data;
  D.19568 = D.19565 != 0B;
  D.19560 = (gboolean) D.19568;
  return D.19560;
}


try_steal (struct MonoWSQ * local_wsq, void * * data, gboolean retry)
{
  struct GPtrArray * wsqs.41;
  void * D.19575;
  int D.19576;
  _Bool D.19581;
  long int D.19582;
  long int D.19583;
  void * * D.19586;
  unsigned int i.42;
  unsigned int D.19588;
  void * * D.19589;
  int D.19593;
  void * D.19594;
  unsigned int ms.43;
  _Bool D.19600;
  long int D.19601;
  long int D.19602;
  unsigned int i.44;
  unsigned int D.19607;
  _Bool D.19610;
  long int D.19611;
  long int D.19612;
  int i;
  int ms;

  wsqs.41 = wsqs;
  if (wsqs.41 == 0B) goto <D.19570>; else goto <D.19573>;
  <D.19573>:
  if (data == 0B) goto <D.19570>; else goto <D.19574>;
  <D.19574>:
  D.19575 = *data;
  if (D.19575 != 0B) goto <D.19570>; else goto <D.19571>;
  <D.19570>:
  return;
  <D.19571>:
  ms = 0;
  <D.18592>:
  D.19576 = mono_runtime_is_shutting_down ();
  if (D.19576 != 0) goto <D.19577>; else goto <D.19578>;
  <D.19577>:
  return;
  <D.19578>:
  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19579>; else goto <D.19580>;
    <D.19579>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19580>:
    D.19581 = ret != 0;
    D.19582 = (long int) D.19581;
    D.19583 = __builtin_expect (D.19582, 0);
    if (D.19583 != 0) goto <D.19584>; else goto <D.19585>;
    <D.19584>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1282, "ret == 0");
    <D.19585>:
  }
  i = 0;
  goto <D.18589>;
  <D.18588>:
  {
    struct MonoWSQ * wsq;

    wsqs.41 = wsqs;
    D.19586 = wsqs.41->pdata;
    i.42 = (unsigned int) i;
    D.19588 = i.42 * 4;
    D.19589 = D.19586 + D.19588;
    wsq = *D.19589;
    if (wsq == local_wsq) goto <D.19590>; else goto <D.19592>;
    <D.19592>:
    D.19593 = mono_wsq_count (wsq);
    if (D.19593 == 0) goto <D.19590>; else goto <D.19591>;
    <D.19590>:
    // predicted unlikely by continue predictor.
    goto <D.18586>;
    <D.19591>:
    wsqs.41 = wsqs;
    D.19586 = wsqs.41->pdata;
    i.42 = (unsigned int) i;
    D.19588 = i.42 * 4;
    D.19589 = D.19586 + D.19588;
    D.19594 = *D.19589;
    ms.43 = (unsigned int) ms;
    mono_wsq_try_steal (D.19594, data, ms.43);
    D.19575 = *data;
    if (D.19575 != 0B) goto <D.19596>; else goto <D.19597>;
    <D.19596>:
    {
      int ret;

      ret = pthread_mutex_unlock (&wsqs_lock.mutex);
      if (ret != 0) goto <D.19598>; else goto <D.19599>;
      <D.19598>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19599>:
      D.19600 = ret != 0;
      D.19601 = (long int) D.19600;
      D.19602 = __builtin_expect (D.19601, 0);
      if (D.19602 != 0) goto <D.19603>; else goto <D.19604>;
      <D.19603>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1291, "ret == 0");
      <D.19604>:
    }
    return;
    <D.19597>:
  }
  <D.18586>:
  i = i + 1;
  <D.18589>:
  wsqs.41 = wsqs;
  if (wsqs.41 != 0B) goto <D.19605>; else goto <D.18590>;
  <D.19605>:
  i.44 = (unsigned int) i;
  wsqs.41 = wsqs;
  D.19607 = wsqs.41->len;
  if (i.44 < D.19607) goto <D.18588>; else goto <D.18590>;
  <D.18590>:
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.19608>; else goto <D.19609>;
    <D.19608>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19609>:
    D.19610 = ret != 0;
    D.19611 = (long int) D.19610;
    D.19612 = __builtin_expect (D.19611, 0);
    if (D.19612 != 0) goto <D.19613>; else goto <D.19614>;
    <D.19613>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1295, "ret == 0");
    <D.19614>:
  }
  ms = ms + 10;
  if (retry != 0) goto <D.19615>; else goto <D.18593>;
  <D.19615>:
  if (ms <= 10) goto <D.18592>; else goto <D.18593>;
  <D.18593>:
}


remove_wsq (struct MonoWSQ * wsq)
{
  _Bool D.19621;
  long int D.19622;
  long int D.19623;
  struct GPtrArray * wsqs.45;
  _Bool D.19631;
  long int D.19632;
  long int D.19633;
  int D.19636;
  void * data.46;
  int D.19640;
  _Bool D.19643;
  long int D.19644;
  long int D.19645;
  void * data;

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

        ret = pthread_mutex_lock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.19619>; else goto <D.19620>;
        <D.19619>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.19620>:
        D.19621 = ret != 0;
        D.19622 = (long int) D.19621;
        D.19623 = __builtin_expect (D.19622, 0);
        if (D.19623 != 0) goto <D.19624>; else goto <D.19625>;
        <D.19624>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1247, "ret == 0");
        <D.19625>:
      }
      wsqs.45 = wsqs;
      if (wsqs.45 == 0B) goto <D.19627>; else goto <D.19628>;
      <D.19627>:
      {
        int ret;

        ret = pthread_mutex_unlock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.19629>; else goto <D.19630>;
        <D.19629>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19630>:
        D.19631 = ret != 0;
        D.19632 = (long int) D.19631;
        D.19633 = __builtin_expect (D.19632, 0);
        if (D.19633 != 0) goto <D.19634>; else goto <D.19635>;
        <D.19634>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1249, "ret == 0");
        <D.19635>:
      }
      return;
      <D.19628>:
      wsqs.45 = wsqs;
      monoeg_g_ptr_array_remove_fast (wsqs.45, wsq);
      data = 0B;
      D.19636 = mono_runtime_is_shutting_down ();
      if (D.19636 != 0) goto <D.19637>; else goto <D.19638>;
      <D.19637>:
      goto <D.18574>;
      <D.18573>:
      data.46 = data;
      threadpool_jobs_dec (data.46);
      data = 0B;
      <D.18574>:
      D.19640 = mono_wsq_local_pop (&data);
      if (D.19640 != 0) goto <D.18573>; else goto <D.18575>;
      <D.18575>:
      <D.19638>:
      mono_wsq_destroy (wsq);
      {
        int ret;

        ret = pthread_mutex_unlock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.19641>; else goto <D.19642>;
        <D.19641>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19642>:
        D.19643 = ret != 0;
        D.19644 = (long int) D.19643;
        D.19645 = __builtin_expect (D.19644, 0);
        if (D.19645 != 0) goto <D.19646>; else goto <D.19647>;
        <D.19646>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1265, "ret == 0");
        <D.19647>:
      }
    }
  finally
    {
      data = {CLOBBER};
    }
}


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

  thread = mono_thread_internal_current ();
  D.19651 = thread->tid;
  D.19652 = (unsigned int) D.19651;
  mono_profiler_thread_end (D.19652);
}


atoi (const char * __nptr)
{
  int D.19653;

  D.19653 = strtol (__nptr, 0B, 10);
  return D.19653;
}


threadpool_init (struct ThreadPool * tp, int min_threads, int max_threads, void (*<Tb30>) (void *) async_invoke)
{
  struct MonoCQ * D.19655;
  union MonoSemType * D.19656;

  memset (tp, 0, 136);
  tp->min_threads = min_threads;
  tp->max_threads = max_threads;
  tp->async_invoke = async_invoke;
  D.19655 = mono_cq_create ();
  tp->queue = D.19655;
  D.19656 = &tp->new_job;
  sem_init (D.19656, 0, 0);
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.19659;
  int D.19664;
  void * D.19666;
  unsigned int D.19667;

  D.19659 = __builtin_constant_p (__len);
  if (D.19659 != 0) goto <D.19660>; else goto <D.19661>;
  <D.19660>:
  if (__len == 0) goto <D.19662>; else goto <D.19663>;
  <D.19662>:
  D.19664 = __builtin_constant_p (__ch);
  if (D.19664 == 0) goto <D.19657>; else goto <D.19665>;
  <D.19665>:
  if (__ch != 0) goto <D.19657>; else goto <D.19658>;
  <D.19657>:
  __warn_memset_zero_len ();
  D.19666 = __dest;
  return D.19666;
  <D.19658>:
  <D.19663>:
  <D.19661>:
  D.19667 = __builtin_object_size (__dest, 0);
  D.19666 = __builtin___memset_chk (__dest, __ch, __len, D.19667);
  return D.19666;
}


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

  try
    {
      if (category == 0B) goto <D.19669>; else goto <D.19671>;
      <D.19671>:
      if (counter == 0B) goto <D.19669>; else goto <D.19670>;
      <D.19669>:
      D.19672 = 0B;
      return D.19672;
      <D.19670>:
      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.19672 = mono_perfcounter_get_impl (category_str, counter_str, 0B, machine, &type, &custom);
      return D.19672;
    }
  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.19677;
  int D.19679;
  struct MonoGHashTable * D.19681;
  int D.19682;
  struct MonoAsyncResult * * D.19685;
  void * D.19686;
  union mono_mutex_t * D.19687;
  _Bool D.19690;
  long int D.19691;
  long int D.19692;
  _Bool D.19699;
  long int D.19700;
  long int D.19701;
  const void * fd.47;
  void (*<T2ee9>) (void *, int, int, int, gboolean) D.19708;
  int D.19709;
  struct MonoMList * list;
  struct SocketIOData * data;
  int fd;
  gboolean is_new;
  int ievt;

  data = &socket_io_data;
  socket_io_init (&socket_io_data);
  D.19677 = mono_runtime_is_shutting_down ();
  if (D.19677 != 0) goto <D.19675>; else goto <D.19678>;
  <D.19678>:
  D.19679 = data->inited;
  if (D.19679 == 3) goto <D.19675>; else goto <D.19680>;
  <D.19680>:
  D.19681 = data->sock_to_state;
  if (D.19681 == 0B) goto <D.19675>; else goto <D.19676>;
  <D.19675>:
  return;
  <D.19676>:
  D.19682 = async_tp.pool_status;
  if (D.19682 == 2) goto <D.19683>; else goto <D.19684>;
  <D.19683>:
  return;
  <D.19684>:
  D.19685 = &state->ares;
  mono_gc_wbarrier_set_field (state, D.19685, ares);
  D.19686 = state->handle;
  fd = (int) D.19686;
  {
    int ret;

    D.19687 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.19687);
    if (ret != 0) goto <D.19688>; else goto <D.19689>;
    <D.19688>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19689>:
    D.19690 = ret != 0;
    D.19691 = (long int) D.19690;
    D.19692 = __builtin_expect (D.19691, 0);
    if (D.19692 != 0) goto <D.19693>; else goto <D.19694>;
    <D.19693>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 546, "ret == 0");
    <D.19694>:
  }
  D.19681 = data->sock_to_state;
  if (D.19681 == 0B) goto <D.19695>; else goto <D.19696>;
  <D.19695>:
  {
    int ret;

    D.19687 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.19687);
    if (ret != 0) goto <D.19697>; else goto <D.19698>;
    <D.19697>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19698>:
    D.19699 = ret != 0;
    D.19700 = (long int) D.19699;
    D.19701 = __builtin_expect (D.19700, 0);
    if (D.19701 != 0) goto <D.19702>; else goto <D.19703>;
    <D.19702>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 548, "ret == 0");
    <D.19703>:
  }
  return;
  <D.19696>:
  D.19681 = data->sock_to_state;
  fd.47 = (const void *) fd;
  list = mono_g_hash_table_lookup (D.19681, fd.47);
  if (list == 0B) goto <D.19705>; else goto <D.19706>;
  <D.19705>:
  list = mono_mlist_alloc (state);
  is_new = 1;
  goto <D.19707>;
  <D.19706>:
  list = mono_mlist_append (list, state);
  is_new = 0;
  <D.19707>:
  D.19681 = data->sock_to_state;
  D.19686 = state->handle;
  mono_g_hash_table_replace (D.19681, D.19686, list);
  ievt = get_events_from_list (list);
  D.19708 = data->modify;
  D.19709 = state->operation;
  D.19708 (data, fd, D.19709, ievt, is_new);
}


socket_io_init (struct SocketIOData * data)
{
  int D.19711;
  int * D.19714;
  union mono_mutex_t * D.19719;
  _Bool D.19722;
  long int D.19723;
  long int D.19724;
  struct MonoGHashTable * D.19727;
  const gchar * D.19728;
  struct MonoDomain * D.19731;
  void (*<Tb30>) (void *) D.19732;
  _Bool D.19735;
  long int D.19736;
  long int D.19737;
  int inited;

  D.19711 = data->inited;
  if (D.19711 > 1) goto <D.19712>; else goto <D.19713>;
  <D.19712>:
  return;
  <D.19713>:
  D.19714 = &data->inited;
  inited = InterlockedCompareExchange (D.19714, 1, 0);
  if (inited > 0) goto <D.19715>; else goto <D.19716>;
  <D.19715>:
  <D.18344>:
  D.19711 = data->inited;
  if (D.19711 > 1) goto <D.19717>; else goto <D.19718>;
  <D.19717>:
  return;
  <D.19718>:
  SleepEx (1, 0);
  goto <D.18344>;
  <D.19716>:
  {
    int ret;

    D.19719 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.19719);
    if (ret != 0) goto <D.19720>; else goto <D.19721>;
    <D.19720>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19721>:
    D.19722 = ret != 0;
    D.19723 = (long int) D.19722;
    D.19724 = __builtin_expect (D.19723, 0);
    if (D.19724 != 0) goto <D.19725>; else goto <D.19726>;
    <D.19725>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 509, "ret == 0");
    <D.19726>:
  }
  D.19727 = mono_g_hash_table_new_type (monoeg_g_direct_hash, monoeg_g_direct_equal, 2);
  data->sock_to_state = D.19727;
  data->event_system = 1;
  D.19728 = monoeg_g_getenv ("MONO_DISABLE_AIO");
  if (D.19728 != 0B) goto <D.19729>; else goto <D.19730>;
  <D.19729>:
  data->event_system = 0;
  <D.19730>:
  init_event_system (data);
  D.19731 = mono_get_root_domain ();
  D.19732 = data->wait;
  mono_thread_create_internal (D.19731, D.19732, data, 1, 0, 131072);
  {
    int ret;

    D.19719 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.19719);
    if (ret != 0) goto <D.19733>; else goto <D.19734>;
    <D.19733>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19734>:
    D.19735 = ret != 0;
    D.19736 = (long int) D.19735;
    D.19737 = __builtin_expect (D.19736, 0);
    if (D.19737 != 0) goto <D.19738>; else goto <D.19739>;
    <D.19738>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 523, "ret == 0");
    <D.19739>:
  }
  data->inited = 2;
  threadpool_start_thread (&async_io_tp);
}


init_event_system (struct SocketIOData * data)
{
  int D.19741;
  void * D.19744;
  void * D.19745;
  const gchar * D.19748;
  void * D.19753;

  D.19741 = data->event_system;
  if (D.19741 == 1) goto <D.19742>; else goto <D.19743>;
  <D.19742>:
  D.19744 = tp_epoll_init (data);
  data->event_data = D.19744;
  D.19745 = data->event_data;
  if (D.19745 == 0B) goto <D.19746>; else goto <D.19747>;
  <D.19746>:
  D.19748 = monoeg_g_getenv ("MONO_DEBUG");
  if (D.19748 != 0B) goto <D.19749>; else goto <D.19750>;
  <D.19749>:
  monoeg_g_log (0B, 32, "Falling back to poll()");
  <D.19750>:
  data->event_system = 0;
  <D.19747>:
  <D.19743>:
  D.19741 = data->event_system;
  if (D.19741 == 0) goto <D.19751>; else goto <D.19752>;
  <D.19751>:
  D.19753 = tp_poll_init (data);
  data->event_data = D.19753;
  <D.19752>:
}


tp_epoll_init (struct SocketIOData * data)
{
  int D.19754;
  int D.19755;
  int * D.19758;
  const gchar * D.19759;
  const gchar * D.19762;
  void * D.19763;
  struct tp_epoll_data * result;

  result = monoeg_malloc0 (4);
  D.19754 = epoll_create1 (524288);
  result->epollfd = D.19754;
  D.19755 = result->epollfd;
  if (D.19755 == -1) goto <D.19756>; else goto <D.19757>;
  <D.19756>:
  {
    int err;

    D.19758 = __errno_location ();
    err = *D.19758;
    D.19759 = monoeg_g_getenv ("MONO_DEBUG");
    if (D.19759 != 0B) goto <D.19760>; else goto <D.19761>;
    <D.19760>:
    D.19762 = monoeg_g_strerror (err);
    monoeg_g_log (0B, 32, "epoll_create1(EPOLL_CLOEXEC) failed: %d %s", err, D.19762);
    <D.19761>:
    D.19763 = 0B;
    return D.19763;
  }
  <D.19757>:
  data->shutdown = tp_epoll_shutdown;
  data->modify = tp_epoll_modify;
  data->wait = tp_epoll_wait;
  D.19763 = result;
  return D.19763;
}


tp_epoll_wait (void * p)
{
  int * D.19768;
  int D.19769;
  const gchar * D.19774;
  union mono_mutex_t * D.19775;
  _Bool D.19778;
  long int D.19779;
  long int D.19780;
  int D.19783;
  _Bool D.19788;
  long int D.19789;
  long int D.19790;
  unsigned int i.48;
  unsigned int D.19794;
  struct MonoGHashTable * D.19795;
  const void * fd.49;
  void * list.50;
  struct MonoMList * list.51;
  unsigned int D.19801;
  unsigned int D.19802;
  int nresults.52;
  unsigned int D.19810;
  int nresults.53;
  void * fd.54;
  unsigned int p.55;
  unsigned int D.19820;
  unsigned int D.19821;
  unsigned int D.19822;
  int D.19823;
  int D.19826;
  const gchar * D.19829;
  _Bool D.19833;
  long int D.19834;
  long int D.19835;
  unsigned int nresults.56;
  unsigned int D.19839;
  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 (2048);
      <D.18136>:
      mono_gc_set_skip_thread (1);
      <D.18122>:
      if (ready == -1) goto <D.19765>; else goto <D.19766>;
      <D.19765>:
      check_for_interruption_critical ();
      <D.19766>:
      ready = epoll_wait (epollfd, events, 128, -1);
      if (ready == -1) goto <D.19767>; else goto <D.18123>;
      <D.19767>:
      D.19768 = __errno_location ();
      D.19769 = *D.19768;
      if (D.19769 == 4) goto <D.18122>; else goto <D.18123>;
      <D.18123>:
      mono_gc_set_skip_thread (0);
      if (ready == -1) goto <D.19770>; else goto <D.19771>;
      <D.19770>:
      {
        int err;

        D.19768 = __errno_location ();
        err = *D.19768;
        monoeg_g_free (events);
        if (err != 9) goto <D.19772>; else goto <D.19773>;
        <D.19772>:
        D.19774 = monoeg_g_strerror (err);
        monoeg_g_log (0B, 16, "epoll_wait: %d %s", err, D.19774);
        <D.19773>:
        return;
      }
      <D.19771>:
      {
        int ret;

        D.19775 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_lock (D.19775);
        if (ret != 0) goto <D.19776>; else goto <D.19777>;
        <D.19776>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.19777>:
        D.19778 = ret != 0;
        D.19779 = (long int) D.19778;
        D.19780 = __builtin_expect (D.19779, 0);
        if (D.19780 != 0) goto <D.19781>; else goto <D.19782>;
        <D.19781>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 132, "ret == 0");
        <D.19782>:
      }
      D.19783 = socket_io_data->inited;
      if (D.19783 == 3) goto <D.19784>; else goto <D.19785>;
      <D.19784>:
      monoeg_g_free (events);
      {
        int ret;

        D.19775 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.19775);
        if (ret != 0) goto <D.19786>; else goto <D.19787>;
        <D.19786>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19787>:
        D.19788 = ret != 0;
        D.19789 = (long int) D.19788;
        D.19790 = __builtin_expect (D.19789, 0);
        if (D.19790 != 0) goto <D.19791>; else goto <D.19792>;
        <D.19791>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 135, "ret == 0");
        <D.19792>:
      }
      return;
      <D.19785>:
      nresults = 0;
      i = 0;
      goto <D.18133>;
      <D.18132>:
      {
        int fd;
        struct MonoMList * list;
        struct MonoObject * ares;

        try
          {
            i.48 = (unsigned int) i;
            D.19794 = i.48 * 16;
            evt = events + D.19794;
            fd = evt->data.fd;
            D.19795 = socket_io_data->sock_to_state;
            fd.49 = (const void *) fd;
            list.50 = mono_g_hash_table_lookup (D.19795, fd.49);
            list = list.50;
            list.51 = list;
            if (list.51 != 0B) goto <D.19799>; else goto <D.19800>;
            <D.19799>:
            D.19801 = evt->events;
            D.19802 = D.19801 & 25;
            if (D.19802 != 0) goto <D.19803>; else goto <D.19804>;
            <D.19803>:
            ares = get_io_event (&list, 1);
            if (ares != 0B) goto <D.19805>; else goto <D.19806>;
            <D.19805>:
            nresults.52 = nresults;
            nresults = nresults.52 + 1;
            async_results[nresults.52] = ares;
            <D.19806>:
            <D.19804>:
            <D.19800>:
            list.51 = list;
            if (list.51 != 0B) goto <D.19808>; else goto <D.19809>;
            <D.19808>:
            D.19801 = evt->events;
            D.19810 = D.19801 & 28;
            if (D.19810 != 0) goto <D.19811>; else goto <D.19812>;
            <D.19811>:
            ares = get_io_event (&list, 4);
            if (ares != 0B) goto <D.19813>; else goto <D.19814>;
            <D.19813>:
            nresults.53 = nresults;
            nresults = nresults.53 + 1;
            async_results[nresults.53] = ares;
            <D.19814>:
            <D.19812>:
            <D.19809>:
            list.51 = list;
            if (list.51 != 0B) goto <D.19816>; else goto <D.19817>;
            <D.19816>:
            {
              int p;

              D.19795 = socket_io_data->sock_to_state;
              fd.54 = (void *) fd;
              list.51 = list;
              mono_g_hash_table_replace (D.19795, fd.54, list.51);
              list.51 = list;
              p = get_events_from_list (list.51);
              p.55 = (unsigned int) p;
              D.19820 = p.55 & 4;
              evt->events = D.19820;
              D.19801 = evt->events;
              p.55 = (unsigned int) p;
              D.19821 = p.55 & 1;
              D.19822 = D.19801 | D.19821;
              evt->events = D.19822;
              D.19823 = epoll_ctl (epollfd, 3, fd, evt);
              if (D.19823 == -1) goto <D.19824>; else goto <D.19825>;
              <D.19824>:
              D.19826 = epoll_ctl (epollfd, 1, fd, evt);
              if (D.19826 == -1) goto <D.19827>; else goto <D.19828>;
              <D.19827>:
              {
                int err;

                D.19768 = __errno_location ();
                err = *D.19768;
                D.19829 = monoeg_g_strerror (err);
                monoeg_g_log (0B, 32, "epoll(ADD): %d %s", err, D.19829);
              }
              <D.19828>:
              <D.19825>:
            }
            goto <D.19830>;
            <D.19817>:
            D.19795 = socket_io_data->sock_to_state;
            fd.49 = (const void *) fd;
            mono_g_hash_table_remove (D.19795, fd.49);
            epoll_ctl (epollfd, 2, fd, evt);
            <D.19830>:
          }
        finally
          {
            list = {CLOBBER};
          }
      }
      i = i + 1;
      <D.18133>:
      if (i < ready) goto <D.18132>; else goto <D.18134>;
      <D.18134>:
      {
        int ret;

        D.19775 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.19775);
        if (ret != 0) goto <D.19831>; else goto <D.19832>;
        <D.19831>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19832>:
        D.19833 = ret != 0;
        D.19834 = (long int) D.19833;
        D.19835 = __builtin_expect (D.19834, 0);
        if (D.19835 != 0) goto <D.19836>; else goto <D.19837>;
        <D.19836>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 178, "ret == 0");
        <D.19837>:
      }
      threadpool_append_jobs (&async_io_tp, &async_results, nresults);
      nresults.56 = (unsigned int) nresults;
      D.19839 = nresults.56 * 4;
      mono_gc_bzero_aligned (&async_results, D.19839);
      goto <D.18136>;
    }
  finally
    {
      async_results = {CLOBBER};
    }
}


tp_epoll_modify (void * p, int fd, int operation, int events, gboolean is_new)
{
  int D.19842;
  unsigned int D.19845;
  unsigned int D.19846;
  int D.19847;
  unsigned int D.19850;
  int iftmp.57;
  int D.19855;
  int D.19856;
  int * D.19859;
  int D.19864;
  const gchar * D.19867;
  union mono_mutex_t * D.19868;
  _Bool D.19871;
  long int D.19872;
  long int D.19873;
  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, 16);
      evt.data.fd = fd;
      D.19842 = events & 1;
      if (D.19842 != 0) goto <D.19843>; else goto <D.19844>;
      <D.19843>:
      D.19845 = evt.events;
      D.19846 = D.19845 | 1;
      evt.events = D.19846;
      <D.19844>:
      D.19847 = events & 4;
      if (D.19847 != 0) goto <D.19848>; else goto <D.19849>;
      <D.19848>:
      D.19845 = evt.events;
      D.19850 = D.19845 | 4;
      evt.events = D.19850;
      <D.19849>:
      if (is_new != 0) goto <D.19852>; else goto <D.19853>;
      <D.19852>:
      iftmp.57 = 1;
      goto <D.19854>;
      <D.19853>:
      iftmp.57 = 3;
      <D.19854>:
      epoll_op = iftmp.57;
      D.19855 = data->epollfd;
      D.19856 = epoll_ctl (D.19855, epoll_op, fd, &evt);
      if (D.19856 == -1) goto <D.19857>; else goto <D.19858>;
      <D.19857>:
      {
        int err;

        D.19859 = __errno_location ();
        err = *D.19859;
        if (epoll_op == 1) goto <D.19860>; else goto <D.19861>;
        <D.19860>:
        if (err == 17) goto <D.19862>; else goto <D.19863>;
        <D.19862>:
        epoll_op = 3;
        D.19855 = data->epollfd;
        D.19864 = epoll_ctl (D.19855, epoll_op, fd, &evt);
        if (D.19864 == -1) goto <D.19865>; else goto <D.19866>;
        <D.19865>:
        D.19867 = monoeg_g_strerror (err);
        monoeg_g_log (0B, 32, "epoll_ctl(MOD): %d %s", err, D.19867);
        <D.19866>:
        <D.19863>:
        <D.19861>:
      }
      <D.19858>:
      {
        int ret;

        D.19868 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.19868);
        if (ret != 0) goto <D.19869>; else goto <D.19870>;
        <D.19869>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19870>:
        D.19871 = ret != 0;
        D.19872 = (long int) D.19871;
        D.19873 = __builtin_expect (D.19872, 0);
        if (D.19873 != 0) goto <D.19874>; else goto <D.19875>;
        <D.19874>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 81, "ret == 0");
        <D.19875>:
      }
    }
  finally
    {
      evt = {CLOBBER};
    }
}


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

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


tp_poll_init (struct SocketIOData * data)
{
  int[2] * D.19877;
  int D.19878;
  int * D.19881;
  _Bool D.19882;
  long int D.19883;
  long int D.19884;
  union MonoSemType * D.19887;
  void * D.19888;
  struct tp_poll_data * result;

  result = monoeg_malloc0 (32);
  D.19877 = &result->pipe;
  D.19878 = pipe (D.19877);
  if (D.19878 != 0) goto <D.19879>; else goto <D.19880>;
  <D.19879>:
  {
    int err;

    D.19881 = __errno_location ();
    err = *D.19881;
    perror ("mono");
    D.19882 = err == 0;
    D.19883 = (long int) D.19882;
    D.19884 = __builtin_expect (D.19883, 0);
    if (D.19884 != 0) goto <D.19885>; else goto <D.19886>;
    <D.19885>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 41, "err");
    <D.19886>:
  }
  <D.19880>:
  D.19887 = &result->new_sem;
  sem_init (D.19887, 0, 1);
  data->shutdown = tp_poll_shutdown;
  data->modify = tp_poll_modify;
  data->wait = tp_poll_wait;
  D.19888 = result;
  return D.19888;
}


tp_poll_wait (void * p)
{
  unsigned int allocated.58;
  unsigned int D.19891;
  int D.19892;
  int D.19893;
  void * iftmp.59;
  void * D.19897;
  int D.19899;
  unsigned int i.60;
  unsigned int D.19901;
  struct mono_pollfd * D.19902;
  unsigned int maxfd.61;
  int * D.19907;
  int D.19908;
  short int D.19913;
  unsigned short D.19914;
  int D.19915;
  int D.19916;
  int D.19919;
  void * * D.19922;
  int D.19923;
  int D.19926;
  int D.19927;
  short int D.19939;
  struct mono_pollfd * D.19940;
  union MonoSemType * D.19941;
  union mono_mutex_t * D.19946;
  _Bool D.19949;
  long int D.19950;
  long int D.19951;
  int D.19954;
  _Bool D.19961;
  long int D.19962;
  long int D.19963;
  unsigned int D.19966;
  unsigned int D.19967;
  short int D.19971;
  struct MonoGHashTable * D.19972;
  const void * D.19973;
  void * list.62;
  struct MonoMList * list.63;
  unsigned short D.19978;
  int D.19979;
  int D.19980;
  int D.19985;
  unsigned int D.19988;
  int D.19989;
  void * D.19990;
  int D.19993;
  int D.19994;
  unsigned int D.19995;
  unsigned int D.19996;
  void * * D.19997;
  int D.20000;
  void * D.20007;
  int D.20010;
  int D.20011;
  unsigned int D.20012;
  unsigned int D.20013;
  void * * D.20014;
  void * D.20017;
  int D.20018;
  short int D.20019;
  int D.20021;
  _Bool D.20027;
  long int D.20028;
  long int D.20029;
  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;
      allocated.58 = (unsigned int) allocated;
      D.19891 = allocated.58 * 8;
      pfds = monoeg_malloc0 (D.19891);
      async_results.size = 0;
      D.19892 = allocated * 2;
      D.19893 = MAX_EXPR <D.19892, 16>;
      async_results.capacity = D.19893;
      D.19892 = allocated * 2;
      if (D.19892 > 16) goto <D.19895>; else goto <D.19896>;
      <D.19895>:
      allocated.58 = (unsigned int) allocated;
      D.19891 = allocated.58 * 8;
      D.19892 = allocated * 2;
      D.19897 = mono_gc_make_root_descr_all_refs (D.19892);
      iftmp.59 = mono_gc_alloc_fixed (D.19891, D.19897);
      goto <D.19898>;
      <D.19896>:
      iftmp.59 = __builtin_alloca (64);
      <D.19898>:
      async_results.data = iftmp.59;
      D.19899 = data->pipe[0];
      pfds->fd = D.19899;
      pfds->events = 1;
      pfds->revents = 0;
      i = 1;
      goto <D.18043>;
      <D.18042>:
      i.60 = (unsigned int) i;
      D.19901 = i.60 * 8;
      D.19902 = pfds + D.19901;
      D.19902->fd = -1;
      i.60 = (unsigned int) i;
      D.19901 = i.60 * 8;
      D.19902 = pfds + D.19901;
      D.19902->events = 0;
      i.60 = (unsigned int) i;
      D.19901 = i.60 * 8;
      D.19902 = pfds + D.19901;
      D.19902->revents = 0;
      i = i + 1;
      <D.18043>:
      if (i < allocated) goto <D.18042>; else goto <D.18044>;
      <D.18044>:
      <D.18074>:
      {
        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.18050>:
            if (nsock == -1) goto <D.19903>; else goto <D.19904>;
            <D.19903>:
            check_for_interruption_critical ();
            <D.19904>:
            maxfd.61 = (unsigned int) maxfd;
            nsock = mono_poll (pfds, maxfd.61, -1);
            if (nsock == -1) goto <D.19906>; else goto <D.18051>;
            <D.19906>:
            D.19907 = __errno_location ();
            D.19908 = *D.19907;
            if (D.19908 == 4) goto <D.18050>; else goto <D.18051>;
            <D.18051>:
            mono_gc_set_skip_thread (0);
            if (nsock == -1) goto <D.19909>; else goto <D.19910>;
            <D.19909>:
            D.19907 = __errno_location ();
            D.19908 = *D.19907;
            if (D.19908 == 9) goto <D.19911>; else goto <D.19912>;
            <D.19911>:
            pfds->revents = 0;
            nsock = mark_bad_fds (pfds, maxfd);
            <D.19912>:
            <D.19910>:
            D.19913 = pfds->revents;
            D.19914 = (unsigned short) D.19913;
            D.19915 = (int) D.19914;
            D.19916 = D.19915 & 56;
            if (D.19916 != 0) goto <D.19917>; else goto <D.19918>;
            <D.19917>:
            monoeg_g_free (pfds);
            D.19919 = async_results.capacity;
            if (D.19919 > 16) goto <D.19920>; else goto <D.19921>;
            <D.19920>:
            D.19922 = async_results.data;
            mono_gc_free_fixed (D.19922);
            <D.19921>:
            socket_io_cleanup (socket_io_data);
            return;
            <D.19918>:
            D.19913 = pfds->revents;
            D.19914 = (unsigned short) D.19913;
            D.19915 = (int) D.19914;
            D.19923 = D.19915 & 1;
            if (D.19923 != 0) goto <D.19924>; else goto <D.19925>;
            <D.19924>:
            {
              int nread;
              gboolean found;

              found = 0;
              i = 1;
              goto <D.18056>;
              <D.18055>:
              i.60 = (unsigned int) i;
              D.19901 = i.60 * 8;
              pfd = pfds + D.19901;
              D.19926 = pfd->fd;
              D.19927 = data->newpfd.fd;
              if (D.19926 == D.19927) goto <D.19928>; else goto <D.19929>;
              <D.19928>:
              found = 1;
              goto <D.18054>;
              <D.19929>:
              i = i + 1;
              <D.18056>:
              if (i < allocated) goto <D.18055>; else goto <D.18054>;
              <D.18054>:
              if (found == 0) goto <D.19930>; else goto <D.19931>;
              <D.19930>:
              i = 1;
              goto <D.18059>;
              <D.18058>:
              i.60 = (unsigned int) i;
              D.19901 = i.60 * 8;
              pfd = pfds + D.19901;
              D.19926 = pfd->fd;
              if (D.19926 == -1) goto <D.18057>; else goto <D.19932>;
              <D.19932>:
              i = i + 1;
              <D.18059>:
              if (i < allocated) goto <D.18058>; else goto <D.18057>;
              <D.18057>:
              <D.19931>:
              if (i == allocated) goto <D.19933>; else goto <D.19934>;
              <D.19933>:
              {
                struct mono_pollfd * oldfd;

                oldfd = pfds;
                i = allocated;
                allocated = allocated * 2;
                allocated.58 = (unsigned int) allocated;
                D.19891 = allocated.58 * 8;
                pfds = monoeg_realloc (oldfd, D.19891);
                monoeg_g_free (oldfd);
                goto <D.18062>;
                <D.18061>:
                i.60 = (unsigned int) i;
                D.19901 = i.60 * 8;
                D.19902 = pfds + D.19901;
                D.19902->fd = -1;
                i.60 = (unsigned int) i;
                D.19901 = i.60 * 8;
                D.19902 = pfds + D.19901;
                D.19902->events = 0;
                i.60 = (unsigned int) i;
                D.19901 = i.60 * 8;
                D.19902 = pfds + D.19901;
                D.19902->revents = 0;
                i = i + 1;
                <D.18062>:
                if (i < allocated) goto <D.18061>; else goto <D.18063>;
                <D.18063>:
              }
              <D.19934>:
              D.19899 = data->pipe[0];
              nread = read (D.19899, &one, 1);
              if (nread <= 0) goto <D.19935>; else goto <D.19936>;
              <D.19935>:
              monoeg_g_free (pfds);
              D.19919 = async_results.capacity;
              if (D.19919 > 16) goto <D.19937>; else goto <D.19938>;
              <D.19937>:
              D.19922 = async_results.data;
              mono_gc_free_fixed (D.19922);
              <D.19938>:
              return;
              <D.19936>:
              i.60 = (unsigned int) i;
              D.19901 = i.60 * 8;
              D.19902 = pfds + D.19901;
              D.19927 = data->newpfd.fd;
              D.19902->fd = D.19927;
              i.60 = (unsigned int) i;
              D.19901 = i.60 * 8;
              D.19902 = pfds + D.19901;
              D.19939 = data->newpfd.events;
              D.19902->events = D.19939;
              i.60 = (unsigned int) i;
              D.19901 = i.60 * 8;
              D.19902 = pfds + D.19901;
              D.19902->revents = 0;
              D.19940 = &data->newpfd;
              memset (D.19940, 0, 8);
              D.19941 = &data->new_sem;
              mono_sem_post (D.19941);
              if (i >= maxfd) goto <D.19942>; else goto <D.19943>;
              <D.19942>:
              maxfd = i + 1;
              <D.19943>:
              nsock = nsock + -1;
            }
            <D.19925>:
            if (nsock == 0) goto <D.19944>; else goto <D.19945>;
            <D.19944>:
            // predicted unlikely by continue predictor.
            goto <D.18064>;
            <D.19945>:
            {
              int ret;

              D.19946 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_lock (D.19946);
              if (ret != 0) goto <D.19947>; else goto <D.19948>;
              <D.19947>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
              <D.19948>:
              D.19949 = ret != 0;
              D.19950 = (long int) D.19949;
              D.19951 = __builtin_expect (D.19950, 0);
              if (D.19951 != 0) goto <D.19952>; else goto <D.19953>;
              <D.19952>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 273, "ret == 0");
              <D.19953>:
            }
            D.19954 = socket_io_data->inited;
            if (D.19954 == 3) goto <D.19955>; else goto <D.19956>;
            <D.19955>:
            monoeg_g_free (pfds);
            D.19919 = async_results.capacity;
            if (D.19919 > 16) goto <D.19957>; else goto <D.19958>;
            <D.19957>:
            D.19922 = async_results.data;
            mono_gc_free_fixed (D.19922);
            <D.19958>:
            {
              int ret;

              D.19946 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_unlock (D.19946);
              if (ret != 0) goto <D.19959>; else goto <D.19960>;
              <D.19959>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
              <D.19960>:
              D.19961 = ret != 0;
              D.19962 = (long int) D.19961;
              D.19963 = __builtin_expect (D.19962, 0);
              if (D.19963 != 0) goto <D.19964>; else goto <D.19965>;
              <D.19964>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 277, "ret == 0");
              <D.19965>:
            }
            return;
            <D.19956>:
            nresults = 0;
            async_results.size = 0;
            D.19922 = async_results.data;
            D.19919 = async_results.capacity;
            D.19966 = (unsigned int) D.19919;
            D.19967 = D.19966 * 4;
            mono_gc_bzero_aligned (D.19922, D.19967);
            i = 1;
            goto <D.18071>;
            <D.18070>:
            i.60 = (unsigned int) i;
            D.19901 = i.60 * 8;
            pfd = pfds + D.19901;
            D.19926 = pfd->fd;
            if (D.19926 == -1) goto <D.19968>; else goto <D.19970>;
            <D.19970>:
            D.19971 = pfd->revents;
            if (D.19971 == 0) goto <D.19968>; else goto <D.19969>;
            <D.19968>:
            // predicted unlikely by continue predictor.
            goto <D.18067>;
            <D.19969>:
            nsock = nsock + -1;
            D.19972 = socket_io_data->sock_to_state;
            D.19926 = pfd->fd;
            D.19973 = (const void *) D.19926;
            list.62 = mono_g_hash_table_lookup (D.19972, D.19973);
            list = list.62;
            list.63 = list;
            if (list.63 != 0B) goto <D.19976>; else goto <D.19977>;
            <D.19976>:
            D.19971 = pfd->revents;
            D.19978 = (unsigned short) D.19971;
            D.19979 = (int) D.19978;
            D.19980 = D.19979 & 57;
            if (D.19980 != 0) goto <D.19981>; else goto <D.19982>;
            <D.19981>:
            ares = get_io_event (&list, 1);
            if (ares != 0B) goto <D.19983>; else goto <D.19984>;
            <D.19983>:
            D.19985 = async_results.size;
            D.19919 = async_results.capacity;
            if (D.19985 >= D.19919) goto <D.19986>; else goto <D.19987>;
            <D.19986>:
            {
              void * __tmp;

              D.19919 = async_results.capacity;
              D.19966 = (unsigned int) D.19919;
              D.19988 = D.19966 * 8;
              D.19919 = async_results.capacity;
              D.19989 = D.19919 * 2;
              D.19990 = mono_gc_make_root_descr_all_refs (D.19989);
              __tmp = mono_gc_alloc_fixed (D.19988, D.19990);
              D.19922 = async_results.data;
              D.19919 = async_results.capacity;
              D.19966 = (unsigned int) D.19919;
              D.19967 = D.19966 * 4;
              mono_gc_memmove_aligned (__tmp, D.19922, D.19967);
              D.19919 = async_results.capacity;
              if (D.19919 > 16) goto <D.19991>; else goto <D.19992>;
              <D.19991>:
              D.19922 = async_results.data;
              mono_gc_free_fixed (D.19922);
              <D.19992>:
              async_results.data = __tmp;
              D.19919 = async_results.capacity;
              D.19989 = D.19919 * 2;
              async_results.capacity = D.19989;
            }
            <D.19987>:
            D.19922 = async_results.data;
            D.19985 = async_results.size;
            D.19993 = D.19985;
            D.19994 = D.19993 + 1;
            async_results.size = D.19994;
            D.19995 = (unsigned int) D.19993;
            D.19996 = D.19995 * 4;
            D.19997 = D.19922 + D.19996;
            *D.19997 = ares;
            nresults = nresults + 1;
            <D.19984>:
            <D.19982>:
            <D.19977>:
            list.63 = list;
            if (list.63 != 0B) goto <D.19998>; else goto <D.19999>;
            <D.19998>:
            D.19971 = pfd->revents;
            D.19978 = (unsigned short) D.19971;
            D.19979 = (int) D.19978;
            D.20000 = D.19979 & 60;
            if (D.20000 != 0) goto <D.20001>; else goto <D.20002>;
            <D.20001>:
            ares = get_io_event (&list, 4);
            if (ares != 0B) goto <D.20003>; else goto <D.20004>;
            <D.20003>:
            D.19985 = async_results.size;
            D.19919 = async_results.capacity;
            if (D.19985 >= D.19919) goto <D.20005>; else goto <D.20006>;
            <D.20005>:
            {
              void * __tmp;

              D.19919 = async_results.capacity;
              D.19966 = (unsigned int) D.19919;
              D.19988 = D.19966 * 8;
              D.19919 = async_results.capacity;
              D.19989 = D.19919 * 2;
              D.20007 = mono_gc_make_root_descr_all_refs (D.19989);
              __tmp = mono_gc_alloc_fixed (D.19988, D.20007);
              D.19922 = async_results.data;
              D.19919 = async_results.capacity;
              D.19966 = (unsigned int) D.19919;
              D.19967 = D.19966 * 4;
              mono_gc_memmove_aligned (__tmp, D.19922, D.19967);
              D.19919 = async_results.capacity;
              if (D.19919 > 16) goto <D.20008>; else goto <D.20009>;
              <D.20008>:
              D.19922 = async_results.data;
              mono_gc_free_fixed (D.19922);
              <D.20009>:
              async_results.data = __tmp;
              D.19919 = async_results.capacity;
              D.19989 = D.19919 * 2;
              async_results.capacity = D.19989;
            }
            <D.20006>:
            D.19922 = async_results.data;
            D.19985 = async_results.size;
            D.20010 = D.19985;
            D.20011 = D.20010 + 1;
            async_results.size = D.20011;
            D.20012 = (unsigned int) D.20010;
            D.20013 = D.20012 * 4;
            D.20014 = D.19922 + D.20013;
            *D.20014 = ares;
            nresults = nresults + 1;
            <D.20004>:
            <D.20002>:
            <D.19999>:
            list.63 = list;
            if (list.63 != 0B) goto <D.20015>; else goto <D.20016>;
            <D.20015>:
            D.19972 = socket_io_data->sock_to_state;
            D.19926 = pfd->fd;
            D.20017 = (void *) D.19926;
            list.63 = list;
            mono_g_hash_table_replace (D.19972, D.20017, list.63);
            list.63 = list;
            D.20018 = get_events_from_list (list.63);
            D.20019 = (short int) D.20018;
            pfd->events = D.20019;
            goto <D.20020>;
            <D.20016>:
            D.19972 = socket_io_data->sock_to_state;
            D.19926 = pfd->fd;
            D.19973 = (const void *) D.19926;
            mono_g_hash_table_remove (D.19972, D.19973);
            pfd->fd = -1;
            D.20021 = maxfd + -1;
            if (D.20021 == i) goto <D.20022>; else goto <D.20023>;
            <D.20022>:
            maxfd = maxfd + -1;
            <D.20023>:
            <D.20020>:
            <D.18067>:
            i = i + 1;
            <D.18071>:
            if (i < maxfd) goto <D.20024>; else goto <D.18072>;
            <D.20024>:
            if (nsock > 0) goto <D.18070>; else goto <D.18072>;
            <D.18072>:
            {
              int ret;

              D.19946 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_unlock (D.19946);
              if (ret != 0) goto <D.20025>; else goto <D.20026>;
              <D.20025>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
              <D.20026>:
              D.20027 = ret != 0;
              D.20028 = (long int) D.20027;
              D.20029 = __builtin_expect (D.20028, 0);
              if (D.20029 != 0) goto <D.20030>; else goto <D.20031>;
              <D.20030>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 317, "ret == 0");
              <D.20031>:
            }
            D.19922 = async_results.data;
            threadpool_append_jobs (&async_io_tp, D.19922, nresults);
            async_results.size = 0;
            D.19922 = async_results.data;
            D.19919 = async_results.capacity;
            D.19966 = (unsigned int) D.19919;
            D.19967 = D.19966 * 4;
            mono_gc_bzero_aligned (D.19922, D.19967);
          }
        finally
          {
            one = {CLOBBER};
            list = {CLOBBER};
          }
      }
      <D.18064>:
      goto <D.18074>;
    }
  finally
    {
      async_results = {CLOBBER};
    }
}


mark_bad_fds (struct mono_pollfd * pfds, int nfds)
{
  unsigned int i.64;
  unsigned int D.20038;
  int D.20039;
  int * D.20045;
  int D.20046;
  short int D.20048;
  short int D.20049;
  int D.20052;
  int i;
  int ret;
  struct mono_pollfd * pfd;
  int count;

  count = 0;
  i = 0;
  goto <D.18029>;
  <D.18028>:
  i.64 = (unsigned int) i;
  D.20038 = i.64 * 8;
  pfd = pfds + D.20038;
  D.20039 = pfd->fd;
  if (D.20039 == -1) goto <D.20040>; else goto <D.20041>;
  <D.20040>:
  // predicted unlikely by continue predictor.
  goto <D.18027>;
  <D.20041>:
  ret = mono_poll (pfd, 1, 0);
  if (ret == -1) goto <D.20044>; else goto <D.20042>;
  <D.20044>:
  D.20045 = __errno_location ();
  D.20046 = *D.20045;
  if (D.20046 == 9) goto <D.20047>; else goto <D.20042>;
  <D.20047>:
  D.20048 = pfd->revents;
  D.20049 = D.20048 | 32;
  pfd->revents = D.20049;
  count = count + 1;
  goto <D.20043>;
  <D.20042>:
  if (ret == 1) goto <D.20050>; else goto <D.20051>;
  <D.20050>:
  count = count + 1;
  <D.20051>:
  <D.20043>:
  <D.18027>:
  i = i + 1;
  <D.18029>:
  if (i < nfds) goto <D.18028>; else goto <D.18030>;
  <D.18030>:
  D.20052 = count;
  return D.20052;
}


socket_io_cleanup (struct SocketIOData * data)
{
  union mono_mutex_t * D.20054;
  _Bool D.20057;
  long int D.20058;
  long int D.20059;
  int D.20062;
  _Bool D.20067;
  long int D.20068;
  long int D.20069;
  void (*<Tb30>) (void *) D.20072;
  void * D.20073;
  _Bool D.20076;
  long int D.20077;
  long int D.20078;

  {
    int ret;

    D.20054 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20054);
    if (ret != 0) goto <D.20055>; else goto <D.20056>;
    <D.20055>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20056>:
    D.20057 = ret != 0;
    D.20058 = (long int) D.20057;
    D.20059 = __builtin_expect (D.20058, 0);
    if (D.20059 != 0) goto <D.20060>; else goto <D.20061>;
    <D.20060>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 317, "ret == 0");
    <D.20061>:
  }
  D.20062 = data->inited;
  if (D.20062 != 2) goto <D.20063>; else goto <D.20064>;
  <D.20063>:
  {
    int ret;

    D.20054 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20054);
    if (ret != 0) goto <D.20065>; else goto <D.20066>;
    <D.20065>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20066>:
    D.20067 = ret != 0;
    D.20068 = (long int) D.20067;
    D.20069 = __builtin_expect (D.20068, 0);
    if (D.20069 != 0) goto <D.20070>; else goto <D.20071>;
    <D.20070>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 319, "ret == 0");
    <D.20071>:
  }
  return;
  <D.20064>:
  data->inited = 3;
  D.20072 = data->shutdown;
  D.20073 = data->event_data;
  D.20072 (D.20073);
  {
    int ret;

    D.20054 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20054);
    if (ret != 0) goto <D.20074>; else goto <D.20075>;
    <D.20074>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20075>:
    D.20076 = ret != 0;
    D.20077 = (long int) D.20076;
    D.20078 = __builtin_expect (D.20077, 0);
    if (D.20078 != 0) goto <D.20079>; else goto <D.20080>;
    <D.20079>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 324, "ret == 0");
    <D.20080>:
  }
}


read (int __fd, void * __buf, size_t __nbytes)
{
  unsigned int D.20082;
  int D.20085;
  ssize_t D.20088;
  unsigned int D.20089;
  unsigned int D.20090;
  unsigned int D.20093;

  D.20082 = __builtin_object_size (__buf, 0);
  if (D.20082 != 4294967295) goto <D.20083>; else goto <D.20084>;
  <D.20083>:
  D.20085 = __builtin_constant_p (__nbytes);
  if (D.20085 == 0) goto <D.20086>; else goto <D.20087>;
  <D.20086>:
  D.20089 = __builtin_object_size (__buf, 0);
  D.20088 = __read_chk (__fd, __buf, __nbytes, D.20089);
  return D.20088;
  <D.20087>:
  D.20090 = __builtin_object_size (__buf, 0);
  if (D.20090 < __nbytes) goto <D.20091>; else goto <D.20092>;
  <D.20091>:
  D.20093 = __builtin_object_size (__buf, 0);
  D.20088 = __read_chk_warn (__fd, __buf, __nbytes, D.20093);
  return D.20088;
  <D.20092>:
  <D.20084>:
  D.20088 = __read_alias (__fd, __buf, __nbytes);
  return D.20088;
}


tp_poll_modify (void * p, int fd, int operation, int events, gboolean is_new)
{
  union mono_mutex_t * D.20095;
  _Bool D.20098;
  long int D.20099;
  long int D.20100;
  union MonoSemType * D.20103;
  short int D.20104;
  char D.20105;
  int D.20106;
  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.20095 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20095);
        if (ret != 0) goto <D.20096>; else goto <D.20097>;
        <D.20096>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20097>:
        D.20098 = ret != 0;
        D.20099 = (long int) D.20098;
        D.20100 = __builtin_expect (D.20099, 0);
        if (D.20100 != 0) goto <D.20101>; else goto <D.20102>;
        <D.20101>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 87, "ret == 0");
        <D.20102>:
      }
      D.20103 = &data->new_sem;
      mono_sem_wait (D.20103, 0);
      data->newpfd.fd = fd;
      D.20104 = (short int) events;
      data->newpfd.events = D.20104;
      data->newpfd.revents = 0;
      D.20105 = (char) operation;
      msg[0] = D.20105;
      D.20106 = data->pipe[1];
      unused = write (D.20106, &msg, 1);
    }
  finally
    {
      msg = {CLOBBER};
    }
}


tp_poll_shutdown (void * event_data)
{
  int D.20107;
  int D.20110;
  union MonoSemType * D.20113;
  struct tp_poll_data * data;

  data = event_data;
  D.20107 = data->pipe[0];
  if (D.20107 >= 0) goto <D.20108>; else goto <D.20109>;
  <D.20108>:
  D.20107 = data->pipe[0];
  close (D.20107);
  <D.20109>:
  D.20110 = data->pipe[1];
  if (D.20110 >= 0) goto <D.20111>; else goto <D.20112>;
  <D.20111>:
  D.20110 = data->pipe[1];
  close (D.20110);
  <D.20112>:
  data->pipe[0] = -1;
  data->pipe[1] = -1;
  D.20113 = &data->new_sem;
  sem_destroy (D.20113);
}


get_events_from_list (struct MonoMList * list)
{
  int D.20114;
  int D.20116;
  struct MonoSocketAsyncResult * state;
  int events;

  events = 0;
  goto <D.18305>;
  <D.18304>:
  D.20114 = get_event_from_state (state);
  events = D.20114 | events;
  list = mono_mlist_next (list);
  <D.18305>:
  if (list != 0B) goto <D.20115>; else goto <D.18306>;
  <D.20115>:
  state = mono_mlist_get_data (list);
  if (state != 0B) goto <D.18304>; else goto <D.18306>;
  <D.18306>:
  D.20116 = events;
  return D.20116;
}


mono_thread_pool_add (struct MonoObject * target, struct MonoMethodMessage * msg, struct MonoDelegate * async_callback, struct MonoObject * state)
{
  struct MonoClass * async_call_klass.65;
  struct MonoMethodMessage * * D.20119;
  struct MonoObject * * D.20120;
  struct MonoVTable * D.20123;
  struct MonoClass * D.20124;
  struct MonoMethod * D.20125;
  struct MonoDelegate * * D.20126;
  struct MonoObject * D.20127;
  struct MonoObject * * D.20128;
  int D.20129;
  struct MonoAsyncResult * D.20132;
  struct MonoDomain * domain;
  struct MonoAsyncResult * ares;
  struct ASyncCall * ac;

  domain = mono_domain_get ();
  async_call_klass.65 = async_call_klass;
  ac = mono_object_new (domain, async_call_klass.65);
  D.20119 = &ac->msg;
  mono_gc_wbarrier_set_field (ac, D.20119, msg);
  D.20120 = &ac->state;
  mono_gc_wbarrier_set_field (ac, D.20120, state);
  if (async_callback != 0B) goto <D.20121>; else goto <D.20122>;
  <D.20121>:
  D.20123 = MEM[(struct MonoObject *)async_callback].vtable;
  D.20124 = D.20123->klass;
  D.20125 = mono_get_delegate_invoke (D.20124);
  ac->cb_method = D.20125;
  D.20126 = &ac->cb_target;
  mono_gc_wbarrier_set_field (ac, D.20126, async_callback);
  <D.20122>:
  D.20127 = ac->state;
  ares = mono_async_result_new (domain, 0B, D.20127, 0B, ac);
  D.20128 = &ares->async_delegate;
  mono_gc_wbarrier_set_field (ares, D.20128, target);
  D.20129 = socket_io_filter (target, state);
  if (D.20129 != 0) goto <D.20130>; else goto <D.20131>;
  <D.20130>:
  socket_io_add (ares, state);
  D.20132 = ares;
  return D.20132;
  <D.20131>:
  threadpool_append_job (&async_tp, ares);
  D.20132 = ares;
  return D.20132;
}


socket_io_filter (struct MonoObject * target, struct MonoObject * state)
{
  gboolean D.20137;
  struct MonoVTable * D.20138;
  struct MonoClass * socket_async_call_klass.66;
  int D.20142;
  struct MonoClass * process_async_call_klass.67;
  int D.20148;
  unsigned int op.68;
  gint op;
  struct MonoSocketAsyncResult * sock_res;
  struct MonoClass * klass;
  struct MonoDomain * domain;

  if (target == 0B) goto <D.20134>; else goto <D.20136>;
  <D.20136>:
  if (state == 0B) goto <D.20134>; else goto <D.20135>;
  <D.20134>:
  D.20137 = 0;
  return D.20137;
  <D.20135>:
  D.20138 = target->vtable;
  domain = D.20138->domain;
  D.20138 = target->vtable;
  klass = D.20138->klass;
  socket_async_call_klass.66 = socket_async_call_klass;
  if (socket_async_call_klass.66 == 0B) goto <D.20140>; else goto <D.20141>;
  <D.20140>:
  D.20142 = is_socketasynccall (domain, klass);
  if (D.20142 != 0) goto <D.20143>; else goto <D.20144>;
  <D.20143>:
  socket_async_call_klass = klass;
  <D.20144>:
  <D.20141>:
  process_async_call_klass.67 = process_async_call_klass;
  if (process_async_call_klass.67 == 0B) goto <D.20146>; else goto <D.20147>;
  <D.20146>:
  D.20148 = is_sdp_asyncreadhandler (domain, klass);
  if (D.20148 != 0) goto <D.20149>; else goto <D.20150>;
  <D.20149>:
  process_async_call_klass = klass;
  <D.20150>:
  <D.20147>:
  socket_async_call_klass.66 = socket_async_call_klass;
  if (klass != socket_async_call_klass.66) goto <D.20151>; else goto <D.20152>;
  <D.20151>:
  process_async_call_klass.67 = process_async_call_klass;
  if (klass != process_async_call_klass.67) goto <D.20153>; else goto <D.20154>;
  <D.20153>:
  D.20137 = 0;
  return D.20137;
  <D.20154>:
  <D.20152>:
  sock_res = state;
  op = sock_res->operation;
  op.68 = (unsigned int) op;
  if (op.68 > 13) goto <D.20156>; else goto <D.20157>;
  <D.20156>:
  D.20137 = 0;
  return D.20137;
  <D.20157>:
  D.20137 = 1;
  return D.20137;
}


is_socketasynccall (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.20159;
  int iftmp.69;
  struct MonoClass * D.20163;
  int D.20165;
  int D.18218;
  int iftmp.70;
  int D.18217;
  const char[16] * D.20170;
  unsigned char D.20171;
  int D.20172;
  unsigned char D.20173;
  int D.20174;
  const unsigned char * D.20179;
  unsigned char D.20180;
  int D.20181;
  const unsigned char * D.20182;
  unsigned char D.20183;
  int D.20184;
  const unsigned char * D.20189;
  unsigned char D.20190;
  int D.20191;
  const unsigned char * D.20192;
  unsigned char D.20193;
  int D.20194;
  const unsigned char * D.20199;
  unsigned char D.20200;
  int D.20201;
  const unsigned char * D.20202;
  unsigned char D.20203;
  int D.20204;
  const char * D.20206;

  D.20163 = klass->nested_in;
  if (D.20163 != 0B) goto <D.20164>; else goto <D.20161>;
  <D.20164>:
  D.20163 = klass->nested_in;
  D.20165 = is_socket (domain, D.20163);
  if (D.20165 != 0) goto <D.20166>; else goto <D.20161>;
  <D.20166>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20170 = "SocketAsyncCall";
      D.20171 = MEM[(const unsigned char *)D.20170];
      D.20172 = (int) D.20171;
      D.20173 = *__s2;
      D.20174 = (int) D.20173;
      __result = D.20172 - D.20174;
      {
        if (__s2_len != 0) goto <D.20175>; else goto <D.20176>;
        <D.20175>:
        if (__result == 0) goto <D.20177>; else goto <D.20178>;
        <D.20177>:
        D.20179 = &MEM[(void *)"SocketAsyncCall" + 1B];
        D.20180 = *D.20179;
        D.20181 = (int) D.20180;
        D.20182 = __s2 + 1;
        D.20183 = *D.20182;
        D.20184 = (int) D.20183;
        __result = D.20181 - D.20184;
        if (__s2_len > 1) goto <D.20185>; else goto <D.20186>;
        <D.20185>:
        if (__result == 0) goto <D.20187>; else goto <D.20188>;
        <D.20187>:
        D.20189 = &MEM[(void *)"SocketAsyncCall" + 2B];
        D.20190 = *D.20189;
        D.20191 = (int) D.20190;
        D.20192 = __s2 + 2;
        D.20193 = *D.20192;
        D.20194 = (int) D.20193;
        __result = D.20191 - D.20194;
        if (__s2_len > 2) goto <D.20195>; else goto <D.20196>;
        <D.20195>:
        if (__result == 0) goto <D.20197>; else goto <D.20198>;
        <D.20197>:
        D.20199 = &MEM[(void *)"SocketAsyncCall" + 3B];
        D.20200 = *D.20199;
        D.20201 = (int) D.20200;
        D.20202 = __s2 + 3;
        D.20203 = *D.20202;
        D.20204 = (int) D.20203;
        __result = D.20201 - D.20204;
        <D.20198>:
        <D.20196>:
        <D.20188>:
        <D.20186>:
        <D.20178>:
        <D.20176>:
      }
      D.18217 = __result;
    }
    iftmp.70 = -D.18217;
    goto <D.20205>;
    <D.20169>:
    D.20206 = klass->name;
    iftmp.70 = __builtin_strcmp (D.20206, "SocketAsyncCall");
    <D.20205>:
    D.18218 = iftmp.70;
  }
  if (D.18218 == 0) goto <D.20207>; else goto <D.20161>;
  <D.20207>:
  iftmp.69 = 1;
  goto <D.20162>;
  <D.20161>:
  iftmp.69 = 0;
  <D.20162>:
  D.20159 = iftmp.69;
  return D.20159;
}


is_sdp_asyncreadhandler (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.20209;
  int iftmp.71;
  struct MonoClass * D.20213;
  int D.20215;
  int D.18275;
  int iftmp.72;
  int D.18274;
  const char[17] * D.20220;
  unsigned char D.20221;
  int D.20222;
  unsigned char D.20223;
  int D.20224;
  const unsigned char * D.20229;
  unsigned char D.20230;
  int D.20231;
  const unsigned char * D.20232;
  unsigned char D.20233;
  int D.20234;
  const unsigned char * D.20239;
  unsigned char D.20240;
  int D.20241;
  const unsigned char * D.20242;
  unsigned char D.20243;
  int D.20244;
  const unsigned char * D.20249;
  unsigned char D.20250;
  int D.20251;
  const unsigned char * D.20252;
  unsigned char D.20253;
  int D.20254;
  const char * D.20256;

  D.20213 = klass->nested_in;
  if (D.20213 != 0B) goto <D.20214>; else goto <D.20211>;
  <D.20214>:
  D.20213 = klass->nested_in;
  D.20215 = is_sd_process (domain, D.20213);
  if (D.20215 != 0) goto <D.20216>; else goto <D.20211>;
  <D.20216>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20220 = "AsyncReadHandler";
      D.20221 = MEM[(const unsigned char *)D.20220];
      D.20222 = (int) D.20221;
      D.20223 = *__s2;
      D.20224 = (int) D.20223;
      __result = D.20222 - D.20224;
      {
        if (__s2_len != 0) goto <D.20225>; else goto <D.20226>;
        <D.20225>:
        if (__result == 0) goto <D.20227>; else goto <D.20228>;
        <D.20227>:
        D.20229 = &MEM[(void *)"AsyncReadHandler" + 1B];
        D.20230 = *D.20229;
        D.20231 = (int) D.20230;
        D.20232 = __s2 + 1;
        D.20233 = *D.20232;
        D.20234 = (int) D.20233;
        __result = D.20231 - D.20234;
        if (__s2_len > 1) goto <D.20235>; else goto <D.20236>;
        <D.20235>:
        if (__result == 0) goto <D.20237>; else goto <D.20238>;
        <D.20237>:
        D.20239 = &MEM[(void *)"AsyncReadHandler" + 2B];
        D.20240 = *D.20239;
        D.20241 = (int) D.20240;
        D.20242 = __s2 + 2;
        D.20243 = *D.20242;
        D.20244 = (int) D.20243;
        __result = D.20241 - D.20244;
        if (__s2_len > 2) goto <D.20245>; else goto <D.20246>;
        <D.20245>:
        if (__result == 0) goto <D.20247>; else goto <D.20248>;
        <D.20247>:
        D.20249 = &MEM[(void *)"AsyncReadHandler" + 3B];
        D.20250 = *D.20249;
        D.20251 = (int) D.20250;
        D.20252 = __s2 + 3;
        D.20253 = *D.20252;
        D.20254 = (int) D.20253;
        __result = D.20251 - D.20254;
        <D.20248>:
        <D.20246>:
        <D.20238>:
        <D.20236>:
        <D.20228>:
        <D.20226>:
      }
      D.18274 = __result;
    }
    iftmp.72 = -D.18274;
    goto <D.20255>;
    <D.20219>:
    D.20256 = klass->name;
    iftmp.72 = __builtin_strcmp (D.20256, "AsyncReadHandler");
    <D.20255>:
    D.18275 = iftmp.72;
  }
  if (D.18275 == 0) goto <D.20257>; else goto <D.20211>;
  <D.20257>:
  iftmp.71 = 1;
  goto <D.20212>;
  <D.20211>:
  iftmp.71 = 0;
  <D.20212>:
  D.20209 = iftmp.71;
  return D.20209;
}


is_sd_process (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.20259;
  gboolean D.20262;
  _Bool D.20263;
  int D.20264;
  int D.18253;
  int iftmp.73;
  int D.18249;
  const char[8] * D.20270;
  unsigned char D.20271;
  int D.20272;
  unsigned char D.20273;
  int D.20274;
  const unsigned char * D.20279;
  unsigned char D.20280;
  int D.20281;
  const unsigned char * D.20282;
  unsigned char D.20283;
  int D.20284;
  const unsigned char * D.20289;
  unsigned char D.20290;
  int D.20291;
  const unsigned char * D.20292;
  unsigned char D.20293;
  int D.20294;
  const unsigned char * D.20299;
  unsigned char D.20300;
  int D.20301;
  const unsigned char * D.20302;
  unsigned char D.20303;
  int D.20304;
  const char * D.20306;
  int D.18262;
  int iftmp.74;
  int D.18258;
  const char[19] * D.20312;
  unsigned char D.20313;
  int D.20314;
  unsigned char D.20315;
  int D.20316;
  const unsigned char * D.20321;
  unsigned char D.20322;
  int D.20323;
  const unsigned char * D.20324;
  unsigned char D.20325;
  int D.20326;
  const unsigned char * D.20331;
  unsigned char D.20332;
  int D.20333;
  const unsigned char * D.20334;
  unsigned char D.20335;
  int D.20336;
  const unsigned char * D.20341;
  unsigned char D.20342;
  int D.20343;
  const unsigned char * D.20344;
  unsigned char D.20345;
  int D.20346;
  const char * D.20348;

  D.20259 = domain->process_class;
  if (D.20259 != 0B) goto <D.20260>; else goto <D.20261>;
  <D.20260>:
  D.20259 = domain->process_class;
  D.20263 = D.20259 == klass;
  D.20262 = (gboolean) D.20263;
  return D.20262;
  <D.20261>:
  D.20264 = is_system_type (domain, klass);
  if (D.20264 != 0) goto <D.20265>; else goto <D.20266>;
  <D.20265>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20270 = "Process";
      D.20271 = MEM[(const unsigned char *)D.20270];
      D.20272 = (int) D.20271;
      D.20273 = *__s2;
      D.20274 = (int) D.20273;
      __result = D.20272 - D.20274;
      {
        if (__s1_len != 0) goto <D.20275>; else goto <D.20276>;
        <D.20275>:
        if (__result == 0) goto <D.20277>; else goto <D.20278>;
        <D.20277>:
        D.20279 = &MEM[(void *)"Process" + 1B];
        D.20280 = *D.20279;
        D.20281 = (int) D.20280;
        D.20282 = __s2 + 1;
        D.20283 = *D.20282;
        D.20284 = (int) D.20283;
        __result = D.20281 - D.20284;
        if (__s1_len > 1) goto <D.20285>; else goto <D.20286>;
        <D.20285>:
        if (__result == 0) goto <D.20287>; else goto <D.20288>;
        <D.20287>:
        D.20289 = &MEM[(void *)"Process" + 2B];
        D.20290 = *D.20289;
        D.20291 = (int) D.20290;
        D.20292 = __s2 + 2;
        D.20293 = *D.20292;
        D.20294 = (int) D.20293;
        __result = D.20291 - D.20294;
        if (__s1_len > 2) goto <D.20295>; else goto <D.20296>;
        <D.20295>:
        if (__result == 0) goto <D.20297>; else goto <D.20298>;
        <D.20297>:
        D.20299 = &MEM[(void *)"Process" + 3B];
        D.20300 = *D.20299;
        D.20301 = (int) D.20300;
        D.20302 = __s2 + 3;
        D.20303 = *D.20302;
        D.20304 = (int) D.20303;
        __result = D.20301 - D.20304;
        <D.20298>:
        <D.20296>:
        <D.20288>:
        <D.20286>:
        <D.20278>:
        <D.20276>:
      }
      D.18249 = __result;
    }
    iftmp.73 = D.18249;
    goto <D.20305>;
    <D.20269>:
    D.20306 = klass->name;
    iftmp.73 = __builtin_strcmp ("Process", D.20306);
    <D.20305>:
    D.18253 = iftmp.73;
  }
  if (D.18253 == 0) goto <D.20307>; else goto <D.20308>;
  <D.20307>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.20312 = "System.Diagnostics";
      D.20313 = MEM[(const unsigned char *)D.20312];
      D.20314 = (int) D.20313;
      D.20315 = *__s2;
      D.20316 = (int) D.20315;
      __result = D.20314 - D.20316;
      {
        if (__s1_len != 0) goto <D.20317>; else goto <D.20318>;
        <D.20317>:
        if (__result == 0) goto <D.20319>; else goto <D.20320>;
        <D.20319>:
        D.20321 = &MEM[(void *)"System.Diagnostics" + 1B];
        D.20322 = *D.20321;
        D.20323 = (int) D.20322;
        D.20324 = __s2 + 1;
        D.20325 = *D.20324;
        D.20326 = (int) D.20325;
        __result = D.20323 - D.20326;
        if (__s1_len > 1) goto <D.20327>; else goto <D.20328>;
        <D.20327>:
        if (__result == 0) goto <D.20329>; else goto <D.20330>;
        <D.20329>:
        D.20331 = &MEM[(void *)"System.Diagnostics" + 2B];
        D.20332 = *D.20331;
        D.20333 = (int) D.20332;
        D.20334 = __s2 + 2;
        D.20335 = *D.20334;
        D.20336 = (int) D.20335;
        __result = D.20333 - D.20336;
        if (__s1_len > 2) goto <D.20337>; else goto <D.20338>;
        <D.20337>:
        if (__result == 0) goto <D.20339>; else goto <D.20340>;
        <D.20339>:
        D.20341 = &MEM[(void *)"System.Diagnostics" + 3B];
        D.20342 = *D.20341;
        D.20343 = (int) D.20342;
        D.20344 = __s2 + 3;
        D.20345 = *D.20344;
        D.20346 = (int) D.20345;
        __result = D.20343 - D.20346;
        <D.20340>:
        <D.20338>:
        <D.20330>:
        <D.20328>:
        <D.20320>:
        <D.20318>:
      }
      D.18258 = __result;
    }
    iftmp.74 = D.18258;
    goto <D.20347>;
    <D.20311>:
    D.20348 = klass->name_space;
    iftmp.74 = __builtin_strcmp ("System.Diagnostics", D.20348);
    <D.20347>:
    D.18262 = iftmp.74;
  }
  if (D.18262 == 0) goto <D.20349>; else goto <D.20350>;
  <D.20349>:
  domain->process_class = klass;
  D.20262 = 1;
  return D.20262;
  <D.20350>:
  <D.20308>:
  <D.20266>:
  D.20262 = 0;
  return D.20262;
}


mono_thread_pool_finish (struct MonoAsyncResult * ares, struct MonoArray * * out_args, struct MonoObject * * exc)
{
  unsigned char D.20352;
  struct MonoException * D.20355;
  struct MonoObject * D.20356;
  unsigned char D.20357;
  struct MonoObject * D.20360;
  _Bool D.20363;
  long int D.20364;
  long int D.20365;
  struct MonoObject * * D.20368;
  struct MonoVTable * D.20369;
  struct MonoDomain * D.20370;
  struct MonoWaitHandle * D.20371;
  _Bool D.20374;
  long int D.20375;
  long int D.20376;
  struct MonoMethodMessage * D.20379;
  struct MonoObject * D.20380;
  struct MonoArray * D.20381;
  struct ASyncCall * ac;
  void * wait_event;

  *exc = 0B;
  *out_args = 0B;
  mono_monitor_enter (ares);
  D.20352 = ares->endinvoke_called;
  if (D.20352 != 0) goto <D.20353>; else goto <D.20354>;
  <D.20353>:
  D.20355 = mono_get_exception_invalid_operation (0B);
  *exc = D.20355;
  mono_monitor_exit (ares);
  D.20356 = 0B;
  return D.20356;
  <D.20354>:
  ares->endinvoke_called = 1;
  D.20357 = ares->completed;
  if (D.20357 == 0) goto <D.20358>; else goto <D.20359>;
  <D.20358>:
  D.20360 = ares->handle;
  if (D.20360 == 0B) goto <D.20361>; else goto <D.20362>;
  <D.20361>:
  wait_event = CreateEvent (0B, 1, 0, 0B);
  D.20363 = wait_event == 0B;
  D.20364 = (long int) D.20363;
  D.20365 = __builtin_expect (D.20364, 0);
  if (D.20365 != 0) goto <D.20366>; else goto <D.20367>;
  <D.20366>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 958, "wait_event != 0");
  <D.20367>:
  D.20368 = &ares->handle;
  D.20369 = MEM[(struct MonoObject *)ares].vtable;
  D.20370 = D.20369->domain;
  D.20371 = mono_wait_handle_new (D.20370, wait_event);
  mono_gc_wbarrier_set_field (ares, D.20368, D.20371);
  goto <D.20372>;
  <D.20362>:
  D.20360 = ares->handle;
  wait_event = mono_wait_handle_get_handle (D.20360);
  <D.20372>:
  mono_monitor_exit (ares);
  WaitForSingleObjectEx (wait_event, 4294967295, 1);
  goto <D.20373>;
  <D.20359>:
  mono_monitor_exit (ares);
  <D.20373>:
  ac = ares->object_data;
  D.20374 = ac == 0B;
  D.20375 = (long int) D.20374;
  D.20376 = __builtin_expect (D.20375, 0);
  if (D.20376 != 0) goto <D.20377>; else goto <D.20378>;
  <D.20377>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 970, "ac != NULL");
  <D.20378>:
  D.20379 = ac->msg;
  D.20380 = D.20379->exc;
  *exc = D.20380;
  D.20381 = ac->out_args;
  *out_args = D.20381;
  D.20356 = ac->res;
  return D.20356;
}


mono_thread_pool_cleanup ()
{
  int D.20383;
  struct MonoCQ * D.20386;
  int D.20389;
  struct GPtrArray * wsqs.75;
  _Bool D.20397;
  long int D.20398;
  long int D.20399;
  _Bool D.20406;
  long int D.20407;
  long int D.20408;

  D.20383 = InterlockedExchange (&async_io_tp.pool_status, 2);
  if (D.20383 == 1) goto <D.20384>; else goto <D.20385>;
  <D.20384>:
  socket_io_cleanup (&socket_io_data);
  threadpool_kill_idle_threads (&async_io_tp);
  <D.20385>:
  D.20386 = async_io_tp.queue;
  if (D.20386 != 0B) goto <D.20387>; else goto <D.20388>;
  <D.20387>:
  sem_destroy (&async_io_tp.new_job);
  threadpool_free_queue (&async_io_tp);
  <D.20388>:
  D.20389 = InterlockedExchange (&async_tp.pool_status, 2);
  if (D.20389 == 1) goto <D.20390>; else goto <D.20391>;
  <D.20390>:
  threadpool_kill_idle_threads (&async_tp);
  threadpool_free_queue (&async_tp);
  <D.20391>:
  wsqs.75 = wsqs;
  if (wsqs.75 != 0B) goto <D.20393>; else goto <D.20394>;
  <D.20393>:
  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20395>; else goto <D.20396>;
    <D.20395>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20396>:
    D.20397 = ret != 0;
    D.20398 = (long int) D.20397;
    D.20399 = __builtin_expect (D.20398, 0);
    if (D.20399 != 0) goto <D.20400>; else goto <D.20401>;
    <D.20400>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1009, "ret == 0");
    <D.20401>:
  }
  mono_wsq_cleanup ();
  wsqs.75 = wsqs;
  if (wsqs.75 != 0B) goto <D.20402>; else goto <D.20403>;
  <D.20402>:
  wsqs.75 = wsqs;
  monoeg_g_ptr_array_free (wsqs.75, 1);
  <D.20403>:
  wsqs = 0B;
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20404>; else goto <D.20405>;
    <D.20404>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20405>:
    D.20406 = ret != 0;
    D.20407 = (long int) D.20406;
    D.20408 = __builtin_expect (D.20407, 0);
    if (D.20408 != 0) goto <D.20409>; else goto <D.20410>;
    <D.20409>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1014, "ret == 0");
    <D.20410>:
  }
  sem_destroy (&async_tp.new_job);
  <D.20394>:
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int old_val.76;
  unsigned int new_val.77;
  unsigned int D.20413;
  int D.20414;
  gint32 D.20415;
  gint32 old_val;

  <D.16909>:
  old_val = *val;
  old_val.76 = (unsigned int) old_val;
  new_val.77 = (unsigned int) new_val;
  D.20413 = __sync_val_compare_and_swap_4 (val, old_val.76, new_val.77);
  D.20414 = (int) D.20413;
  if (D.20414 != old_val) goto <D.16909>; else goto <D.16910>;
  <D.16910>:
  D.20415 = old_val;
  return D.20415;
}


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

  D.20417 = &tp->max_threads;
  n = InterlockedCompareExchange (D.20417, 0, -1);
  goto <D.18472>;
  <D.18471>:
  n = n + -1;
  D.20418 = &tp->new_job;
  mono_sem_post (D.20418);
  <D.18472>:
  if (n != 0) goto <D.18471>; else goto <D.18473>;
  <D.18473>:
}


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

  D.20419 = tp->queue;
  mono_cq_destroy (D.20419);
  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.20420;
  _Bool D.20421;
  long int D.20422;
  long int D.20423;
  _Bool D.20428;
  long int D.20429;
  long int D.20430;
  struct MonoGHashTable * D.20433;
  _Bool D.20438;
  long int D.20439;
  long int D.20440;
  int D.20443;
  unsigned int timeout.78;
  unsigned int D.20451;
  unsigned int D.20452;
  int D.20455;
  gboolean D.20456;
  void * sem_handle;
  int result;
  guint32 start_time;

  result = 1;
  start_time = 0;
  D.20420 = domain->state;
  D.20421 = D.20420 != 2;
  D.20422 = (long int) D.20421;
  D.20423 = __builtin_expect (D.20422, 0);
  if (D.20423 != 0) goto <D.20424>; else goto <D.20425>;
  <D.20424>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1159, "domain->state == MONO_APPDOMAIN_UNLOADING");
  <D.20425>:
  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.20426>; else goto <D.20427>;
    <D.20426>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20427>:
    D.20428 = ret != 0;
    D.20429 = (long int) D.20428;
    D.20430 = __builtin_expect (D.20429, 0);
    if (D.20430 != 0) goto <D.20431>; else goto <D.20432>;
    <D.20431>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1164, "ret == 0");
    <D.20432>:
  }
  D.20433 = socket_io_data.sock_to_state;
  if (D.20433 != 0B) goto <D.20434>; else goto <D.20435>;
  <D.20434>:
  D.20433 = socket_io_data.sock_to_state;
  mono_g_hash_table_foreach_remove (D.20433, remove_sockstate_for_domain, domain);
  <D.20435>:
  {
    int ret;

    ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
    if (ret != 0) goto <D.20436>; else goto <D.20437>;
    <D.20436>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20437>:
    D.20438 = ret != 0;
    D.20439 = (long int) D.20438;
    D.20440 = __builtin_expect (D.20439, 0);
    if (D.20440 != 0) goto <D.20441>; else goto <D.20442>;
    <D.20441>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1168, "ret == 0");
    <D.20442>:
  }
  sem_handle = CreateSemaphore (0B, 0, 1, 0B);
  domain->cleanup_semaphore = sem_handle;
  mono_memory_write_barrier ();
  D.20443 = domain->threadpool_jobs;
  if (D.20443 != 0) goto <D.20444>; else goto <D.20445>;
  <D.20444>:
  if (timeout != -1) goto <D.20446>; else goto <D.20447>;
  <D.20446>:
  start_time = mono_msec_ticks ();
  <D.20447>:
  <D.20445>:
  goto <D.18548>;
  <D.18547>:
  timeout.78 = (unsigned int) timeout;
  WaitForSingleObject (sem_handle, timeout.78);
  if (timeout != -1) goto <D.20449>; else goto <D.20450>;
  <D.20449>:
  D.20451 = mono_msec_ticks ();
  D.20452 = D.20451 - start_time;
  timeout.78 = (unsigned int) timeout;
  if (D.20452 > timeout.78) goto <D.20453>; else goto <D.20454>;
  <D.20453>:
  result = 0;
  goto <D.18546>;
  <D.20454>:
  <D.20450>:
  <D.18548>:
  D.20455 = domain->threadpool_jobs;
  if (D.20455 != 0) goto <D.18547>; else goto <D.18546>;
  <D.18546>:
  domain->cleanup_semaphore = 0B;
  CloseHandle (sem_handle);
  D.20456 = result;
  return D.20456;
}


remove_sockstate_for_domain (void * key, void * value, void * user_data)
{
  struct MonoVTable * D.20458;
  struct MonoDomain * D.20459;
  gboolean D.20462;
  struct MonoMList * list;
  gboolean remove;

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

    data = mono_mlist_get_data (list);
    D.20458 = data->vtable;
    D.20459 = D.20458->domain;
    if (D.20459 == user_data) goto <D.20460>; else goto <D.20461>;
    <D.20460>:
    remove = 1;
    mono_mlist_set_data (list, 0B);
    <D.20461>:
    list = mono_mlist_next (list);
  }
  <D.18535>:
  if (list != 0B) goto <D.18534>; else goto <D.18536>;
  <D.18536>:
  D.20462 = remove;
  return D.20462;
}


threadpool_clear_queue (struct ThreadPool * tp, struct MonoDomain * domain)
{
  struct MonoObject * obj.79;
  struct MonoVTable * D.20469;
  struct MonoDomain * D.20470;
  int D.20473;
  int D.20474;
  struct MonoObject * D.20477;
  struct MonoObject * obj;
  struct MonoMList * other;
  struct MonoCQ * queue;

  try
    {
      other = 0B;
      queue = tp->queue;
      if (queue == 0B) goto <D.20464>; else goto <D.20465>;
      <D.20464>:
      return;
      <D.20465>:
      goto <D.18520>;
      <D.18521>:
      obj.79 = obj;
      if (obj.79 == 0B) goto <D.20467>; else goto <D.20468>;
      <D.20467>:
      // predicted unlikely by continue predictor.
      goto <D.18520>;
      <D.20468>:
      obj.79 = obj;
      D.20469 = obj.79->vtable;
      D.20470 = D.20469->domain;
      if (D.20470 != domain) goto <D.20471>; else goto <D.20472>;
      <D.20471>:
      obj.79 = obj;
      other = mono_mlist_prepend (other, obj.79);
      <D.20472>:
      obj.79 = obj;
      threadpool_jobs_dec (obj.79);
      <D.18520>:
      D.20473 = mono_cq_dequeue (queue, &obj);
      if (D.20473 != 0) goto <D.18521>; else goto <D.18522>;
      <D.18522>:
      D.20474 = mono_runtime_is_shutting_down ();
      if (D.20474 != 0) goto <D.20475>; else goto <D.20476>;
      <D.20475>:
      return;
      <D.20476>:
      goto <D.18524>;
      <D.18523>:
      D.20477 = mono_mlist_get_data (other);
      threadpool_append_job (tp, D.20477);
      other = mono_mlist_next (other);
      <D.18524>:
      if (other != 0B) goto <D.18523>; else goto <D.18525>;
      <D.18525>:
    }
  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.20481;

  D.20481 = 0;
  return D.20481;
}


ves_icall_System_Threading_ThreadPool_GetAvailableThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.20483;
  int D.20484;
  int D.20485;
  int D.20486;
  int D.20487;
  int D.20488;

  D.20483 = async_tp.max_threads;
  D.20484 = async_tp.busy_threads;
  D.20485 = D.20483 - D.20484;
  *workerThreads = D.20485;
  D.20486 = async_io_tp.max_threads;
  D.20487 = async_io_tp.busy_threads;
  D.20488 = D.20486 - D.20487;
  *completionPortThreads = D.20488;
}


ves_icall_System_Threading_ThreadPool_GetMaxThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.20489;
  int D.20490;

  D.20489 = async_tp.max_threads;
  *workerThreads = D.20489;
  D.20490 = async_io_tp.max_threads;
  *completionPortThreads = D.20490;
}


ves_icall_System_Threading_ThreadPool_GetMinThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.20491;
  int D.20492;

  D.20491 = async_tp.min_threads;
  *workerThreads = D.20491;
  D.20492 = async_io_tp.min_threads;
  *completionPortThreads = D.20492;
}


ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, gint completionPortThreads)
{
  MonoBoolean D.20496;
  int D.20500;
  struct MonoDomain * D.20503;
  int D.20504;
  struct MonoDomain * D.20507;
  gint max_threads;
  gint max_io_threads;

  max_threads = async_tp.max_threads;
  if (workerThreads <= 0) goto <D.20493>; else goto <D.20495>;
  <D.20495>:
  if (workerThreads > max_threads) goto <D.20493>; else goto <D.20494>;
  <D.20493>:
  D.20496 = 0;
  return D.20496;
  <D.20494>:
  max_io_threads = async_io_tp.max_threads;
  if (completionPortThreads <= 0) goto <D.20497>; else goto <D.20499>;
  <D.20499>:
  if (completionPortThreads > max_io_threads) goto <D.20497>; else goto <D.20498>;
  <D.20497>:
  D.20496 = 0;
  return D.20496;
  <D.20498>:
  InterlockedExchange (&async_tp.min_threads, workerThreads);
  InterlockedExchange (&async_io_tp.min_threads, completionPortThreads);
  D.20500 = async_tp.nthreads;
  if (D.20500 < workerThreads) goto <D.20501>; else goto <D.20502>;
  <D.20501>:
  D.20503 = mono_get_root_domain ();
  mono_thread_create_internal (D.20503, threadpool_start_idle_threads, &async_tp, 1, 0, 131072);
  <D.20502>:
  D.20504 = async_io_tp.nthreads;
  if (D.20504 < completionPortThreads) goto <D.20505>; else goto <D.20506>;
  <D.20505>:
  D.20507 = mono_get_root_domain ();
  mono_thread_create_internal (D.20507, threadpool_start_idle_threads, &async_io_tp, 1, 0, 131072);
  <D.20506>:
  D.20496 = 1;
  return D.20496;
}


ves_icall_System_Threading_ThreadPool_SetMaxThreads (gint workerThreads, gint completionPortThreads)
{
  MonoBoolean D.20512;
  gint min_threads;
  gint min_io_threads;
  gint cpu_count;

  cpu_count = mono_cpu_count ();
  min_threads = async_tp.min_threads;
  if (workerThreads < min_threads) goto <D.20509>; else goto <D.20511>;
  <D.20511>:
  if (workerThreads < cpu_count) goto <D.20509>; else goto <D.20510>;
  <D.20509>:
  D.20512 = 0;
  return D.20512;
  <D.20510>:
  min_io_threads = async_io_tp.min_threads;
  if (completionPortThreads < min_io_threads) goto <D.20513>; else goto <D.20515>;
  <D.20515>:
  if (completionPortThreads < cpu_count) goto <D.20513>; else goto <D.20514>;
  <D.20513>:
  D.20512 = 0;
  return D.20512;
  <D.20514>:
  InterlockedExchange (&async_tp.max_threads, workerThreads);
  InterlockedExchange (&async_io_tp.max_threads, completionPortThreads);
  D.20512 = 1;
  return D.20512;
}


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.20517;
  struct MonoVTable * D.20520;
  struct MonoDomain * D.20521;
  struct MonoClass * D.20524;
  int D.20527;
  struct MonoInternalThread * D.20532;

  D.20517 = mono_runtime_unhandled_exception_policy_get ();
  if (D.20517 == 1) goto <D.20518>; else goto <D.20519>;
  <D.20518>:
  {
    gboolean unloaded;
    struct MonoClass * klass;

    D.20520 = exc->vtable;
    klass = D.20520->klass;
    D.20520 = exc->vtable;
    D.20521 = D.20520->domain;
    unloaded = is_appdomainunloaded_exception (D.20521, klass);
    if (unloaded == 0) goto <D.20522>; else goto <D.20523>;
    <D.20522>:
    D.20524 = mono_defaults.threadabortexception_class;
    if (D.20524 != klass) goto <D.20525>; else goto <D.20526>;
    <D.20525>:
    mono_unhandled_exception (exc);
    D.20527 = mono_environment_exitcode_get ();
    if (D.20527 == 1) goto <D.20528>; else goto <D.20529>;
    <D.20528>:
    exit (255);
    <D.20529>:
    <D.20526>:
    <D.20523>:
    D.20524 = mono_defaults.threadabortexception_class;
    if (D.20524 == klass) goto <D.20530>; else goto <D.20531>;
    <D.20530>:
    D.20532 = mono_thread_internal_current ();
    mono_thread_internal_reset_abort (D.20532);
    <D.20531>:
  }
  <D.20519>:
}


is_appdomainunloaded_exception (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.20533;
  gboolean D.20536;
  _Bool D.20537;
  int D.20538;
  int D.18231;
  int iftmp.80;
  int D.18227;
  const char[27] * D.20544;
  unsigned char D.20545;
  int D.20546;
  unsigned char D.20547;
  int D.20548;
  const unsigned char * D.20553;
  unsigned char D.20554;
  int D.20555;
  const unsigned char * D.20556;
  unsigned char D.20557;
  int D.20558;
  const unsigned char * D.20563;
  unsigned char D.20564;
  int D.20565;
  const unsigned char * D.20566;
  unsigned char D.20567;
  int D.20568;
  const unsigned char * D.20573;
  unsigned char D.20574;
  int D.20575;
  const unsigned char * D.20576;
  unsigned char D.20577;
  int D.20578;
  const char * D.20580;
  int D.18240;
  int iftmp.81;
  int D.18236;
  const char[7] * D.20586;
  unsigned char D.20587;
  int D.20588;
  unsigned char D.20589;
  int D.20590;
  const unsigned char * D.20595;
  unsigned char D.20596;
  int D.20597;
  const unsigned char * D.20598;
  unsigned char D.20599;
  int D.20600;
  const unsigned char * D.20605;
  unsigned char D.20606;
  int D.20607;
  const unsigned char * D.20608;
  unsigned char D.20609;
  int D.20610;
  const unsigned char * D.20615;
  unsigned char D.20616;
  int D.20617;
  const unsigned char * D.20618;
  unsigned char D.20619;
  int D.20620;
  const char * D.20622;

  D.20533 = domain->ad_unloaded_ex_class;
  if (D.20533 != 0B) goto <D.20534>; else goto <D.20535>;
  <D.20534>:
  D.20533 = domain->ad_unloaded_ex_class;
  D.20537 = D.20533 == klass;
  D.20536 = (gboolean) D.20537;
  return D.20536;
  <D.20535>:
  D.20538 = is_corlib_type (domain, klass);
  if (D.20538 != 0) goto <D.20539>; else goto <D.20540>;
  <D.20539>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20544 = "AppDomainUnloadedException";
      D.20545 = MEM[(const unsigned char *)D.20544];
      D.20546 = (int) D.20545;
      D.20547 = *__s2;
      D.20548 = (int) D.20547;
      __result = D.20546 - D.20548;
      {
        if (__s1_len != 0) goto <D.20549>; else goto <D.20550>;
        <D.20549>:
        if (__result == 0) goto <D.20551>; else goto <D.20552>;
        <D.20551>:
        D.20553 = &MEM[(void *)"AppDomainUnloadedException" + 1B];
        D.20554 = *D.20553;
        D.20555 = (int) D.20554;
        D.20556 = __s2 + 1;
        D.20557 = *D.20556;
        D.20558 = (int) D.20557;
        __result = D.20555 - D.20558;
        if (__s1_len > 1) goto <D.20559>; else goto <D.20560>;
        <D.20559>:
        if (__result == 0) goto <D.20561>; else goto <D.20562>;
        <D.20561>:
        D.20563 = &MEM[(void *)"AppDomainUnloadedException" + 2B];
        D.20564 = *D.20563;
        D.20565 = (int) D.20564;
        D.20566 = __s2 + 2;
        D.20567 = *D.20566;
        D.20568 = (int) D.20567;
        __result = D.20565 - D.20568;
        if (__s1_len > 2) goto <D.20569>; else goto <D.20570>;
        <D.20569>:
        if (__result == 0) goto <D.20571>; else goto <D.20572>;
        <D.20571>:
        D.20573 = &MEM[(void *)"AppDomainUnloadedException" + 3B];
        D.20574 = *D.20573;
        D.20575 = (int) D.20574;
        D.20576 = __s2 + 3;
        D.20577 = *D.20576;
        D.20578 = (int) D.20577;
        __result = D.20575 - D.20578;
        <D.20572>:
        <D.20570>:
        <D.20562>:
        <D.20560>:
        <D.20552>:
        <D.20550>:
      }
      D.18227 = __result;
    }
    iftmp.80 = D.18227;
    goto <D.20579>;
    <D.20543>:
    D.20580 = klass->name;
    iftmp.80 = __builtin_strcmp ("AppDomainUnloadedException", D.20580);
    <D.20579>:
    D.18231 = iftmp.80;
  }
  if (D.18231 == 0) goto <D.20581>; else goto <D.20582>;
  <D.20581>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.20586 = "System";
      D.20587 = MEM[(const unsigned char *)D.20586];
      D.20588 = (int) D.20587;
      D.20589 = *__s2;
      D.20590 = (int) D.20589;
      __result = D.20588 - D.20590;
      {
        if (__s1_len != 0) goto <D.20591>; else goto <D.20592>;
        <D.20591>:
        if (__result == 0) goto <D.20593>; else goto <D.20594>;
        <D.20593>:
        D.20595 = &MEM[(void *)"System" + 1B];
        D.20596 = *D.20595;
        D.20597 = (int) D.20596;
        D.20598 = __s2 + 1;
        D.20599 = *D.20598;
        D.20600 = (int) D.20599;
        __result = D.20597 - D.20600;
        if (__s1_len > 1) goto <D.20601>; else goto <D.20602>;
        <D.20601>:
        if (__result == 0) goto <D.20603>; else goto <D.20604>;
        <D.20603>:
        D.20605 = &MEM[(void *)"System" + 2B];
        D.20606 = *D.20605;
        D.20607 = (int) D.20606;
        D.20608 = __s2 + 2;
        D.20609 = *D.20608;
        D.20610 = (int) D.20609;
        __result = D.20607 - D.20610;
        if (__s1_len > 2) goto <D.20611>; else goto <D.20612>;
        <D.20611>:
        if (__result == 0) goto <D.20613>; else goto <D.20614>;
        <D.20613>:
        D.20615 = &MEM[(void *)"System" + 3B];
        D.20616 = *D.20615;
        D.20617 = (int) D.20616;
        D.20618 = __s2 + 3;
        D.20619 = *D.20618;
        D.20620 = (int) D.20619;
        __result = D.20617 - D.20620;
        <D.20614>:
        <D.20612>:
        <D.20604>:
        <D.20602>:
        <D.20594>:
        <D.20592>:
      }
      D.18236 = __result;
    }
    iftmp.81 = D.18236;
    goto <D.20621>;
    <D.20585>:
    D.20622 = klass->name_space;
    iftmp.81 = __builtin_strcmp ("System", D.20622);
    <D.20621>:
    D.18240 = iftmp.81;
  }
  if (D.18240 == 0) goto <D.20623>; else goto <D.20624>;
  <D.20623>:
  domain->ad_unloaded_ex_class = klass;
  D.20536 = 1;
  return D.20536;
  <D.20624>:
  <D.20582>:
  <D.20540>:
  D.20536 = 0;
  return D.20536;
}


mono_thread_pool_suspend ()
{
  suspended = 1;
}


mono_thread_pool_resume ()
{
  suspended = 0;
}


