mono_thread_pool_remove_socket (int sock)
{
  int D.19625;
  _Bool D.19630;
  long int D.19631;
  long int D.19632;
  struct MonoGHashTable * D.19635;
  _Bool D.19640;
  long int D.19641;
  long int D.19642;
  long int D.19645;
  const void * D.19646;
  void * list.0;
  struct MonoMList * list.1;
  _Bool D.19653;
  long int D.19654;
  long int D.19655;
  int D.19658;
  struct MonoMList * list;
  struct MonoSocketAsyncResult * state;
  struct MonoObject * ares;

  try
    {
      D.19625 = socket_io_data.inited;
      if (D.19625 == 0) goto <D.19626>; else goto <D.19627>;
      <D.19626>:
      return;
      <D.19627>:
      {
        int ret;

        ret = pthread_mutex_lock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.19628>; else goto <D.19629>;
        <D.19628>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.19629>:
        D.19630 = ret != 0;
        D.19631 = (long int) D.19630;
        D.19632 = __builtin_expect (D.19631, 0);
        if (D.19632 != 0) goto <D.19633>; else goto <D.19634>;
        <D.19633>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 446, "ret == 0");
        <D.19634>:
      }
      D.19635 = socket_io_data.sock_to_state;
      if (D.19635 == 0B) goto <D.19636>; else goto <D.19637>;
      <D.19636>:
      {
        int ret;

        ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.19638>; else goto <D.19639>;
        <D.19638>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19639>:
        D.19640 = ret != 0;
        D.19641 = (long int) D.19640;
        D.19642 = __builtin_expect (D.19641, 0);
        if (D.19642 != 0) goto <D.19643>; else goto <D.19644>;
        <D.19643>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 448, "ret == 0");
        <D.19644>:
      }
      return;
      <D.19637>:
      D.19635 = socket_io_data.sock_to_state;
      D.19645 = (long int) sock;
      D.19646 = (const void *) D.19645;
      list.0 = mono_g_hash_table_lookup (D.19635, D.19646);
      list = list.0;
      list.1 = list;
      if (list.1 != 0B) goto <D.19649>; else goto <D.19650>;
      <D.19649>:
      D.19635 = socket_io_data.sock_to_state;
      D.19645 = (long int) sock;
      D.19646 = (const void *) D.19645;
      mono_g_hash_table_remove (D.19635, D.19646);
      <D.19650>:
      {
        int ret;

        ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
        if (ret != 0) goto <D.19651>; else goto <D.19652>;
        <D.19651>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.19652>:
        D.19653 = ret != 0;
        D.19654 = (long int) D.19653;
        D.19655 = __builtin_expect (D.19654, 0);
        if (D.19655 != 0) goto <D.19656>; else goto <D.19657>;
        <D.19656>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 454, "ret == 0");
        <D.19657>:
      }
      goto <D.19248>;
      <D.19247>:
      list.1 = list;
      state = mono_mlist_get_data (list.1);
      D.19658 = state->operation;
      if (D.19658 == 2) goto <D.19659>; else goto <D.19660>;
      <D.19659>:
      state->operation = 6;
      goto <D.19661>;
      <D.19660>:
      D.19658 = state->operation;
      if (D.19658 == 4) goto <D.19662>; else goto <D.19663>;
      <D.19662>:
      state->operation = 7;
      <D.19663>:
      <D.19661>:
      ares = get_io_event (&list, 1);
      threadpool_append_job (&async_io_tp, ares);
      list.1 = list;
      if (list.1 != 0B) goto <D.19664>; else goto <D.19665>;
      <D.19664>:
      ares = get_io_event (&list, 4);
      threadpool_append_job (&async_io_tp, ares);
      <D.19665>:
      <D.19248>:
      list.1 = list;
      if (list.1 != 0B) goto <D.19247>; else goto <D.19249>;
      <D.19249>:
    }
  finally
    {
      list = {CLOBBER};
    }
}


get_io_event (struct MonoMList * * list, gint event)
{
  int D.19669;
  struct MonoMList * D.19675;
  struct MonoMList * D.19677;
  struct MonoMList * D.19678;
  struct MonoObject * D.19679;
  struct MonoObject * state;
  struct MonoMList * current;
  struct MonoMList * prev;

  current = *list;
  prev = 0B;
  state = 0B;
  goto <D.19237>;
  <D.19236>:
  state = mono_mlist_get_data (current);
  D.19669 = get_event_from_state (state);
  if (D.19669 == event) goto <D.19235>; else goto <D.19670>;
  <D.19670>:
  state = 0B;
  prev = current;
  current = mono_mlist_next (current);
  <D.19237>:
  if (current != 0B) goto <D.19236>; else goto <D.19235>;
  <D.19235>:
  if (current != 0B) goto <D.19671>; else goto <D.19672>;
  <D.19671>:
  if (prev != 0B) goto <D.19673>; else goto <D.19674>;
  <D.19673>:
  D.19675 = mono_mlist_next (current);
  mono_mlist_set_next (prev, D.19675);
  goto <D.19676>;
  <D.19674>:
  D.19677 = *list;
  D.19678 = mono_mlist_next (D.19677);
  *list = D.19678;
  <D.19676>:
  <D.19672>:
  D.19679 = state;
  return D.19679;
}


get_event_from_state (struct MonoSocketAsyncResult * state)
{
  int D.19681;
  int D.19682;

  D.19681 = state->operation;
  switch (D.19681) <default: <D.19211>, case 0: <D.19198>, case 1: <D.19208>, case 2: <D.19199>, case 3: <D.19201>, case 4: <D.19205>, case 5: <D.19207>, case 6: <D.19200>, case 7: <D.19206>, case 8: <D.19202>, case 10: <D.19210>, case 11: <D.19203>, case 12: <D.19204>, case 13: <D.19209>>
  <D.19198>:
  <D.19199>:
  <D.19200>:
  <D.19201>:
  <D.19202>:
  <D.19203>:
  <D.19204>:
  D.19682 = 1;
  return D.19682;
  <D.19205>:
  <D.19206>:
  <D.19207>:
  <D.19208>:
  <D.19209>:
  <D.19210>:
  D.19682 = 4;
  return D.19682;
  <D.19211>:
  monoeg_g_log (0B, 32, "get_event_from_state: unknown value in switch!!!");
  D.19682 = 0;
  return D.19682;
}


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.19684;
  int D.19687;
  volatile gint * D.19690;
  int D.19691;
  int D.19694;
  struct MonoDomain * D.19697;
  int D.19698;
  struct MonoDomain * D.19701;
  long unsigned int D.19702;
  long unsigned int D.19703;
  struct MonoObject * * D.19704;
  struct MonoVTable * D.19708;
  struct MonoDomain * D.19709;
  int D.19710;
  int D.19713;
  int D.19714;
  long int D.19717;
  void * D.19718;
  int D.19721;
  struct MonoCQ * D.19724;
  int D.19725;
  int iftmp.2;
  int D.19728;
  static int job_counter;
  struct MonoObject * ar;
  gint i;

  D.19684 = mono_runtime_is_shutting_down ();
  if (D.19684 != 0) goto <D.19685>; else goto <D.19686>;
  <D.19685>:
  return;
  <D.19686>:
  D.19687 = tp->pool_status;
  if (D.19687 == 0) goto <D.19688>; else goto <D.19689>;
  <D.19688>:
  D.19690 = &tp->pool_status;
  D.19691 = InterlockedCompareExchange (D.19690, 1, 0);
  if (D.19691 == 0) goto <D.19692>; else goto <D.19693>;
  <D.19692>:
  D.19694 = tp->is_io;
  if (D.19694 == 0) goto <D.19695>; else goto <D.19696>;
  <D.19695>:
  D.19697 = mono_get_root_domain ();
  mono_thread_create_internal (D.19697, monitor_thread, 0B, 1, 0, 262144);
  threadpool_start_thread (tp);
  <D.19696>:
  D.19698 = mono_config_is_server_mode ();
  if (D.19698 != 0) goto <D.19699>; else goto <D.19700>;
  <D.19699>:
  D.19701 = mono_get_root_domain ();
  mono_thread_create_internal (D.19701, threadpool_start_idle_threads, tp, 1, 0, 262144);
  <D.19700>:
  <D.19693>:
  <D.19689>:
  i = 0;
  goto <D.19421>;
  <D.19420>:
  D.19702 = (long unsigned int) i;
  D.19703 = D.19702 * 8;
  D.19704 = jobs + D.19703;
  ar = *D.19704;
  if (ar == 0B) goto <D.19705>; else goto <D.19707>;
  <D.19707>:
  D.19708 = ar->vtable;
  D.19709 = D.19708->domain;
  D.19710 = mono_domain_is_unloading (D.19709);
  if (D.19710 != 0) goto <D.19705>; else goto <D.19706>;
  <D.19705>:
  // predicted unlikely by continue predictor.
  goto <D.19418>;
  <D.19706>:
  D.19694 = tp->is_io;
  if (D.19694 == 0) goto <D.19711>; else goto <D.19712>;
  <D.19711>:
  D.19713 = InterlockedIncrement (&job_counter);
  D.19714 = D.19713 % 10;
  if (D.19714 == 0) goto <D.19715>; else goto <D.19716>;
  <D.19715>:
  {
    struct MonoAsyncResult * o;

    o = ar;
    D.19717 = mono_100ns_ticks ();
    o->add_time = D.19717;
  }
  <D.19716>:
  <D.19712>:
  threadpool_jobs_inc (ar);
  D.19718 = tp->pc_nitems;
  mono_perfcounter_update_value (D.19718, 1, 1);
  D.19694 = tp->is_io;
  if (D.19694 == 0) goto <D.19719>; else goto <D.19720>;
  <D.19719>:
  D.19721 = mono_wsq_local_push (ar);
  if (D.19721 != 0) goto <D.19722>; else goto <D.19723>;
  <D.19722>:
  // predicted unlikely by continue predictor.
  goto <D.19418>;
  <D.19723>:
  <D.19720>:
  D.19724 = tp->queue;
  mono_cq_enqueue (D.19724, ar);
  <D.19418>:
  i = i + 1;
  <D.19421>:
  if (i < njobs) goto <D.19420>; else goto <D.19422>;
  <D.19422>:
  i = 0;
  goto <D.19424>;
  <D.19423>:
  pulse_on_new_job (tp);
  i = i + 1;
  <D.19424>:
  D.19725 = tp->waiting;
  if (D.19725 > 0) goto <D.19726>; else goto <D.19425>;
  <D.19726>:
  D.19728 = tp->max_threads;
  if (D.19728 <= njobs) goto <D.19729>; else goto <D.19730>;
  <D.19729>:
  iftmp.2 = tp->max_threads;
  goto <D.19731>;
  <D.19730>:
  iftmp.2 = njobs;
  <D.19731>:
  if (iftmp.2 > i) goto <D.19423>; else goto <D.19425>;
  <D.19425>:
}


threadpool_start_idle_threads (struct ThreadPool * tp)
{
  guint32 iftmp.3;
  int D.19734;
  int D.19738;
  volatile gint * D.19741;
  int D.19742;
  int D.19743;
  void * D.19745;
  struct MonoDomain * D.19746;
  void (*<Tc09>) (void *) D.19747;
  int n;
  guint32 stack_size;

  D.19734 = tp->is_io;
  if (D.19734 == 0) goto <D.19735>; else goto <D.19736>;
  <D.19735>:
  iftmp.3 = 0;
  goto <D.19737>;
  <D.19736>:
  iftmp.3 = 262144;
  <D.19737>:
  stack_size = iftmp.3;
  <D.19299>:
  <D.19298>:
  n = tp->nthreads;
  D.19738 = tp->min_threads;
  if (D.19738 <= n) goto <D.19739>; else goto <D.19740>;
  <D.19739>:
  return;
  <D.19740>:
  D.19741 = &tp->nthreads;
  D.19742 = n + 1;
  D.19743 = InterlockedCompareExchange (D.19741, D.19742, n);
  if (D.19743 == n) goto <D.19297>; else goto <D.19744>;
  <D.19744>:
  goto <D.19298>;
  <D.19297>:
  D.19745 = tp->pc_nthreads;
  mono_perfcounter_update_value (D.19745, 1, 1);
  D.19746 = mono_get_root_domain ();
  D.19747 = tp->async_invoke;
  mono_thread_create_internal (D.19746, D.19747, tp, 1, 0, stack_size);
  SleepEx (100, 1);
  goto <D.19299>;
}


monitor_thread (void * unused)
{
  struct MonoDomain * D.19749;
  struct MonoString * D.19750;
  unsigned int D.19751;
  unsigned int D.19753;
  unsigned int D.19754;
  int D.19755;
  unsigned int D.19757;
  unsigned int D.19758;
  int i.4;
  int D.19763;
  int suspended.5;
  int D.19768;
  struct MonoCQ * D.19771;
  int D.19772;
  _Bool D.19773;
  int D.19776;
  _Bool D.19781;
  long int D.19782;
  long int D.19783;
  struct GPtrArray * wsqs.6;
  void * * D.19787;
  long unsigned int D.19788;
  long unsigned int D.19789;
  void * * D.19790;
  int D.19791;
  unsigned int i.7;
  unsigned int D.19796;
  _Bool D.19799;
  long int D.19800;
  long int D.19801;
  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.19749 = mono_domain_get ();
      D.19750 = mono_string_new (D.19749, "Threadpool monitor");
      ves_icall_System_Threading_Thread_SetName_internal (thread, D.19750);
      <D.19341>:
      ms = 500;
      i = 10;
      <D.19327>:
      {
        guint32 ts;

        ts = mono_msec_ticks ();
        D.19751 = SleepEx (ms, 1);
        if (D.19751 == 0) goto <D.19326>; else goto <D.19752>;
        <D.19752>:
        D.19753 = mono_msec_ticks ();
        D.19754 = D.19753 - ts;
        ms = ms - D.19754;
        D.19755 = mono_runtime_is_shutting_down ();
        if (D.19755 != 0) goto <D.19326>; else goto <D.19756>;
        <D.19756>:
        D.19757 = thread->state;
        D.19758 = D.19757 & 3;
        if (D.19758 != 0) goto <D.19759>; else goto <D.19760>;
        <D.19759>:
        mono_thread_interruption_checkpoint ();
        <D.19760>:
      }
      if (ms != 0) goto <D.19761>; else goto <D.19326>;
      <D.19761>:
      i.4 = i;
      i = i.4 + -1;
      if (i.4 != 0) goto <D.19327>; else goto <D.19326>;
      <D.19326>:
      D.19763 = mono_runtime_is_shutting_down ();
      if (D.19763 != 0) goto <D.19328>; else goto <D.19764>;
      <D.19764>:
      suspended.5 = suspended;
      if (suspended.5 != 0) goto <D.19766>; else goto <D.19767>;
      <D.19766>:
      // predicted unlikely by continue predictor.
      goto <D.19329>;
      <D.19767>:
      i = 0;
      goto <D.19339>;
      <D.19338>:
      {
        struct ThreadPool * tp;

        tp = pools[i];
        D.19768 = tp->waiting;
        if (D.19768 > 0) goto <D.19769>; else goto <D.19770>;
        <D.19769>:
        // predicted unlikely by continue predictor.
        goto <D.19331>;
        <D.19770>:
        D.19771 = tp->queue;
        D.19772 = mono_cq_count (D.19771);
        D.19773 = D.19772 > 0;
        need_one = (gboolean) D.19773;
        if (need_one == 0) goto <D.19774>; else goto <D.19775>;
        <D.19774>:
        D.19776 = tp->is_io;
        if (D.19776 == 0) goto <D.19777>; else goto <D.19778>;
        <D.19777>:
        {
          int ret;

          ret = pthread_mutex_lock (&wsqs_lock.mutex);
          if (ret != 0) goto <D.19779>; else goto <D.19780>;
          <D.19779>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
          <D.19780>:
          D.19781 = ret != 0;
          D.19782 = (long int) D.19781;
          D.19783 = __builtin_expect (D.19782, 0);
          if (D.19783 != 0) goto <D.19784>; else goto <D.19785>;
          <D.19784>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 801, "ret == 0");
          <D.19785>:
        }
        i = 0;
        goto <D.19336>;
        <D.19335>:
        {
          struct MonoWSQ * wsq;

          wsqs.6 = wsqs;
          D.19787 = wsqs.6->pdata;
          D.19788 = (long unsigned int) i;
          D.19789 = D.19788 * 8;
          D.19790 = D.19787 + D.19789;
          wsq = *D.19790;
          D.19791 = mono_wsq_count (wsq);
          if (D.19791 != 0) goto <D.19792>; else goto <D.19793>;
          <D.19792>:
          need_one = 1;
          goto <D.19334>;
          <D.19793>:
        }
        i = i + 1;
        <D.19336>:
        wsqs.6 = wsqs;
        if (wsqs.6 != 0B) goto <D.19794>; else goto <D.19334>;
        <D.19794>:
        i.7 = (unsigned int) i;
        wsqs.6 = wsqs;
        D.19796 = wsqs.6->len;
        if (i.7 < D.19796) goto <D.19335>; else goto <D.19334>;
        <D.19334>:
        {
          int ret;

          ret = pthread_mutex_unlock (&wsqs_lock.mutex);
          if (ret != 0) goto <D.19797>; else goto <D.19798>;
          <D.19797>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.19798>:
          D.19799 = ret != 0;
          D.19800 = (long int) D.19799;
          D.19801 = __builtin_expect (D.19800, 0);
          if (D.19801 != 0) goto <D.19802>; else goto <D.19803>;
          <D.19802>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 810, "ret == 0");
          <D.19803>:
        }
        <D.19778>:
        <D.19775>:
        if (need_one != 0) goto <D.19804>; else goto <D.19805>;
        <D.19804>:
        threadpool_start_thread (tp);
        <D.19805>:
      }
      <D.19331>:
      i = i + 1;
      <D.19339>:
      if (i <= 1) goto <D.19338>; else goto <D.19340>;
      <D.19340>:
      <D.19329>:
      goto <D.19341>;
      <D.19328>:
    }
  finally
    {
      pools = {CLOBBER};
    }
}


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

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


threadpool_start_thread (struct ThreadPool * tp)
{
  guint32 iftmp.10;
  int D.19812;
  volatile gint * D.19816;
  int D.19817;
  int D.19818;
  void * D.19821;
  struct MonoDomain * D.19822;
  void (*<Tc09>) (void *) D.19823;
  gboolean D.19824;
  int D.19825;
  int D.19827;
  gint n;
  guint32 stack_size;

  D.19812 = tp->is_io;
  if (D.19812 == 0) goto <D.19813>; else goto <D.19814>;
  <D.19813>:
  iftmp.10 = 0;
  goto <D.19815>;
  <D.19814>:
  iftmp.10 = 262144;
  <D.19815>:
  stack_size = iftmp.10;
  goto <D.19398>;
  <D.19397>:
  D.19816 = &tp->nthreads;
  D.19817 = n + 1;
  D.19818 = InterlockedCompareExchange (D.19816, D.19817, n);
  if (D.19818 == n) goto <D.19819>; else goto <D.19820>;
  <D.19819>:
  D.19821 = tp->pc_nthreads;
  mono_perfcounter_update_value (D.19821, 1, 1);
  D.19822 = mono_get_root_domain ();
  D.19823 = tp->async_invoke;
  mono_thread_create_internal (D.19822, D.19823, tp, 1, 0, stack_size);
  D.19824 = 1;
  return D.19824;
  <D.19820>:
  <D.19398>:
  D.19825 = mono_runtime_is_shutting_down ();
  if (D.19825 == 0) goto <D.19826>; else goto <D.19399>;
  <D.19826>:
  n = tp->nthreads;
  D.19827 = tp->max_threads;
  if (n < D.19827) goto <D.19397>; else goto <D.19399>;
  <D.19399>:
  D.19824 = 0;
  return D.19824;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.19829;
  unsigned int D.19830;

  D.19830 = __sync_add_and_fetch_4 (val, 1);
  D.19829 = (gint32) D.19830;
  return D.19829;
}


threadpool_jobs_inc (struct MonoObject * obj)
{
  struct MonoVTable * D.19834;
  struct MonoDomain * D.19835;
  volatile int * D.19836;

  if (obj != 0B) goto <D.19832>; else goto <D.19833>;
  <D.19832>:
  D.19834 = obj->vtable;
  D.19835 = D.19834->domain;
  D.19836 = &D.19835->threadpool_jobs;
  InterlockedIncrement (D.19836);
  <D.19833>:
}


pulse_on_new_job (struct ThreadPool * tp)
{
  int D.19837;
  union MonoSemType * D.19840;

  D.19837 = tp->waiting;
  if (D.19837 != 0) goto <D.19838>; else goto <D.19839>;
  <D.19838>:
  D.19840 = &tp->new_job;
  mono_sem_post (D.19840);
  <D.19839>:
}


mono_thread_pool_init_tls ()
{
  mono_wsq_init ();
}


mono_thread_pool_init ()
{
  int tp_inited.11;
  int tp_inited.12;
  int D.19849;
  const gchar * D.19852;
  const gchar * D.19855;
  int D.19858;
  int D.19859;
  int D.19860;
  int D.19861;
  int D.19862;
  struct MonoImage * D.19863;
  struct MonoClass * async_call_klass.13;
  struct MonoClass * async_call_klass.14;
  _Bool D.19866;
  long int D.19867;
  long int D.19868;
  unsigned int D.19871;
  struct GPtrArray * wsqs.15;
  void * D.19873;
  void * D.19874;
  _Bool D.19875;
  long int D.19876;
  long int D.19877;
  void * D.19880;
  void * D.19881;
  _Bool D.19882;
  long int D.19883;
  long int D.19884;
  void * D.19887;
  void * D.19888;
  _Bool D.19889;
  long int D.19890;
  long int D.19891;
  void * D.19894;
  void * D.19895;
  _Bool D.19896;
  long int D.19897;
  long int D.19898;
  gint threads_per_cpu;
  gint thread_count;
  gint cpu_count;
  int result;

  threads_per_cpu = 1;
  cpu_count = mono_cpu_count ();
  tp_inited.11 = tp_inited;
  if (tp_inited.11 == 2) goto <D.19842>; else goto <D.19843>;
  <D.19842>:
  return;
  <D.19843>:
  result = InterlockedCompareExchange (&tp_inited, 1, 0);
  if (result == 1) goto <D.19844>; else goto <D.19845>;
  <D.19844>:
  <D.19352>:
  SleepEx (1, 0);
  tp_inited.12 = tp_inited;
  if (tp_inited.12 == 2) goto <D.19847>; else goto <D.19848>;
  <D.19847>:
  return;
  <D.19848>:
  goto <D.19352>;
  <D.19845>:
  D.19849 = mono_gc_is_moving ();
  if (D.19849 == 0) goto <D.19850>; else goto <D.19851>;
  <D.19850>:
  mono_gc_register_root (&socket_io_data.sock_to_state, 8, 0B);
  <D.19851>:
  InitializeCriticalSection (&socket_io_data.io_lock);
  D.19852 = monoeg_g_getenv ("MONO_THREADS_PER_CPU");
  if (D.19852 != 0B) goto <D.19853>; else goto <D.19854>;
  <D.19853>:
  D.19855 = monoeg_g_getenv ("MONO_THREADS_PER_CPU");
  threads_per_cpu = atoi (D.19855);
  if (threads_per_cpu <= 0) goto <D.19856>; else goto <D.19857>;
  <D.19856>:
  threads_per_cpu = 1;
  <D.19857>:
  <D.19854>:
  D.19858 = cpu_count * 100;
  D.19859 = cpu_count * threads_per_cpu;
  thread_count = MIN_EXPR <D.19858, D.19859>;
  D.19858 = cpu_count * 100;
  D.19860 = MAX_EXPR <D.19858, thread_count>;
  threadpool_init (&async_tp, thread_count, D.19860, async_invoke_thread);
  D.19861 = cpu_count * 2;
  D.19862 = cpu_count * 4;
  threadpool_init (&async_io_tp, D.19861, D.19862, async_invoke_thread);
  async_io_tp.is_io = 1;
  D.19863 = mono_defaults.corlib;
  async_call_klass.13 = mono_class_from_name (D.19863, "System", "MonoAsyncCall");
  async_call_klass = async_call_klass.13;
  async_call_klass.14 = async_call_klass;
  D.19866 = async_call_klass.14 == 0B;
  D.19867 = (long int) D.19866;
  D.19868 = __builtin_expect (D.19867, 0);
  if (D.19868 != 0) goto <D.19869>; else goto <D.19870>;
  <D.19869>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 858, "async_call_klass");
  <D.19870>:
  InitializeCriticalSection (&wsqs_lock);
  D.19858 = cpu_count * 100;
  D.19860 = MAX_EXPR <D.19858, thread_count>;
  D.19871 = (unsigned int) D.19860;
  wsqs.15 = monoeg_g_ptr_array_sized_new (D.19871);
  wsqs = wsqs.15;
  D.19873 = init_perf_counter ("Mono Threadpool", "Work Items Added");
  async_tp.pc_nitems = D.19873;
  D.19874 = async_tp.pc_nitems;
  D.19875 = D.19874 == 0B;
  D.19876 = (long int) D.19875;
  D.19877 = __builtin_expect (D.19876, 0);
  if (D.19877 != 0) goto <D.19878>; else goto <D.19879>;
  <D.19878>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 865, "async_tp.pc_nitems");
  <D.19879>:
  D.19880 = init_perf_counter ("Mono Threadpool", "IO Work Items Added");
  async_io_tp.pc_nitems = D.19880;
  D.19881 = async_io_tp.pc_nitems;
  D.19882 = D.19881 == 0B;
  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", "threadpool.c", 868, "async_io_tp.pc_nitems");
  <D.19886>:
  D.19887 = init_perf_counter ("Mono Threadpool", "# of Threads");
  async_tp.pc_nthreads = D.19887;
  D.19888 = async_tp.pc_nthreads;
  D.19889 = D.19888 == 0B;
  D.19890 = (long int) D.19889;
  D.19891 = __builtin_expect (D.19890, 0);
  if (D.19891 != 0) goto <D.19892>; else goto <D.19893>;
  <D.19892>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 871, "async_tp.pc_nthreads");
  <D.19893>:
  D.19894 = init_perf_counter ("Mono Threadpool", "# of IO Threads");
  async_io_tp.pc_nthreads = D.19894;
  D.19895 = async_io_tp.pc_nthreads;
  D.19896 = D.19895 == 0B;
  D.19897 = (long int) D.19896;
  D.19898 = __builtin_expect (D.19897, 0);
  if (D.19898 != 0) goto <D.19899>; else goto <D.19900>;
  <D.19899>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 874, "async_io_tp.pc_nthreads");
  <D.19900>:
  tp_inited = 2;
}


async_invoke_thread (void * data)
{
  int D.19902;
  void (*<Tc09>) (void *) tp_start_func.16;
  void * tp_hooks_user_data.17;
  volatile gint * D.19911;
  struct MonoVTable * D.19912;
  void * data.18;
  struct MonoVTable * D.19914;
  int D.19915;
  _Bool D.19916;
  int D.19919;
  void * D.19920;
  long int D.19921;
  unsigned int D.19922;
  struct MonoArray * D.19923;
  int D.19924;
  int D.19925;
  int D.19926;
  gint * D.19927;
  int D.19928;
  int D.19929;
  _Bool D.19931;
  long int D.19932;
  long int D.19933;
  int D.19939;
  int D.19941;
  volatile gint * D.19942;
  int D.19943;
  volatile gint * D.19946;
  int D.19947;
  void (*<Tc09>) (void *) tp_item_begin_func.19;
  void * tp_item_user_data.20;
  long int D.19956;
  void (*<Tc09>) (void *) tp_item_end_func.21;
  unsigned char D.19968;
  struct MonoDelegate * D.19971;
  struct MonoDomain * D.19974;
  volatile gint * D.19975;
  int D.19981;
  volatile gint * D.19982;
  volatile gint * D.19985;
  int D.19986;
  struct MonoCQ * D.19988;
  int D.19989;
  union MonoSemType * D.19991;
  volatile gint * D.19992;
  int D.19993;
  int D.20001;
  volatile gint * D.20008;
  int D.20013;
  volatile gint * D.20018;
  int D.20019;
  int D.20020;
  void * D.20021;
  void (*<Tc09>) (void *) tp_finish_func.22;
  struct MonoDomain * domain;
  struct MonoWSQ * wsq;
  struct ThreadPool * tp;
  gboolean must_die;

  tp = data;
  wsq = 0B;
  D.19902 = tp->is_io;
  if (D.19902 == 0) goto <D.19903>; else goto <D.19904>;
  <D.19903>:
  wsq = add_wsq ();
  <D.19904>:
  set_tp_thread_info (tp);
  tp_start_func.16 = tp_start_func;
  if (tp_start_func.16 != 0B) goto <D.19906>; else goto <D.19907>;
  <D.19906>:
  tp_start_func.16 = tp_start_func;
  tp_hooks_user_data.17 = tp_hooks_user_data;
  tp_start_func.16 (tp_hooks_user_data.17);
  <D.19907>:
  data = 0B;
  <D.19577>:
  {
    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.19909>; else goto <D.19910>;
    <D.19909>:
    D.19911 = &tp->busy_threads;
    InterlockedIncrement (D.19911);
    D.19912 = MEM[(struct MonoObject *)ar].vtable;
    domain = D.19912->domain;
    data.18 = data;
    D.19914 = MEM[(struct MonoObject *)data.18].vtable;
    klass = D.19914->klass;
    D.19915 = is_corlib_asyncresult (domain, klass);
    D.19916 = D.19915 == 0;
    is_io_task = (gboolean) D.19916;
    is_socket = 0;
    if (is_io_task != 0) goto <D.19917>; else goto <D.19918>;
    <D.19917>:
    {
      struct MonoSocketAsyncResult * state;

      state = data;
      is_socket = is_socketasyncresult (domain, klass);
      ar = state->ares;
      D.19919 = state->operation;
      switch (D.19919) <default: <D.19930>, case 2: <D.19559>, case 4: <D.19561>>
      <D.19559>:
      D.19920 = state->handle;
      D.19921 = (long int) D.19920;
      D.19922 = (unsigned int) D.19921;
      D.19923 = state->buffer;
      D.19924 = state->offset;
      D.19925 = state->size;
      D.19926 = state->socket_flags;
      D.19927 = &state->error;
      D.19928 = ves_icall_System_Net_Sockets_Socket_Receive_internal (D.19922, D.19923, D.19924, D.19925, D.19926, D.19927);
      state->total = D.19928;
      goto <D.19560>;
      <D.19561>:
      D.19920 = state->handle;
      D.19921 = (long int) D.19920;
      D.19922 = (unsigned int) D.19921;
      D.19923 = state->buffer;
      D.19924 = state->offset;
      D.19925 = state->size;
      D.19926 = state->socket_flags;
      D.19927 = &state->error;
      D.19929 = ves_icall_System_Net_Sockets_Socket_Send_internal (D.19922, D.19923, D.19924, D.19925, D.19926, D.19927);
      state->total = D.19929;
      goto <D.19560>;
      <D.19930>:
      <D.19560>:
    }
    <D.19918>:
    D.19931 = domain == 0B;
    D.19932 = (long int) D.19931;
    D.19933 = __builtin_expect (D.19932, 0);
    if (D.19933 != 0) goto <D.19934>; else goto <D.19935>;
    <D.19934>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1492, "domain");
    <D.19935>:
    D.19939 = mono_domain_is_unloading (domain);
    if (D.19939 != 0) goto <D.19936>; else goto <D.19940>;
    <D.19940>:
    D.19941 = mono_runtime_is_shutting_down ();
    if (D.19941 != 0) goto <D.19936>; else goto <D.19937>;
    <D.19936>:
    threadpool_jobs_dec (ar);
    data = 0B;
    ar = 0B;
    D.19942 = &tp->busy_threads;
    InterlockedDecrement (D.19942);
    goto <D.19938>;
    <D.19937>:
    mono_thread_push_appdomain_ref (domain);
    D.19943 = threadpool_jobs_dec (ar);
    if (D.19943 != 0) goto <D.19944>; else goto <D.19945>;
    <D.19944>:
    data = 0B;
    ar = 0B;
    mono_thread_pop_appdomain_ref ();
    D.19946 = &tp->busy_threads;
    InterlockedDecrement (D.19946);
    // predicted unlikely by continue predictor.
    goto <D.19562>;
    <D.19945>:
    D.19947 = mono_domain_set (domain, 0);
    if (D.19947 != 0) goto <D.19948>; else goto <D.19949>;
    <D.19948>:
    {
      struct MonoObject * exc;

      tp_item_begin_func.19 = tp_item_begin_func;
      if (tp_item_begin_func.19 != 0B) goto <D.19951>; else goto <D.19952>;
      <D.19951>:
      tp_item_begin_func.19 = tp_item_begin_func;
      tp_item_user_data.20 = tp_item_user_data;
      tp_item_begin_func.19 (tp_item_user_data.20);
      <D.19952>:
      if (is_io_task == 0) goto <D.19954>; else goto <D.19955>;
      <D.19954>:
      D.19956 = ar->add_time;
      if (D.19956 > 0) goto <D.19957>; else goto <D.19958>;
      <D.19957>:
      D.19956 = ar->add_time;
      process_idle_times (tp, D.19956);
      <D.19958>:
      <D.19955>:
      exc = mono_async_invoke (tp, ar);
      tp_item_end_func.21 = tp_item_end_func;
      if (tp_item_end_func.21 != 0B) goto <D.19960>; else goto <D.19961>;
      <D.19960>:
      tp_item_end_func.21 = tp_item_end_func;
      tp_item_user_data.20 = tp_item_user_data;
      tp_item_end_func.21 (tp_item_user_data.20);
      <D.19961>:
      if (exc != 0B) goto <D.19962>; else goto <D.19963>;
      <D.19962>:
      mono_internal_thread_unhandled_exception (exc);
      <D.19963>:
      if (is_socket != 0) goto <D.19964>; else goto <D.19965>;
      <D.19964>:
      D.19902 = tp->is_io;
      if (D.19902 != 0) goto <D.19966>; else goto <D.19967>;
      <D.19966>:
      {
        struct MonoSocketAsyncResult * state;

        state = data;
        D.19968 = state->completed;
        if (D.19968 != 0) goto <D.19969>; else goto <D.19970>;
        <D.19969>:
        D.19971 = state->callback;
        if (D.19971 != 0B) goto <D.19972>; else goto <D.19973>;
        <D.19972>:
        {
          struct MonoAsyncResult * cb_ares;

          D.19971 = state->callback;
          cb_ares = create_simple_asyncresult (D.19971, state);
          icall_append_job (cb_ares);
        }
        <D.19973>:
        <D.19970>:
      }
      <D.19967>:
      <D.19965>:
      D.19974 = mono_get_root_domain ();
      mono_domain_set (D.19974, 1);
    }
    <D.19949>:
    mono_thread_pop_appdomain_ref ();
    D.19975 = &tp->busy_threads;
    InterlockedDecrement (D.19975);
    clear_thread_state ();
    <D.19938>:
    <D.19910>:
    ar = 0B;
    data = 0B;
    must_die = should_i_die (tp);
    if (must_die == 0) goto <D.19978>; else goto <D.19979>;
    <D.19978>:
    D.19902 = tp->is_io;
    if (D.19902 != 0) goto <D.19976>; else goto <D.19980>;
    <D.19980>:
    D.19981 = mono_wsq_local_pop (&data);
    if (D.19981 == 0) goto <D.19976>; else goto <D.19977>;
    <D.19976>:
    dequeue_or_steal (tp, &data, wsq);
    <D.19977>:
    <D.19979>:
    n_naps = 0;
    goto <D.19572>;
    <D.19571>:
    {
      gboolean res;

      D.19982 = &tp->waiting;
      InterlockedIncrement (D.19982);
      dequeue_or_steal (tp, &data, wsq);
      data.18 = data;
      if (data.18 != 0B) goto <D.19983>; else goto <D.19984>;
      <D.19983>:
      D.19985 = &tp->waiting;
      InterlockedDecrement (D.19985);
      goto <D.19567>;
      <D.19984>:
      mono_gc_set_skip_thread (1);
      goto <D.19570>;
      <D.19569>:
      D.19986 = mono_runtime_is_shutting_down ();
      if (D.19986 != 0) goto <D.19568>; else goto <D.19987>;
      <D.19987>:
      check_for_interruption_critical ();
      <D.19570>:
      D.19988 = tp->queue;
      D.19989 = mono_cq_count (D.19988);
      if (D.19989 == 0) goto <D.19990>; else goto <D.19568>;
      <D.19990>:
      D.19991 = &tp->new_job;
      res = mono_sem_timedwait (D.19991, 2000, 1);
      if (res == -1) goto <D.19569>; else goto <D.19568>;
      <D.19568>:
      D.19992 = &tp->waiting;
      InterlockedDecrement (D.19992);
      mono_gc_set_skip_thread (0);
      D.19993 = mono_runtime_is_shutting_down ();
      if (D.19993 != 0) goto <D.19567>; else goto <D.19994>;
      <D.19994>:
      must_die = should_i_die (tp);
      dequeue_or_steal (tp, &data, wsq);
      n_naps = n_naps + 1;
    }
    <D.19572>:
    if (must_die == 0) goto <D.19995>; else goto <D.19567>;
    <D.19995>:
    data.18 = data;
    if (data.18 == 0B) goto <D.19996>; else goto <D.19567>;
    <D.19996>:
    if (n_naps <= 3) goto <D.19571>; else goto <D.19567>;
    <D.19567>:
    data.18 = data;
    if (data.18 == 0B) goto <D.19997>; else goto <D.19998>;
    <D.19997>:
    D.19902 = tp->is_io;
    if (D.19902 == 0) goto <D.19999>; else goto <D.20000>;
    <D.19999>:
    D.20001 = mono_runtime_is_shutting_down ();
    if (D.20001 == 0) goto <D.20002>; else goto <D.20003>;
    <D.20002>:
    mono_wsq_local_pop (&data);
    data.18 = data;
    if (data.18 != 0B) goto <D.20004>; else goto <D.20005>;
    <D.20004>:
    if (must_die != 0) goto <D.20006>; else goto <D.20007>;
    <D.20006>:
    D.20008 = &tp->destroy_thread;
    InterlockedCompareExchange (D.20008, 1, 0);
    pulse_on_new_job (tp);
    <D.20007>:
    <D.20005>:
    <D.20003>:
    <D.20000>:
    <D.19998>:
    data.18 = data;
    if (data.18 == 0B) goto <D.20009>; else goto <D.20010>;
    <D.20009>:
    {
      gint nt;
      gboolean down;

      <D.19576>:
      nt = tp->nthreads;
      down = mono_runtime_is_shutting_down ();
      if (down == 0) goto <D.20011>; else goto <D.20012>;
      <D.20011>:
      D.20013 = tp->min_threads;
      if (D.20013 >= nt) goto <D.19575>; else goto <D.20014>;
      <D.20014>:
      <D.20012>:
      if (down != 0) goto <D.20015>; else goto <D.20017>;
      <D.20017>:
      D.20018 = &tp->nthreads;
      D.20019 = nt + -1;
      D.20020 = InterlockedCompareExchange (D.20018, D.20019, nt);
      if (D.20020 == nt) goto <D.20015>; else goto <D.20016>;
      <D.20015>:
      D.20021 = tp->pc_nthreads;
      mono_perfcounter_update_value (D.20021, 1, -1);
      D.19902 = tp->is_io;
      if (D.19902 == 0) goto <D.20022>; else goto <D.20023>;
      <D.20022>:
      remove_wsq (wsq);
      <D.20023>:
      fire_profiler_thread_end ();
      tp_finish_func.22 = tp_finish_func;
      if (tp_finish_func.22 != 0B) goto <D.20025>; else goto <D.20026>;
      <D.20025>:
      tp_finish_func.22 = tp_finish_func;
      tp_hooks_user_data.17 = tp_hooks_user_data;
      tp_finish_func.22 (tp_hooks_user_data.17);
      <D.20026>:
      return;
      <D.20016>:
      goto <D.19576>;
      <D.19575>:
    }
    <D.20010>:
  }
  <D.19562>:
  goto <D.19577>;
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "threadpool.c", 1616);
}


add_wsq ()
{
  _Bool D.20030;
  long int D.20031;
  long int D.20032;
  struct GPtrArray * wsqs.23;
  _Bool D.20040;
  long int D.20041;
  long int D.20042;
  struct MonoWSQ * D.20045;
  void * * D.20046;
  long unsigned int D.20047;
  long unsigned int D.20048;
  void * * D.20049;
  void * D.20050;
  _Bool D.20055;
  long int D.20056;
  long int D.20057;
  unsigned int i.24;
  unsigned int D.20061;
  _Bool D.20064;
  long int D.20065;
  long int D.20066;
  int i;
  struct MonoWSQ * wsq;

  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20028>; else goto <D.20029>;
    <D.20028>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20029>:
    D.20030 = ret != 0;
    D.20031 = (long int) D.20030;
    D.20032 = __builtin_expect (D.20031, 0);
    if (D.20032 != 0) goto <D.20033>; else goto <D.20034>;
    <D.20033>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1221, "ret == 0");
    <D.20034>:
  }
  wsq = mono_wsq_create ();
  wsqs.23 = wsqs;
  if (wsqs.23 == 0B) goto <D.20036>; else goto <D.20037>;
  <D.20036>:
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20038>; else goto <D.20039>;
    <D.20038>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20039>:
    D.20040 = ret != 0;
    D.20041 = (long int) D.20040;
    D.20042 = __builtin_expect (D.20041, 0);
    if (D.20042 != 0) goto <D.20043>; else goto <D.20044>;
    <D.20043>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1224, "ret == 0");
    <D.20044>:
  }
  D.20045 = 0B;
  return D.20045;
  <D.20037>:
  i = 0;
  goto <D.19477>;
  <D.19476>:
  wsqs.23 = wsqs;
  D.20046 = wsqs.23->pdata;
  D.20047 = (long unsigned int) i;
  D.20048 = D.20047 * 8;
  D.20049 = D.20046 + D.20048;
  D.20050 = *D.20049;
  if (D.20050 == 0B) goto <D.20051>; else goto <D.20052>;
  <D.20051>:
  wsqs.23 = wsqs;
  D.20046 = wsqs.23->pdata;
  D.20047 = (long unsigned int) i;
  D.20048 = D.20047 * 8;
  D.20049 = D.20046 + D.20048;
  *D.20049 = wsq;
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20053>; else goto <D.20054>;
    <D.20053>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20054>:
    D.20055 = ret != 0;
    D.20056 = (long int) D.20055;
    D.20057 = __builtin_expect (D.20056, 0);
    if (D.20057 != 0) goto <D.20058>; else goto <D.20059>;
    <D.20058>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1230, "ret == 0");
    <D.20059>:
  }
  D.20045 = wsq;
  return D.20045;
  <D.20052>:
  i = i + 1;
  <D.19477>:
  i.24 = (unsigned int) i;
  wsqs.23 = wsqs;
  D.20061 = wsqs.23->len;
  if (i.24 < D.20061) goto <D.19476>; else goto <D.19478>;
  <D.19478>:
  wsqs.23 = wsqs;
  monoeg_g_ptr_array_add (wsqs.23, wsq);
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20062>; else goto <D.20063>;
    <D.20062>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20063>:
    D.20064 = ret != 0;
    D.20065 = (long int) D.20064;
    D.20066 = __builtin_expect (D.20065, 0);
    if (D.20066 != 0) goto <D.20067>; else goto <D.20068>;
    <D.20067>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1235, "ret == 0");
    <D.20068>:
  }
  D.20045 = wsq;
  return D.20045;
}


set_tp_thread_info (struct ThreadPool * tp)
{
  long unsigned int D.20070;
  const gchar * iftmp.25;
  int D.20072;
  struct MonoDomain * D.20076;
  struct MonoString * D.20077;
  const gchar * name;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.20070 = thread->tid;
  mono_profiler_thread_start (D.20070);
  D.20072 = tp->is_io;
  if (D.20072 != 0) goto <D.20073>; else goto <D.20074>;
  <D.20073>:
  iftmp.25 = "IO Threadpool worker";
  goto <D.20075>;
  <D.20074>:
  iftmp.25 = "Threadpool worker";
  <D.20075>:
  name = iftmp.25;
  D.20076 = mono_domain_get ();
  D.20077 = mono_string_new (D.20076, name);
  mono_thread_set_name_internal (thread, D.20077, 0);
}


is_corlib_asyncresult (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.20078;
  gboolean D.20081;
  _Bool D.20082;
  int D.20083;
  int D.19074;
  int iftmp.26;
  int D.19070;
  const char[12] * D.20089;
  unsigned char D.20090;
  int D.20091;
  unsigned char D.20092;
  int D.20093;
  const unsigned char * D.20098;
  unsigned char D.20099;
  int D.20100;
  const unsigned char * D.20101;
  unsigned char D.20102;
  int D.20103;
  const unsigned char * D.20108;
  unsigned char D.20109;
  int D.20110;
  const unsigned char * D.20111;
  unsigned char D.20112;
  int D.20113;
  const unsigned char * D.20118;
  unsigned char D.20119;
  int D.20120;
  const unsigned char * D.20121;
  unsigned char D.20122;
  int D.20123;
  const char * D.20125;
  int D.19083;
  int iftmp.27;
  int D.19079;
  const char[34] * D.20131;
  unsigned char D.20132;
  int D.20133;
  unsigned char D.20134;
  int D.20135;
  const unsigned char * D.20140;
  unsigned char D.20141;
  int D.20142;
  const unsigned char * D.20143;
  unsigned char D.20144;
  int D.20145;
  const unsigned char * D.20150;
  unsigned char D.20151;
  int D.20152;
  const unsigned char * D.20153;
  unsigned char D.20154;
  int D.20155;
  const unsigned char * D.20160;
  unsigned char D.20161;
  int D.20162;
  const unsigned char * D.20163;
  unsigned char D.20164;
  int D.20165;
  const char * D.20167;

  D.20078 = domain->corlib_asyncresult_class;
  if (D.20078 != 0B) goto <D.20079>; else goto <D.20080>;
  <D.20079>:
  D.20078 = domain->corlib_asyncresult_class;
  D.20082 = D.20078 == klass;
  D.20081 = (gboolean) D.20082;
  return D.20081;
  <D.20080>:
  D.20083 = is_corlib_type (domain, klass);
  if (D.20083 != 0) goto <D.20084>; else goto <D.20085>;
  <D.20084>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20089 = "AsyncResult";
      D.20090 = MEM[(const unsigned char *)D.20089];
      D.20091 = (int) D.20090;
      D.20092 = *__s2;
      D.20093 = (int) D.20092;
      __result = D.20091 - D.20093;
      {
        if (__s1_len != 0) goto <D.20094>; else goto <D.20095>;
        <D.20094>:
        if (__result == 0) goto <D.20096>; else goto <D.20097>;
        <D.20096>:
        D.20098 = &MEM[(void *)"AsyncResult" + 1B];
        D.20099 = *D.20098;
        D.20100 = (int) D.20099;
        D.20101 = __s2 + 1;
        D.20102 = *D.20101;
        D.20103 = (int) D.20102;
        __result = D.20100 - D.20103;
        if (__s1_len > 1) goto <D.20104>; else goto <D.20105>;
        <D.20104>:
        if (__result == 0) goto <D.20106>; else goto <D.20107>;
        <D.20106>:
        D.20108 = &MEM[(void *)"AsyncResult" + 2B];
        D.20109 = *D.20108;
        D.20110 = (int) D.20109;
        D.20111 = __s2 + 2;
        D.20112 = *D.20111;
        D.20113 = (int) D.20112;
        __result = D.20110 - D.20113;
        if (__s1_len > 2) goto <D.20114>; else goto <D.20115>;
        <D.20114>:
        if (__result == 0) goto <D.20116>; else goto <D.20117>;
        <D.20116>:
        D.20118 = &MEM[(void *)"AsyncResult" + 3B];
        D.20119 = *D.20118;
        D.20120 = (int) D.20119;
        D.20121 = __s2 + 3;
        D.20122 = *D.20121;
        D.20123 = (int) D.20122;
        __result = D.20120 - D.20123;
        <D.20117>:
        <D.20115>:
        <D.20107>:
        <D.20105>:
        <D.20097>:
        <D.20095>:
      }
      D.19070 = __result;
    }
    iftmp.26 = D.19070;
    goto <D.20124>;
    <D.20088>:
    D.20125 = klass->name;
    iftmp.26 = __builtin_strcmp ("AsyncResult", D.20125);
    <D.20124>:
    D.19074 = iftmp.26;
  }
  if (D.19074 == 0) goto <D.20126>; else goto <D.20127>;
  <D.20126>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.20131 = "System.Runtime.Remoting.Messaging";
      D.20132 = MEM[(const unsigned char *)D.20131];
      D.20133 = (int) D.20132;
      D.20134 = *__s2;
      D.20135 = (int) D.20134;
      __result = D.20133 - D.20135;
      {
        if (__s1_len != 0) goto <D.20136>; else goto <D.20137>;
        <D.20136>:
        if (__result == 0) goto <D.20138>; else goto <D.20139>;
        <D.20138>:
        D.20140 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 1B];
        D.20141 = *D.20140;
        D.20142 = (int) D.20141;
        D.20143 = __s2 + 1;
        D.20144 = *D.20143;
        D.20145 = (int) D.20144;
        __result = D.20142 - D.20145;
        if (__s1_len > 1) goto <D.20146>; else goto <D.20147>;
        <D.20146>:
        if (__result == 0) goto <D.20148>; else goto <D.20149>;
        <D.20148>:
        D.20150 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 2B];
        D.20151 = *D.20150;
        D.20152 = (int) D.20151;
        D.20153 = __s2 + 2;
        D.20154 = *D.20153;
        D.20155 = (int) D.20154;
        __result = D.20152 - D.20155;
        if (__s1_len > 2) goto <D.20156>; else goto <D.20157>;
        <D.20156>:
        if (__result == 0) goto <D.20158>; else goto <D.20159>;
        <D.20158>:
        D.20160 = &MEM[(void *)"System.Runtime.Remoting.Messaging" + 3B];
        D.20161 = *D.20160;
        D.20162 = (int) D.20161;
        D.20163 = __s2 + 3;
        D.20164 = *D.20163;
        D.20165 = (int) D.20164;
        __result = D.20162 - D.20165;
        <D.20159>:
        <D.20157>:
        <D.20149>:
        <D.20147>:
        <D.20139>:
        <D.20137>:
      }
      D.19079 = __result;
    }
    iftmp.27 = D.19079;
    goto <D.20166>;
    <D.20130>:
    D.20167 = klass->name_space;
    iftmp.27 = __builtin_strcmp ("System.Runtime.Remoting.Messaging", D.20167);
    <D.20166>:
    D.19083 = iftmp.27;
  }
  if (D.19083 == 0) goto <D.20168>; else goto <D.20169>;
  <D.20168>:
  domain->corlib_asyncresult_class = klass;
  D.20081 = 1;
  return D.20081;
  <D.20169>:
  <D.20127>:
  <D.20085>:
  D.20081 = 0;
  return D.20081;
}


is_corlib_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.20171;
  struct MonoImage * D.20172;
  struct MonoImage * D.20173;
  _Bool D.20174;

  D.20172 = klass->image;
  D.20173 = mono_defaults.corlib;
  D.20174 = D.20172 == D.20173;
  D.20171 = (gboolean) D.20174;
  return D.20171;
}


is_socketasyncresult (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.20176;
  int iftmp.28;
  struct MonoClass * D.20180;
  int D.20182;
  int D.19118;
  int iftmp.29;
  int D.19117;
  const char[18] * D.20187;
  unsigned char D.20188;
  int D.20189;
  unsigned char D.20190;
  int D.20191;
  const unsigned char * D.20196;
  unsigned char D.20197;
  int D.20198;
  const unsigned char * D.20199;
  unsigned char D.20200;
  int D.20201;
  const unsigned char * D.20206;
  unsigned char D.20207;
  int D.20208;
  const unsigned char * D.20209;
  unsigned char D.20210;
  int D.20211;
  const unsigned char * D.20216;
  unsigned char D.20217;
  int D.20218;
  const unsigned char * D.20219;
  unsigned char D.20220;
  int D.20221;
  const char * D.20223;

  D.20180 = klass->nested_in;
  if (D.20180 != 0B) goto <D.20181>; else goto <D.20178>;
  <D.20181>:
  D.20180 = klass->nested_in;
  D.20182 = is_socket (domain, D.20180);
  if (D.20182 != 0) goto <D.20183>; else goto <D.20178>;
  <D.20183>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20187 = "SocketAsyncResult";
      D.20188 = MEM[(const unsigned char *)D.20187];
      D.20189 = (int) D.20188;
      D.20190 = *__s2;
      D.20191 = (int) D.20190;
      __result = D.20189 - D.20191;
      {
        if (__s2_len != 0) goto <D.20192>; else goto <D.20193>;
        <D.20192>:
        if (__result == 0) goto <D.20194>; else goto <D.20195>;
        <D.20194>:
        D.20196 = &MEM[(void *)"SocketAsyncResult" + 1B];
        D.20197 = *D.20196;
        D.20198 = (int) D.20197;
        D.20199 = __s2 + 1;
        D.20200 = *D.20199;
        D.20201 = (int) D.20200;
        __result = D.20198 - D.20201;
        if (__s2_len > 1) goto <D.20202>; else goto <D.20203>;
        <D.20202>:
        if (__result == 0) goto <D.20204>; else goto <D.20205>;
        <D.20204>:
        D.20206 = &MEM[(void *)"SocketAsyncResult" + 2B];
        D.20207 = *D.20206;
        D.20208 = (int) D.20207;
        D.20209 = __s2 + 2;
        D.20210 = *D.20209;
        D.20211 = (int) D.20210;
        __result = D.20208 - D.20211;
        if (__s2_len > 2) goto <D.20212>; else goto <D.20213>;
        <D.20212>:
        if (__result == 0) goto <D.20214>; else goto <D.20215>;
        <D.20214>:
        D.20216 = &MEM[(void *)"SocketAsyncResult" + 3B];
        D.20217 = *D.20216;
        D.20218 = (int) D.20217;
        D.20219 = __s2 + 3;
        D.20220 = *D.20219;
        D.20221 = (int) D.20220;
        __result = D.20218 - D.20221;
        <D.20215>:
        <D.20213>:
        <D.20205>:
        <D.20203>:
        <D.20195>:
        <D.20193>:
      }
      D.19117 = __result;
    }
    iftmp.29 = -D.19117;
    goto <D.20222>;
    <D.20186>:
    D.20223 = klass->name;
    iftmp.29 = __builtin_strcmp (D.20223, "SocketAsyncResult");
    <D.20222>:
    D.19118 = iftmp.29;
  }
  if (D.19118 == 0) goto <D.20224>; else goto <D.20178>;
  <D.20224>:
  iftmp.28 = 1;
  goto <D.20179>;
  <D.20178>:
  iftmp.28 = 0;
  <D.20179>:
  D.20176 = iftmp.28;
  return D.20176;
}


is_socket (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.20226;
  gboolean D.20229;
  _Bool D.20230;
  int D.20231;
  int D.19096;
  int iftmp.30;
  int D.19092;
  const char[7] * D.20237;
  unsigned char D.20238;
  int D.20239;
  unsigned char D.20240;
  int D.20241;
  const unsigned char * D.20246;
  unsigned char D.20247;
  int D.20248;
  const unsigned char * D.20249;
  unsigned char D.20250;
  int D.20251;
  const unsigned char * D.20256;
  unsigned char D.20257;
  int D.20258;
  const unsigned char * D.20259;
  unsigned char D.20260;
  int D.20261;
  const unsigned char * D.20266;
  unsigned char D.20267;
  int D.20268;
  const unsigned char * D.20269;
  unsigned char D.20270;
  int D.20271;
  const char * D.20273;
  int D.19105;
  int iftmp.31;
  int D.19101;
  const char[19] * D.20279;
  unsigned char D.20280;
  int D.20281;
  unsigned char D.20282;
  int D.20283;
  const unsigned char * D.20288;
  unsigned char D.20289;
  int D.20290;
  const unsigned char * D.20291;
  unsigned char D.20292;
  int D.20293;
  const unsigned char * D.20298;
  unsigned char D.20299;
  int D.20300;
  const unsigned char * D.20301;
  unsigned char D.20302;
  int D.20303;
  const unsigned char * D.20308;
  unsigned char D.20309;
  int D.20310;
  const unsigned char * D.20311;
  unsigned char D.20312;
  int D.20313;
  const char * D.20315;

  D.20226 = domain->socket_class;
  if (D.20226 != 0B) goto <D.20227>; else goto <D.20228>;
  <D.20227>:
  D.20226 = domain->socket_class;
  D.20230 = D.20226 == klass;
  D.20229 = (gboolean) D.20230;
  return D.20229;
  <D.20228>:
  D.20231 = is_socket_type (domain, klass);
  if (D.20231 != 0) goto <D.20232>; else goto <D.20233>;
  <D.20232>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.20237 = "Socket";
      D.20238 = MEM[(const unsigned char *)D.20237];
      D.20239 = (int) D.20238;
      D.20240 = *__s2;
      D.20241 = (int) D.20240;
      __result = D.20239 - D.20241;
      {
        if (__s1_len != 0) goto <D.20242>; else goto <D.20243>;
        <D.20242>:
        if (__result == 0) goto <D.20244>; else goto <D.20245>;
        <D.20244>:
        D.20246 = &MEM[(void *)"Socket" + 1B];
        D.20247 = *D.20246;
        D.20248 = (int) D.20247;
        D.20249 = __s2 + 1;
        D.20250 = *D.20249;
        D.20251 = (int) D.20250;
        __result = D.20248 - D.20251;
        if (__s1_len > 1) goto <D.20252>; else goto <D.20253>;
        <D.20252>:
        if (__result == 0) goto <D.20254>; else goto <D.20255>;
        <D.20254>:
        D.20256 = &MEM[(void *)"Socket" + 2B];
        D.20257 = *D.20256;
        D.20258 = (int) D.20257;
        D.20259 = __s2 + 2;
        D.20260 = *D.20259;
        D.20261 = (int) D.20260;
        __result = D.20258 - D.20261;
        if (__s1_len > 2) goto <D.20262>; else goto <D.20263>;
        <D.20262>:
        if (__result == 0) goto <D.20264>; else goto <D.20265>;
        <D.20264>:
        D.20266 = &MEM[(void *)"Socket" + 3B];
        D.20267 = *D.20266;
        D.20268 = (int) D.20267;
        D.20269 = __s2 + 3;
        D.20270 = *D.20269;
        D.20271 = (int) D.20270;
        __result = D.20268 - D.20271;
        <D.20265>:
        <D.20263>:
        <D.20255>:
        <D.20253>:
        <D.20245>:
        <D.20243>:
      }
      D.19092 = __result;
    }
    iftmp.30 = D.19092;
    goto <D.20272>;
    <D.20236>:
    D.20273 = klass->name;
    iftmp.30 = __builtin_strcmp ("Socket", D.20273);
    <D.20272>:
    D.19096 = iftmp.30;
  }
  if (D.19096 == 0) goto <D.20274>; else goto <D.20275>;
  <D.20274>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.20279 = "System.Net.Sockets";
      D.20280 = MEM[(const unsigned char *)D.20279];
      D.20281 = (int) D.20280;
      D.20282 = *__s2;
      D.20283 = (int) D.20282;
      __result = D.20281 - D.20283;
      {
        if (__s1_len != 0) goto <D.20284>; else goto <D.20285>;
        <D.20284>:
        if (__result == 0) goto <D.20286>; else goto <D.20287>;
        <D.20286>:
        D.20288 = &MEM[(void *)"System.Net.Sockets" + 1B];
        D.20289 = *D.20288;
        D.20290 = (int) D.20289;
        D.20291 = __s2 + 1;
        D.20292 = *D.20291;
        D.20293 = (int) D.20292;
        __result = D.20290 - D.20293;
        if (__s1_len > 1) goto <D.20294>; else goto <D.20295>;
        <D.20294>:
        if (__result == 0) goto <D.20296>; else goto <D.20297>;
        <D.20296>:
        D.20298 = &MEM[(void *)"System.Net.Sockets" + 2B];
        D.20299 = *D.20298;
        D.20300 = (int) D.20299;
        D.20301 = __s2 + 2;
        D.20302 = *D.20301;
        D.20303 = (int) D.20302;
        __result = D.20300 - D.20303;
        if (__s1_len > 2) goto <D.20304>; else goto <D.20305>;
        <D.20304>:
        if (__result == 0) goto <D.20306>; else goto <D.20307>;
        <D.20306>:
        D.20308 = &MEM[(void *)"System.Net.Sockets" + 3B];
        D.20309 = *D.20308;
        D.20310 = (int) D.20309;
        D.20311 = __s2 + 3;
        D.20312 = *D.20311;
        D.20313 = (int) D.20312;
        __result = D.20310 - D.20313;
        <D.20307>:
        <D.20305>:
        <D.20297>:
        <D.20295>:
        <D.20287>:
        <D.20285>:
      }
      D.19101 = __result;
    }
    iftmp.31 = D.19101;
    goto <D.20314>;
    <D.20278>:
    D.20315 = klass->name_space;
    iftmp.31 = __builtin_strcmp ("System.Net.Sockets", D.20315);
    <D.20314>:
    D.19105 = iftmp.31;
  }
  if (D.19105 == 0) goto <D.20316>; else goto <D.20317>;
  <D.20316>:
  domain->socket_class = klass;
  D.20229 = 1;
  return D.20229;
  <D.20317>:
  <D.20275>:
  <D.20233>:
  D.20229 = 0;
  return D.20229;
}


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

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


is_system_type (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoImage * D.20321;
  struct MonoImage * D.20324;
  gboolean D.20325;
  struct MonoImage * D.20326;
  _Bool D.20327;

  D.20321 = domain->system_image;
  if (D.20321 == 0B) goto <D.20322>; else goto <D.20323>;
  <D.20322>:
  D.20324 = mono_image_loaded ("System");
  domain->system_image = D.20324;
  <D.20323>:
  D.20326 = klass->image;
  D.20321 = domain->system_image;
  D.20327 = D.20326 == D.20321;
  D.20325 = (gboolean) D.20327;
  return D.20325;
}


threadpool_jobs_dec (struct MonoObject * obj)
{
  gboolean D.20331;
  struct MonoVTable * D.20332;
  volatile int * D.20333;
  void * D.20336;
  struct MonoDomain * domain;
  int remaining_jobs;

  if (obj == 0B) goto <D.20329>; else goto <D.20330>;
  <D.20329>:
  D.20331 = 0;
  return D.20331;
  <D.20330>:
  D.20332 = obj->vtable;
  domain = D.20332->domain;
  D.20333 = &domain->threadpool_jobs;
  remaining_jobs = InterlockedDecrement (D.20333);
  if (remaining_jobs == 0) goto <D.20334>; else goto <D.20335>;
  <D.20334>:
  D.20336 = domain->cleanup_semaphore;
  if (D.20336 != 0B) goto <D.20337>; else goto <D.20338>;
  <D.20337>:
  D.20336 = domain->cleanup_semaphore;
  ReleaseSemaphore (D.20336, 1, 0B);
  D.20331 = 1;
  return D.20331;
  <D.20338>:
  <D.20335>:
  D.20331 = 0;
  return D.20331;
}


process_idle_times (struct ThreadPool * tp, gint64 t)
{
  int D.20342;
  volatile gint * D.20344;
  int D.20345;
  int D.20347;
  long int D.20350;
  long int D.20351;
  int D.20352;
  int D.20353;
  long int D.20354;
  long int D.20358;
  long int D.20361;
  long int D.20362;
  long int D.20367;
  int D.20368;
  long int D.20369;
  long int D.20370;
  long int D.20374;
  long int D.20375;
  long int D.20376;
  long int D.20381;
  int D.20391;
  int D.20394;
  int D.20399;
  volatile gint * D.20402;
  int D.20403;
  gint64 ticks;
  gint64 avg;
  gboolean compute_avg;
  gint new_threads;
  gint64 per1;

  D.20342 = tp->ignore_times;
  if (D.20342 != 0) goto <D.20340>; else goto <D.20343>;
  <D.20343>:
  if (t <= 0) goto <D.20340>; else goto <D.20341>;
  <D.20340>:
  return;
  <D.20341>:
  compute_avg = 0;
  ticks = mono_100ns_ticks ();
  t = ticks - t;
  <D.19522>:
  D.20344 = &tp->sp_lock;
  D.20345 = InterlockedCompareExchange (D.20344, 1, 0);
  if (D.20345 == 0) goto <D.19521>; else goto <D.20346>;
  <D.20346>:
  goto <D.19522>;
  <D.19521>:
  D.20347 = tp->ignore_times;
  if (D.20347 != 0) goto <D.20348>; else goto <D.20349>;
  <D.20348>:
  tp->sp_lock = 0;
  return;
  <D.20349>:
  D.20350 = tp->time_sum;
  D.20351 = D.20350 + t;
  tp->time_sum = D.20351;
  D.20352 = tp->n_sum;
  D.20353 = D.20352 + 1;
  tp->n_sum = D.20353;
  D.20354 = tp->last_check;
  if (D.20354 == 0) goto <D.20355>; else goto <D.20356>;
  <D.20355>:
  tp->last_check = ticks;
  goto <D.20357>;
  <D.20356>:
  D.20358 = tp->last_check;
  if (D.20358 > 0) goto <D.20359>; else goto <D.20360>;
  <D.20359>:
  D.20361 = tp->last_check;
  D.20362 = ticks - D.20361;
  if (D.20362 > 5000000) goto <D.20363>; else goto <D.20364>;
  <D.20363>:
  tp->ignore_times = 1;
  compute_avg = 1;
  <D.20364>:
  <D.20360>:
  <D.20357>:
  tp->sp_lock = 0;
  if (compute_avg == 0) goto <D.20365>; else goto <D.20366>;
  <D.20365>:
  return;
  <D.20366>:
  tp->last_check = ticks;
  new_threads = 0;
  D.20367 = tp->time_sum;
  D.20368 = tp->n_sum;
  D.20369 = (long int) D.20368;
  avg = D.20367 / D.20369;
  D.20370 = tp->averages[1];
  if (D.20370 == 0) goto <D.20371>; else goto <D.20372>;
  <D.20371>:
  tp->averages[1] = avg;
  goto <D.20373>;
  <D.20372>:
  D.20370 = tp->averages[1];
  D.20374 = avg - D.20370;
  D.20375 = ABS_EXPR <D.20374>;
  D.20376 = D.20375 * 100;
  D.20370 = tp->averages[1];
  per1 = D.20376 / D.20370;
  if (per1 > 5) goto <D.20377>; else goto <D.20378>;
  <D.20377>:
  D.20370 = tp->averages[1];
  if (D.20370 < avg) goto <D.20379>; else goto <D.20380>;
  <D.20379>:
  D.20370 = tp->averages[1];
  D.20381 = tp->averages[0];
  if (D.20370 < D.20381) goto <D.20382>; else goto <D.20383>;
  <D.20382>:
  new_threads = -1;
  goto <D.20384>;
  <D.20383>:
  new_threads = 1;
  <D.20384>:
  goto <D.20385>;
  <D.20380>:
  D.20370 = tp->averages[1];
  if (D.20370 > avg) goto <D.20386>; else goto <D.20387>;
  <D.20386>:
  D.20370 = tp->averages[1];
  D.20381 = tp->averages[0];
  if (D.20370 < D.20381) goto <D.20388>; else goto <D.20389>;
  <D.20388>:
  new_threads = 1;
  <D.20389>:
  <D.20387>:
  <D.20385>:
  goto <D.20390>;
  <D.20378>:
  {
    int min;
    int n;

    min = tp->min_threads;
    n = tp->nthreads;
    D.20391 = n - min;
    if (D.20391 < min) goto <D.20392>; else goto <D.20393>;
    <D.20392>:
    D.20394 = tp->busy_threads;
    if (D.20394 == n) goto <D.20395>; else goto <D.20396>;
    <D.20395>:
    new_threads = 1;
    <D.20396>:
    <D.20393>:
  }
  <D.20390>:
  <D.20373>:
  tp->time_sum = 0;
  tp->n_sum = 0;
  D.20370 = tp->averages[1];
  tp->averages[0] = D.20370;
  tp->averages[1] = avg;
  tp->ignore_times = 0;
  if (new_threads == -1) goto <D.20397>; else goto <D.20398>;
  <D.20397>:
  D.20399 = tp->destroy_thread;
  if (D.20399 == 0) goto <D.20400>; else goto <D.20401>;
  <D.20400>:
  D.20402 = &tp->destroy_thread;
  D.20403 = InterlockedCompareExchange (D.20402, 1, 0);
  if (D.20403 == 0) goto <D.20404>; else goto <D.20405>;
  <D.20404>:
  pulse_on_new_job (tp);
  <D.20405>:
  <D.20401>:
  <D.20398>:
}


mono_async_invoke (struct ThreadPool * tp, struct MonoAsyncResult * ares)
{
  struct MonoAsyncResult * ares.32;
  struct MonoObject * D.20408;
  struct MonoObject * * D.20411;
  struct MonoObject * D.20412;
  struct MonoObject * pa.33;
  struct MonoObject * D.20417;
  struct MonoMethod * D.20418;
  struct MonoMethodMessage * D.20420;
  struct MonoObject * * D.20421;
  struct MonoObject * * D.20422;
  struct MonoObject * exc.34;
  struct MonoArray * * D.20424;
  struct MonoArray * out_args.35;
  struct MonoObject * D.20426;
  struct MonoMethod * D.20434;
  struct MonoDelegate * D.20436;
  struct MonoObject * cb_exc.36;
  struct MonoObject * D.20438;
  struct MonoObject * D.20441;
  struct ASyncCall * ac;
  struct MonoObject * res;
  struct MonoObject * exc;
  struct MonoArray * out_args;
  void * wait_event;
  struct MonoInternalThread * thread;

  try
    {
      ares.32 = ares;
      ac = ares.32->object_data;
      exc = 0B;
      out_args = 0B;
      wait_event = 0B;
      thread = mono_thread_internal_current ();
      ares.32 = ares;
      D.20408 = ares.32->execution_context;
      if (D.20408 != 0B) goto <D.20409>; else goto <D.20410>;
      <D.20409>:
      ares.32 = ares;
      ares.32 = ares;
      D.20411 = &ares.32->original_context;
      D.20412 = mono_thread_get_execution_context ();
      mono_gc_wbarrier_set_field (ares.32, D.20411, D.20412);
      ares.32 = ares;
      D.20408 = ares.32->execution_context;
      mono_thread_set_execution_context (D.20408);
      goto <D.20413>;
      <D.20410>:
      ares.32 = ares;
      ares.32->original_context = 0B;
      <D.20413>:
      if (ac == 0B) goto <D.20414>; else goto <D.20415>;
      <D.20414>:
      {
        void * pa;

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

        try
          {
            cb_exc = 0B;
            D.20420 = ac->msg;
            D.20420->exc = 0B;
            ares.32 = ares;
            D.20417 = ares.32->async_delegate;
            D.20420 = ac->msg;
            res = mono_message_invoke (D.20417, D.20420, &exc, &out_args);
            D.20421 = &ac->res;
            mono_gc_wbarrier_set_field (ac, D.20421, res);
            D.20420 = ac->msg;
            D.20422 = &D.20420->exc;
            exc.34 = exc;
            mono_gc_wbarrier_set_field (ac, D.20422, exc.34);
            D.20424 = &ac->out_args;
            out_args.35 = out_args;
            mono_gc_wbarrier_set_field (ac, D.20424, out_args.35);
            ares.32 = ares;
            mono_monitor_enter (ares.32);
            ares.32 = ares;
            ares.32->completed = 1;
            ares.32 = ares;
            D.20426 = ares.32->handle;
            if (D.20426 != 0B) goto <D.20427>; else goto <D.20428>;
            <D.20427>:
            ares.32 = ares;
            D.20426 = ares.32->handle;
            wait_event = mono_wait_handle_get_handle (D.20426);
            <D.20428>:
            ares.32 = ares;
            mono_monitor_exit (ares.32);
            if (wait_event != 0B) goto <D.20429>; else goto <D.20430>;
            <D.20429>:
            SetEvent (wait_event);
            <D.20430>:
            if (ac != 0B) goto <D.20433>; else goto <D.20431>;
            <D.20433>:
            D.20434 = ac->cb_method;
            if (D.20434 != 0B) goto <D.20435>; else goto <D.20431>;
            <D.20435>:
            {
              void * pa;

              pa = &ares;
              cb_exc = 0B;
              D.20434 = ac->cb_method;
              thread->async_invoke_method = D.20434;
              D.20434 = ac->cb_method;
              D.20436 = ac->cb_target;
              mono_runtime_invoke (D.20434, D.20436, pa, &cb_exc);
              thread->async_invoke_method = 0B;
              cb_exc.36 = cb_exc;
              exc = cb_exc.36;
            }
            goto <D.20432>;
            <D.20431>:
            exc = 0B;
            <D.20432>:
          }
        finally
          {
            cb_exc = {CLOBBER};
          }
      }
      <D.20419>:
      ares.32 = ares;
      D.20438 = ares.32->original_context;
      if (D.20438 != 0B) goto <D.20439>; else goto <D.20440>;
      <D.20439>:
      ares.32 = ares;
      D.20438 = ares.32->original_context;
      mono_thread_set_execution_context (D.20438);
      ares.32 = ares;
      ares.32->original_context = 0B;
      <D.20440>:
      D.20441 = exc;
      return D.20441;
    }
  finally
    {
      exc = {CLOBBER};
      out_args = {CLOBBER};
    }
}


create_simple_asyncresult (struct MonoObject * target, struct MonoObject * state)
{
  struct MonoClass * D.20444;
  struct MonoObject * * D.20445;
  struct MonoObject * * D.20446;
  struct MonoAsyncResult * D.20447;
  struct MonoDomain * domain;
  struct MonoAsyncResult * ares;

  domain = mono_domain_get ();
  D.20444 = mono_defaults.asyncresult_class;
  ares = mono_object_new (domain, D.20444);
  D.20445 = &ares->async_delegate;
  mono_gc_wbarrier_set_field (ares, D.20445, target);
  D.20446 = &ares->async_state;
  mono_gc_wbarrier_set_field (ares, D.20446, state);
  D.20447 = ares;
  return D.20447;
}


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

  thread = mono_thread_internal_current ();
  mono_thread_clr_state (thread, 4294967291);
  D.20449 = mono_thread_test_state (thread, 4);
  if (D.20449 == 0) goto <D.20450>; else goto <D.20451>;
  <D.20450>:
  ves_icall_System_Threading_Thread_SetState (thread, 4);
  <D.20451>:
}


check_for_interruption_critical ()
{
  unsigned int D.20452;
  unsigned int D.20453;
  struct MonoInternalThread * thread;

  mono_gc_set_skip_thread (0);
  thread = mono_thread_internal_current ();
  D.20452 = thread->state;
  D.20453 = D.20452 & 3;
  if (D.20453 != 0) goto <D.20454>; else goto <D.20455>;
  <D.20454>:
  mono_thread_interruption_checkpoint ();
  <D.20455>:
  mono_gc_set_skip_thread (1);
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.20456;
  unsigned int D.20457;

  D.20457 = __sync_sub_and_fetch_4 (val, 1);
  D.20456 = (gint32) D.20457;
  return D.20456;
}


should_i_die (struct ThreadPool * tp)
{
  int D.20459;
  volatile gint * D.20462;
  int D.20463;
  int D.20466;
  int D.20467;
  _Bool D.20468;
  gboolean D.20469;
  gboolean result;

  result = 0;
  D.20459 = tp->destroy_thread;
  if (D.20459 == 1) goto <D.20460>; else goto <D.20461>;
  <D.20460>:
  D.20462 = &tp->destroy_thread;
  D.20463 = InterlockedCompareExchange (D.20462, 0, 1);
  if (D.20463 == 1) goto <D.20464>; else goto <D.20465>;
  <D.20464>:
  D.20466 = tp->nthreads;
  D.20467 = tp->min_threads;
  D.20468 = D.20466 > D.20467;
  result = (gboolean) D.20468;
  <D.20465>:
  <D.20461>:
  D.20469 = result;
  return D.20469;
}


dequeue_or_steal (struct ThreadPool * tp, void * * data, struct MonoWSQ * local_wsq)
{
  int D.20471;
  gboolean D.20474;
  struct MonoCQ * D.20475;
  int D.20476;
  void * D.20479;
  _Bool D.20482;

  D.20471 = mono_runtime_is_shutting_down ();
  if (D.20471 != 0) goto <D.20472>; else goto <D.20473>;
  <D.20472>:
  D.20474 = 0;
  return D.20474;
  <D.20473>:
  D.20475 = tp->queue;
  mono_cq_dequeue (D.20475, data);
  D.20476 = tp->is_io;
  if (D.20476 == 0) goto <D.20477>; else goto <D.20478>;
  <D.20477>:
  D.20479 = *data;
  if (D.20479 == 0B) goto <D.20480>; else goto <D.20481>;
  <D.20480>:
  try_steal (local_wsq, data, 0);
  <D.20481>:
  <D.20478>:
  D.20479 = *data;
  D.20482 = D.20479 != 0B;
  D.20474 = (gboolean) D.20482;
  return D.20474;
}


try_steal (struct MonoWSQ * local_wsq, void * * data, gboolean retry)
{
  struct GPtrArray * wsqs.37;
  void * D.20489;
  int D.20490;
  _Bool D.20495;
  long int D.20496;
  long int D.20497;
  void * * D.20500;
  long unsigned int D.20501;
  long unsigned int D.20502;
  void * * D.20503;
  int D.20507;
  void * D.20508;
  unsigned int ms.38;
  _Bool D.20514;
  long int D.20515;
  long int D.20516;
  unsigned int i.39;
  unsigned int D.20521;
  _Bool D.20524;
  long int D.20525;
  long int D.20526;
  int i;
  int ms;

  wsqs.37 = wsqs;
  if (wsqs.37 == 0B) goto <D.20484>; else goto <D.20487>;
  <D.20487>:
  if (data == 0B) goto <D.20484>; else goto <D.20488>;
  <D.20488>:
  D.20489 = *data;
  if (D.20489 != 0B) goto <D.20484>; else goto <D.20485>;
  <D.20484>:
  return;
  <D.20485>:
  ms = 0;
  <D.19505>:
  D.20490 = mono_runtime_is_shutting_down ();
  if (D.20490 != 0) goto <D.20491>; else goto <D.20492>;
  <D.20491>:
  return;
  <D.20492>:
  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20493>; else goto <D.20494>;
    <D.20493>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20494>:
    D.20495 = ret != 0;
    D.20496 = (long int) D.20495;
    D.20497 = __builtin_expect (D.20496, 0);
    if (D.20497 != 0) goto <D.20498>; else goto <D.20499>;
    <D.20498>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1282, "ret == 0");
    <D.20499>:
  }
  i = 0;
  goto <D.19502>;
  <D.19501>:
  {
    struct MonoWSQ * wsq;

    wsqs.37 = wsqs;
    D.20500 = wsqs.37->pdata;
    D.20501 = (long unsigned int) i;
    D.20502 = D.20501 * 8;
    D.20503 = D.20500 + D.20502;
    wsq = *D.20503;
    if (wsq == local_wsq) goto <D.20504>; else goto <D.20506>;
    <D.20506>:
    D.20507 = mono_wsq_count (wsq);
    if (D.20507 == 0) goto <D.20504>; else goto <D.20505>;
    <D.20504>:
    // predicted unlikely by continue predictor.
    goto <D.19499>;
    <D.20505>:
    wsqs.37 = wsqs;
    D.20500 = wsqs.37->pdata;
    D.20501 = (long unsigned int) i;
    D.20502 = D.20501 * 8;
    D.20503 = D.20500 + D.20502;
    D.20508 = *D.20503;
    ms.38 = (unsigned int) ms;
    mono_wsq_try_steal (D.20508, data, ms.38);
    D.20489 = *data;
    if (D.20489 != 0B) goto <D.20510>; else goto <D.20511>;
    <D.20510>:
    {
      int ret;

      ret = pthread_mutex_unlock (&wsqs_lock.mutex);
      if (ret != 0) goto <D.20512>; else goto <D.20513>;
      <D.20512>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.20513>:
      D.20514 = ret != 0;
      D.20515 = (long int) D.20514;
      D.20516 = __builtin_expect (D.20515, 0);
      if (D.20516 != 0) goto <D.20517>; else goto <D.20518>;
      <D.20517>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1291, "ret == 0");
      <D.20518>:
    }
    return;
    <D.20511>:
  }
  <D.19499>:
  i = i + 1;
  <D.19502>:
  wsqs.37 = wsqs;
  if (wsqs.37 != 0B) goto <D.20519>; else goto <D.19503>;
  <D.20519>:
  i.39 = (unsigned int) i;
  wsqs.37 = wsqs;
  D.20521 = wsqs.37->len;
  if (i.39 < D.20521) goto <D.19501>; else goto <D.19503>;
  <D.19503>:
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.20522>; else goto <D.20523>;
    <D.20522>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20523>:
    D.20524 = ret != 0;
    D.20525 = (long int) D.20524;
    D.20526 = __builtin_expect (D.20525, 0);
    if (D.20526 != 0) goto <D.20527>; else goto <D.20528>;
    <D.20527>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1295, "ret == 0");
    <D.20528>:
  }
  ms = ms + 10;
  if (retry != 0) goto <D.20529>; else goto <D.19506>;
  <D.20529>:
  if (ms <= 10) goto <D.19505>; else goto <D.19506>;
  <D.19506>:
}


remove_wsq (struct MonoWSQ * wsq)
{
  _Bool D.20535;
  long int D.20536;
  long int D.20537;
  struct GPtrArray * wsqs.40;
  _Bool D.20545;
  long int D.20546;
  long int D.20547;
  int D.20550;
  void * data.41;
  int D.20554;
  _Bool D.20557;
  long int D.20558;
  long int D.20559;
  void * data;

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

        ret = pthread_mutex_lock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.20533>; else goto <D.20534>;
        <D.20533>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20534>:
        D.20535 = ret != 0;
        D.20536 = (long int) D.20535;
        D.20537 = __builtin_expect (D.20536, 0);
        if (D.20537 != 0) goto <D.20538>; else goto <D.20539>;
        <D.20538>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1247, "ret == 0");
        <D.20539>:
      }
      wsqs.40 = wsqs;
      if (wsqs.40 == 0B) goto <D.20541>; else goto <D.20542>;
      <D.20541>:
      {
        int ret;

        ret = pthread_mutex_unlock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.20543>; else goto <D.20544>;
        <D.20543>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20544>:
        D.20545 = ret != 0;
        D.20546 = (long int) D.20545;
        D.20547 = __builtin_expect (D.20546, 0);
        if (D.20547 != 0) goto <D.20548>; else goto <D.20549>;
        <D.20548>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1249, "ret == 0");
        <D.20549>:
      }
      return;
      <D.20542>:
      wsqs.40 = wsqs;
      monoeg_g_ptr_array_remove_fast (wsqs.40, wsq);
      data = 0B;
      D.20550 = mono_runtime_is_shutting_down ();
      if (D.20550 != 0) goto <D.20551>; else goto <D.20552>;
      <D.20551>:
      goto <D.19487>;
      <D.19486>:
      data.41 = data;
      threadpool_jobs_dec (data.41);
      data = 0B;
      <D.19487>:
      D.20554 = mono_wsq_local_pop (&data);
      if (D.20554 != 0) goto <D.19486>; else goto <D.19488>;
      <D.19488>:
      <D.20552>:
      mono_wsq_destroy (wsq);
      {
        int ret;

        ret = pthread_mutex_unlock (&wsqs_lock.mutex);
        if (ret != 0) goto <D.20555>; else goto <D.20556>;
        <D.20555>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20556>:
        D.20557 = ret != 0;
        D.20558 = (long int) D.20557;
        D.20559 = __builtin_expect (D.20558, 0);
        if (D.20559 != 0) goto <D.20560>; else goto <D.20561>;
        <D.20560>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1265, "ret == 0");
        <D.20561>:
      }
    }
  finally
    {
      data = {CLOBBER};
    }
}


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

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


atoi (const char * __nptr)
{
  int D.20566;
  long int D.20567;

  D.20567 = strtol (__nptr, 0B, 10);
  D.20566 = (int) D.20567;
  return D.20566;
}


threadpool_init (struct ThreadPool * tp, int min_threads, int max_threads, void (*<Tc09>) (void *) async_invoke)
{
  struct MonoCQ * D.20569;
  union MonoSemType * D.20570;

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


memset (void * __dest, int __ch, size_t __len)
{
  int D.20573;
  int D.20578;
  void * D.20580;
  long unsigned int D.20581;

  D.20573 = __builtin_constant_p (__len);
  if (D.20573 != 0) goto <D.20574>; else goto <D.20575>;
  <D.20574>:
  if (__len == 0) goto <D.20576>; else goto <D.20577>;
  <D.20576>:
  D.20578 = __builtin_constant_p (__ch);
  if (D.20578 == 0) goto <D.20571>; else goto <D.20579>;
  <D.20579>:
  if (__ch != 0) goto <D.20571>; else goto <D.20572>;
  <D.20571>:
  __warn_memset_zero_len ();
  D.20580 = __dest;
  return D.20580;
  <D.20572>:
  <D.20577>:
  <D.20575>:
  D.20581 = __builtin_object_size (__dest, 0);
  D.20580 = __builtin___memset_chk (__dest, __ch, __len, D.20581);
  return D.20580;
}


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

  try
    {
      if (category == 0B) goto <D.20583>; else goto <D.20585>;
      <D.20585>:
      if (counter == 0B) goto <D.20583>; else goto <D.20584>;
      <D.20583>:
      D.20586 = 0B;
      return D.20586;
      <D.20584>:
      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.20586 = mono_perfcounter_get_impl (category_str, counter_str, 0B, machine, &type, &custom);
      return D.20586;
    }
  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.20591;
  int D.20593;
  struct MonoGHashTable * D.20595;
  int D.20596;
  struct MonoAsyncResult * * D.20599;
  void * D.20600;
  long int D.20601;
  union mono_mutex_t * D.20602;
  _Bool D.20605;
  long int D.20606;
  long int D.20607;
  _Bool D.20614;
  long int D.20615;
  long int D.20616;
  long int D.20619;
  const void * D.20620;
  void (*<T3003>) (void *, int, int, int, gboolean) D.20624;
  int D.20625;
  struct MonoMList * list;
  struct SocketIOData * data;
  int fd;
  gboolean is_new;
  int ievt;

  data = &socket_io_data;
  socket_io_init (&socket_io_data);
  D.20591 = mono_runtime_is_shutting_down ();
  if (D.20591 != 0) goto <D.20589>; else goto <D.20592>;
  <D.20592>:
  D.20593 = data->inited;
  if (D.20593 == 3) goto <D.20589>; else goto <D.20594>;
  <D.20594>:
  D.20595 = data->sock_to_state;
  if (D.20595 == 0B) goto <D.20589>; else goto <D.20590>;
  <D.20589>:
  return;
  <D.20590>:
  D.20596 = async_tp.pool_status;
  if (D.20596 == 2) goto <D.20597>; else goto <D.20598>;
  <D.20597>:
  return;
  <D.20598>:
  D.20599 = &state->ares;
  mono_gc_wbarrier_set_field (state, D.20599, ares);
  D.20600 = state->handle;
  D.20601 = (long int) D.20600;
  fd = (int) D.20601;
  {
    int ret;

    D.20602 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20602);
    if (ret != 0) goto <D.20603>; else goto <D.20604>;
    <D.20603>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20604>:
    D.20605 = ret != 0;
    D.20606 = (long int) D.20605;
    D.20607 = __builtin_expect (D.20606, 0);
    if (D.20607 != 0) goto <D.20608>; else goto <D.20609>;
    <D.20608>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 546, "ret == 0");
    <D.20609>:
  }
  D.20595 = data->sock_to_state;
  if (D.20595 == 0B) goto <D.20610>; else goto <D.20611>;
  <D.20610>:
  {
    int ret;

    D.20602 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20602);
    if (ret != 0) goto <D.20612>; else goto <D.20613>;
    <D.20612>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20613>:
    D.20614 = ret != 0;
    D.20615 = (long int) D.20614;
    D.20616 = __builtin_expect (D.20615, 0);
    if (D.20616 != 0) goto <D.20617>; else goto <D.20618>;
    <D.20617>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 548, "ret == 0");
    <D.20618>:
  }
  return;
  <D.20611>:
  D.20595 = data->sock_to_state;
  D.20619 = (long int) fd;
  D.20620 = (const void *) D.20619;
  list = mono_g_hash_table_lookup (D.20595, D.20620);
  if (list == 0B) goto <D.20621>; else goto <D.20622>;
  <D.20621>:
  list = mono_mlist_alloc (state);
  is_new = 1;
  goto <D.20623>;
  <D.20622>:
  list = mono_mlist_append (list, state);
  is_new = 0;
  <D.20623>:
  D.20595 = data->sock_to_state;
  D.20600 = state->handle;
  mono_g_hash_table_replace (D.20595, D.20600, list);
  ievt = get_events_from_list (list);
  D.20624 = data->modify;
  D.20625 = state->operation;
  D.20624 (data, fd, D.20625, ievt, is_new);
}


socket_io_init (struct SocketIOData * data)
{
  int D.20627;
  int * D.20630;
  union mono_mutex_t * D.20635;
  _Bool D.20638;
  long int D.20639;
  long int D.20640;
  struct MonoGHashTable * D.20643;
  const gchar * D.20644;
  struct MonoDomain * D.20647;
  void (*<Tc09>) (void *) D.20648;
  _Bool D.20651;
  long int D.20652;
  long int D.20653;
  int inited;

  D.20627 = data->inited;
  if (D.20627 > 1) goto <D.20628>; else goto <D.20629>;
  <D.20628>:
  return;
  <D.20629>:
  D.20630 = &data->inited;
  inited = InterlockedCompareExchange (D.20630, 1, 0);
  if (inited > 0) goto <D.20631>; else goto <D.20632>;
  <D.20631>:
  <D.19257>:
  D.20627 = data->inited;
  if (D.20627 > 1) goto <D.20633>; else goto <D.20634>;
  <D.20633>:
  return;
  <D.20634>:
  SleepEx (1, 0);
  goto <D.19257>;
  <D.20632>:
  {
    int ret;

    D.20635 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20635);
    if (ret != 0) goto <D.20636>; else goto <D.20637>;
    <D.20636>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20637>:
    D.20638 = ret != 0;
    D.20639 = (long int) D.20638;
    D.20640 = __builtin_expect (D.20639, 0);
    if (D.20640 != 0) goto <D.20641>; else goto <D.20642>;
    <D.20641>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 509, "ret == 0");
    <D.20642>:
  }
  D.20643 = mono_g_hash_table_new_type (monoeg_g_direct_hash, monoeg_g_direct_equal, 2);
  data->sock_to_state = D.20643;
  data->event_system = 1;
  D.20644 = monoeg_g_getenv ("MONO_DISABLE_AIO");
  if (D.20644 != 0B) goto <D.20645>; else goto <D.20646>;
  <D.20645>:
  data->event_system = 0;
  <D.20646>:
  init_event_system (data);
  D.20647 = mono_get_root_domain ();
  D.20648 = data->wait;
  mono_thread_create_internal (D.20647, D.20648, data, 1, 0, 262144);
  {
    int ret;

    D.20635 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20635);
    if (ret != 0) goto <D.20649>; else goto <D.20650>;
    <D.20649>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20650>:
    D.20651 = ret != 0;
    D.20652 = (long int) D.20651;
    D.20653 = __builtin_expect (D.20652, 0);
    if (D.20653 != 0) goto <D.20654>; else goto <D.20655>;
    <D.20654>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 523, "ret == 0");
    <D.20655>:
  }
  data->inited = 2;
  threadpool_start_thread (&async_io_tp);
}


init_event_system (struct SocketIOData * data)
{
  int D.20657;
  void * D.20660;
  void * D.20661;
  const gchar * D.20664;
  void * D.20669;

  D.20657 = data->event_system;
  if (D.20657 == 1) goto <D.20658>; else goto <D.20659>;
  <D.20658>:
  D.20660 = tp_epoll_init (data);
  data->event_data = D.20660;
  D.20661 = data->event_data;
  if (D.20661 == 0B) goto <D.20662>; else goto <D.20663>;
  <D.20662>:
  D.20664 = monoeg_g_getenv ("MONO_DEBUG");
  if (D.20664 != 0B) goto <D.20665>; else goto <D.20666>;
  <D.20665>:
  monoeg_g_log (0B, 32, "Falling back to poll()");
  <D.20666>:
  data->event_system = 0;
  <D.20663>:
  <D.20659>:
  D.20657 = data->event_system;
  if (D.20657 == 0) goto <D.20667>; else goto <D.20668>;
  <D.20667>:
  D.20669 = tp_poll_init (data);
  data->event_data = D.20669;
  <D.20668>:
}


tp_epoll_init (struct SocketIOData * data)
{
  int D.20670;
  int D.20671;
  int * D.20674;
  const gchar * D.20675;
  const gchar * D.20678;
  void * D.20679;
  struct tp_epoll_data * result;

  result = monoeg_malloc0 (4);
  D.20670 = epoll_create1 (524288);
  result->epollfd = D.20670;
  D.20671 = result->epollfd;
  if (D.20671 == -1) goto <D.20672>; else goto <D.20673>;
  <D.20672>:
  {
    int err;

    D.20674 = __errno_location ();
    err = *D.20674;
    D.20675 = monoeg_g_getenv ("MONO_DEBUG");
    if (D.20675 != 0B) goto <D.20676>; else goto <D.20677>;
    <D.20676>:
    D.20678 = monoeg_g_strerror (err);
    monoeg_g_log (0B, 32, "epoll_create1(EPOLL_CLOEXEC) failed: %d %s", err, D.20678);
    <D.20677>:
    D.20679 = 0B;
    return D.20679;
  }
  <D.20673>:
  data->shutdown = tp_epoll_shutdown;
  data->modify = tp_epoll_modify;
  data->wait = tp_epoll_wait;
  D.20679 = result;
  return D.20679;
}


tp_epoll_wait (void * p)
{
  int * D.20684;
  int D.20685;
  const gchar * D.20690;
  union mono_mutex_t * D.20691;
  _Bool D.20694;
  long int D.20695;
  long int D.20696;
  int D.20699;
  _Bool D.20704;
  long int D.20705;
  long int D.20706;
  long unsigned int D.20709;
  long unsigned int D.20710;
  struct MonoGHashTable * D.20711;
  long int D.20712;
  const void * D.20713;
  void * list.42;
  struct MonoMList * list.43;
  unsigned int D.20718;
  unsigned int D.20719;
  int nresults.44;
  unsigned int D.20727;
  int nresults.45;
  void * D.20735;
  unsigned int p.46;
  unsigned int D.20737;
  unsigned int D.20738;
  unsigned int D.20739;
  int D.20740;
  int D.20743;
  const gchar * D.20746;
  _Bool D.20750;
  long int D.20751;
  long int D.20752;
  long unsigned int D.20755;
  long unsigned int D.20756;
  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.19049>:
      mono_gc_set_skip_thread (1);
      <D.19035>:
      if (ready == -1) goto <D.20681>; else goto <D.20682>;
      <D.20681>:
      check_for_interruption_critical ();
      <D.20682>:
      ready = epoll_wait (epollfd, events, 128, -1);
      if (ready == -1) goto <D.20683>; else goto <D.19036>;
      <D.20683>:
      D.20684 = __errno_location ();
      D.20685 = *D.20684;
      if (D.20685 == 4) goto <D.19035>; else goto <D.19036>;
      <D.19036>:
      mono_gc_set_skip_thread (0);
      if (ready == -1) goto <D.20686>; else goto <D.20687>;
      <D.20686>:
      {
        int err;

        D.20684 = __errno_location ();
        err = *D.20684;
        monoeg_g_free (events);
        if (err != 9) goto <D.20688>; else goto <D.20689>;
        <D.20688>:
        D.20690 = monoeg_g_strerror (err);
        monoeg_g_log (0B, 16, "epoll_wait: %d %s", err, D.20690);
        <D.20689>:
        return;
      }
      <D.20687>:
      {
        int ret;

        D.20691 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_lock (D.20691);
        if (ret != 0) goto <D.20692>; else goto <D.20693>;
        <D.20692>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
        <D.20693>:
        D.20694 = ret != 0;
        D.20695 = (long int) D.20694;
        D.20696 = __builtin_expect (D.20695, 0);
        if (D.20696 != 0) goto <D.20697>; else goto <D.20698>;
        <D.20697>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 132, "ret == 0");
        <D.20698>:
      }
      D.20699 = socket_io_data->inited;
      if (D.20699 == 3) goto <D.20700>; else goto <D.20701>;
      <D.20700>:
      monoeg_g_free (events);
      {
        int ret;

        D.20691 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20691);
        if (ret != 0) goto <D.20702>; else goto <D.20703>;
        <D.20702>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20703>:
        D.20704 = ret != 0;
        D.20705 = (long int) D.20704;
        D.20706 = __builtin_expect (D.20705, 0);
        if (D.20706 != 0) goto <D.20707>; else goto <D.20708>;
        <D.20707>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 135, "ret == 0");
        <D.20708>:
      }
      return;
      <D.20701>:
      nresults = 0;
      i = 0;
      goto <D.19046>;
      <D.19045>:
      {
        int fd;
        struct MonoMList * list;
        struct MonoObject * ares;

        try
          {
            D.20709 = (long unsigned int) i;
            D.20710 = D.20709 * 16;
            evt = events + D.20710;
            fd = evt->data.fd;
            D.20711 = socket_io_data->sock_to_state;
            D.20712 = (long int) fd;
            D.20713 = (const void *) D.20712;
            list.42 = mono_g_hash_table_lookup (D.20711, D.20713);
            list = list.42;
            list.43 = list;
            if (list.43 != 0B) goto <D.20716>; else goto <D.20717>;
            <D.20716>:
            D.20718 = evt->events;
            D.20719 = D.20718 & 25;
            if (D.20719 != 0) goto <D.20720>; else goto <D.20721>;
            <D.20720>:
            ares = get_io_event (&list, 1);
            if (ares != 0B) goto <D.20722>; else goto <D.20723>;
            <D.20722>:
            nresults.44 = nresults;
            nresults = nresults.44 + 1;
            async_results[nresults.44] = ares;
            <D.20723>:
            <D.20721>:
            <D.20717>:
            list.43 = list;
            if (list.43 != 0B) goto <D.20725>; else goto <D.20726>;
            <D.20725>:
            D.20718 = evt->events;
            D.20727 = D.20718 & 28;
            if (D.20727 != 0) goto <D.20728>; else goto <D.20729>;
            <D.20728>:
            ares = get_io_event (&list, 4);
            if (ares != 0B) goto <D.20730>; else goto <D.20731>;
            <D.20730>:
            nresults.45 = nresults;
            nresults = nresults.45 + 1;
            async_results[nresults.45] = ares;
            <D.20731>:
            <D.20729>:
            <D.20726>:
            list.43 = list;
            if (list.43 != 0B) goto <D.20733>; else goto <D.20734>;
            <D.20733>:
            {
              int p;

              D.20711 = socket_io_data->sock_to_state;
              D.20712 = (long int) fd;
              D.20735 = (void *) D.20712;
              list.43 = list;
              mono_g_hash_table_replace (D.20711, D.20735, list.43);
              list.43 = list;
              p = get_events_from_list (list.43);
              p.46 = (unsigned int) p;
              D.20737 = p.46 & 4;
              evt->events = D.20737;
              D.20718 = evt->events;
              p.46 = (unsigned int) p;
              D.20738 = p.46 & 1;
              D.20739 = D.20718 | D.20738;
              evt->events = D.20739;
              D.20740 = epoll_ctl (epollfd, 3, fd, evt);
              if (D.20740 == -1) goto <D.20741>; else goto <D.20742>;
              <D.20741>:
              D.20743 = epoll_ctl (epollfd, 1, fd, evt);
              if (D.20743 == -1) goto <D.20744>; else goto <D.20745>;
              <D.20744>:
              {
                int err;

                D.20684 = __errno_location ();
                err = *D.20684;
                D.20746 = monoeg_g_strerror (err);
                monoeg_g_log (0B, 32, "epoll(ADD): %d %s", err, D.20746);
              }
              <D.20745>:
              <D.20742>:
            }
            goto <D.20747>;
            <D.20734>:
            D.20711 = socket_io_data->sock_to_state;
            D.20712 = (long int) fd;
            D.20713 = (const void *) D.20712;
            mono_g_hash_table_remove (D.20711, D.20713);
            epoll_ctl (epollfd, 2, fd, evt);
            <D.20747>:
          }
        finally
          {
            list = {CLOBBER};
          }
      }
      i = i + 1;
      <D.19046>:
      if (i < ready) goto <D.19045>; else goto <D.19047>;
      <D.19047>:
      {
        int ret;

        D.20691 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20691);
        if (ret != 0) goto <D.20748>; else goto <D.20749>;
        <D.20748>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20749>:
        D.20750 = ret != 0;
        D.20751 = (long int) D.20750;
        D.20752 = __builtin_expect (D.20751, 0);
        if (D.20752 != 0) goto <D.20753>; else goto <D.20754>;
        <D.20753>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 178, "ret == 0");
        <D.20754>:
      }
      threadpool_append_jobs (&async_io_tp, &async_results, nresults);
      D.20755 = (long unsigned int) nresults;
      D.20756 = D.20755 * 8;
      mono_gc_bzero_aligned (&async_results, D.20756);
      goto <D.19049>;
    }
  finally
    {
      async_results = {CLOBBER};
    }
}


tp_epoll_modify (void * p, int fd, int operation, int events, gboolean is_new)
{
  int D.20759;
  unsigned int D.20762;
  unsigned int D.20763;
  int D.20764;
  unsigned int D.20767;
  int iftmp.47;
  int D.20772;
  int D.20773;
  int * D.20776;
  int D.20781;
  const gchar * D.20784;
  union mono_mutex_t * D.20785;
  _Bool D.20788;
  long int D.20789;
  long int D.20790;
  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.20759 = events & 1;
      if (D.20759 != 0) goto <D.20760>; else goto <D.20761>;
      <D.20760>:
      D.20762 = evt.events;
      D.20763 = D.20762 | 1;
      evt.events = D.20763;
      <D.20761>:
      D.20764 = events & 4;
      if (D.20764 != 0) goto <D.20765>; else goto <D.20766>;
      <D.20765>:
      D.20762 = evt.events;
      D.20767 = D.20762 | 4;
      evt.events = D.20767;
      <D.20766>:
      if (is_new != 0) goto <D.20769>; else goto <D.20770>;
      <D.20769>:
      iftmp.47 = 1;
      goto <D.20771>;
      <D.20770>:
      iftmp.47 = 3;
      <D.20771>:
      epoll_op = iftmp.47;
      D.20772 = data->epollfd;
      D.20773 = epoll_ctl (D.20772, epoll_op, fd, &evt);
      if (D.20773 == -1) goto <D.20774>; else goto <D.20775>;
      <D.20774>:
      {
        int err;

        D.20776 = __errno_location ();
        err = *D.20776;
        if (epoll_op == 1) goto <D.20777>; else goto <D.20778>;
        <D.20777>:
        if (err == 17) goto <D.20779>; else goto <D.20780>;
        <D.20779>:
        epoll_op = 3;
        D.20772 = data->epollfd;
        D.20781 = epoll_ctl (D.20772, epoll_op, fd, &evt);
        if (D.20781 == -1) goto <D.20782>; else goto <D.20783>;
        <D.20782>:
        D.20784 = monoeg_g_strerror (err);
        monoeg_g_log (0B, 32, "epoll_ctl(MOD): %d %s", err, D.20784);
        <D.20783>:
        <D.20780>:
        <D.20778>:
      }
      <D.20775>:
      {
        int ret;

        D.20785 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.20785);
        if (ret != 0) goto <D.20786>; else goto <D.20787>;
        <D.20786>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.20787>:
        D.20788 = ret != 0;
        D.20789 = (long int) D.20788;
        D.20790 = __builtin_expect (D.20789, 0);
        if (D.20790 != 0) goto <D.20791>; else goto <D.20792>;
        <D.20791>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-epoll.c", 81, "ret == 0");
        <D.20792>:
      }
    }
  finally
    {
      evt = {CLOBBER};
    }
}


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

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


tp_poll_init (struct SocketIOData * data)
{
  int[2] * D.20794;
  int D.20795;
  int * D.20798;
  _Bool D.20799;
  long int D.20800;
  long int D.20801;
  union MonoSemType * D.20804;
  void * D.20805;
  struct tp_poll_data * result;

  result = monoeg_malloc0 (48);
  D.20794 = &result->pipe;
  D.20795 = pipe (D.20794);
  if (D.20795 != 0) goto <D.20796>; else goto <D.20797>;
  <D.20796>:
  {
    int err;

    D.20798 = __errno_location ();
    err = *D.20798;
    perror ("mono");
    D.20799 = err == 0;
    D.20800 = (long int) D.20799;
    D.20801 = __builtin_expect (D.20800, 0);
    if (D.20801 != 0) goto <D.20802>; else goto <D.20803>;
    <D.20802>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 41, "err");
    <D.20803>:
  }
  <D.20797>:
  D.20804 = &result->new_sem;
  sem_init (D.20804, 0, 1);
  data->shutdown = tp_poll_shutdown;
  data->modify = tp_poll_modify;
  data->wait = tp_poll_wait;
  D.20805 = result;
  return D.20805;
}


tp_poll_wait (void * p)
{
  long unsigned int D.20807;
  long unsigned int D.20808;
  int D.20809;
  int D.20810;
  void * iftmp.48;
  long unsigned int D.20814;
  void * D.20815;
  int D.20817;
  long unsigned int D.20818;
  long unsigned int D.20819;
  struct mono_pollfd * D.20820;
  unsigned int maxfd.49;
  int * D.20825;
  int D.20826;
  short int D.20831;
  unsigned short D.20832;
  int D.20833;
  int D.20834;
  int D.20837;
  void * * D.20840;
  int D.20841;
  int D.20844;
  int D.20845;
  long int D.20853;
  short int D.20858;
  struct mono_pollfd * D.20859;
  union MonoSemType * D.20860;
  union mono_mutex_t * D.20865;
  _Bool D.20868;
  long int D.20869;
  long int D.20870;
  int D.20873;
  _Bool D.20880;
  long int D.20881;
  long int D.20882;
  long unsigned int D.20885;
  long unsigned int D.20886;
  short int D.20890;
  struct MonoGHashTable * D.20891;
  long int D.20892;
  const void * D.20893;
  void * list.50;
  struct MonoMList * list.51;
  unsigned short D.20898;
  int D.20899;
  int D.20900;
  int D.20905;
  long unsigned int D.20908;
  int D.20909;
  void * D.20910;
  int D.20913;
  int D.20914;
  long unsigned int D.20915;
  long unsigned int D.20916;
  void * * D.20917;
  int D.20920;
  void * D.20927;
  int D.20930;
  int D.20931;
  long unsigned int D.20932;
  long unsigned int D.20933;
  void * * D.20934;
  void * D.20937;
  int D.20938;
  short int D.20939;
  int D.20941;
  _Bool D.20947;
  long int D.20948;
  long int D.20949;
  struct mono_pollfd * pfds;
  gint maxfd;
  gint allocated;
  gint i;
  struct tp_poll_data * data;
  struct SocketIOData * socket_io_data;
  struct MonoPtrArray async_results;
  gint nresults;

  try
    {
      maxfd = 1;
      socket_io_data = p;
      data = socket_io_data->event_data;
      allocated = 1024;
      D.20807 = (long unsigned int) allocated;
      D.20808 = D.20807 * 8;
      pfds = monoeg_malloc0 (D.20808);
      async_results.size = 0;
      D.20809 = allocated * 2;
      D.20810 = MAX_EXPR <D.20809, 16>;
      async_results.capacity = D.20810;
      D.20809 = allocated * 2;
      if (D.20809 > 16) goto <D.20812>; else goto <D.20813>;
      <D.20812>:
      D.20807 = (long unsigned int) allocated;
      D.20814 = D.20807 * 16;
      D.20809 = allocated * 2;
      D.20815 = mono_gc_make_root_descr_all_refs (D.20809);
      iftmp.48 = mono_gc_alloc_fixed (D.20814, D.20815);
      goto <D.20816>;
      <D.20813>:
      iftmp.48 = __builtin_alloca (128);
      <D.20816>:
      async_results.data = iftmp.48;
      D.20817 = data->pipe[0];
      pfds->fd = D.20817;
      pfds->events = 1;
      pfds->revents = 0;
      i = 1;
      goto <D.18956>;
      <D.18955>:
      D.20818 = (long unsigned int) i;
      D.20819 = D.20818 * 8;
      D.20820 = pfds + D.20819;
      D.20820->fd = -1;
      D.20818 = (long unsigned int) i;
      D.20819 = D.20818 * 8;
      D.20820 = pfds + D.20819;
      D.20820->events = 0;
      D.20818 = (long unsigned int) i;
      D.20819 = D.20818 * 8;
      D.20820 = pfds + D.20819;
      D.20820->revents = 0;
      i = i + 1;
      <D.18956>:
      if (i < allocated) goto <D.18955>; else goto <D.18957>;
      <D.18957>:
      <D.18987>:
      {
        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.18963>:
            if (nsock == -1) goto <D.20821>; else goto <D.20822>;
            <D.20821>:
            check_for_interruption_critical ();
            <D.20822>:
            maxfd.49 = (unsigned int) maxfd;
            nsock = mono_poll (pfds, maxfd.49, -1);
            if (nsock == -1) goto <D.20824>; else goto <D.18964>;
            <D.20824>:
            D.20825 = __errno_location ();
            D.20826 = *D.20825;
            if (D.20826 == 4) goto <D.18963>; else goto <D.18964>;
            <D.18964>:
            mono_gc_set_skip_thread (0);
            if (nsock == -1) goto <D.20827>; else goto <D.20828>;
            <D.20827>:
            D.20825 = __errno_location ();
            D.20826 = *D.20825;
            if (D.20826 == 9) goto <D.20829>; else goto <D.20830>;
            <D.20829>:
            pfds->revents = 0;
            nsock = mark_bad_fds (pfds, maxfd);
            <D.20830>:
            <D.20828>:
            D.20831 = pfds->revents;
            D.20832 = (unsigned short) D.20831;
            D.20833 = (int) D.20832;
            D.20834 = D.20833 & 56;
            if (D.20834 != 0) goto <D.20835>; else goto <D.20836>;
            <D.20835>:
            monoeg_g_free (pfds);
            D.20837 = async_results.capacity;
            if (D.20837 > 16) goto <D.20838>; else goto <D.20839>;
            <D.20838>:
            D.20840 = async_results.data;
            mono_gc_free_fixed (D.20840);
            <D.20839>:
            socket_io_cleanup (socket_io_data);
            return;
            <D.20836>:
            D.20831 = pfds->revents;
            D.20832 = (unsigned short) D.20831;
            D.20833 = (int) D.20832;
            D.20841 = D.20833 & 1;
            if (D.20841 != 0) goto <D.20842>; else goto <D.20843>;
            <D.20842>:
            {
              int nread;
              gboolean found;

              found = 0;
              i = 1;
              goto <D.18969>;
              <D.18968>:
              D.20818 = (long unsigned int) i;
              D.20819 = D.20818 * 8;
              pfd = pfds + D.20819;
              D.20844 = pfd->fd;
              D.20845 = data->newpfd.fd;
              if (D.20844 == D.20845) goto <D.20846>; else goto <D.20847>;
              <D.20846>:
              found = 1;
              goto <D.18967>;
              <D.20847>:
              i = i + 1;
              <D.18969>:
              if (i < allocated) goto <D.18968>; else goto <D.18967>;
              <D.18967>:
              if (found == 0) goto <D.20848>; else goto <D.20849>;
              <D.20848>:
              i = 1;
              goto <D.18972>;
              <D.18971>:
              D.20818 = (long unsigned int) i;
              D.20819 = D.20818 * 8;
              pfd = pfds + D.20819;
              D.20844 = pfd->fd;
              if (D.20844 == -1) goto <D.18970>; else goto <D.20850>;
              <D.20850>:
              i = i + 1;
              <D.18972>:
              if (i < allocated) goto <D.18971>; else goto <D.18970>;
              <D.18970>:
              <D.20849>:
              if (i == allocated) goto <D.20851>; else goto <D.20852>;
              <D.20851>:
              {
                struct mono_pollfd * oldfd;

                oldfd = pfds;
                i = allocated;
                allocated = allocated * 2;
                D.20807 = (long unsigned int) allocated;
                D.20808 = D.20807 * 8;
                pfds = monoeg_realloc (oldfd, D.20808);
                monoeg_g_free (oldfd);
                goto <D.18975>;
                <D.18974>:
                D.20818 = (long unsigned int) i;
                D.20819 = D.20818 * 8;
                D.20820 = pfds + D.20819;
                D.20820->fd = -1;
                D.20818 = (long unsigned int) i;
                D.20819 = D.20818 * 8;
                D.20820 = pfds + D.20819;
                D.20820->events = 0;
                D.20818 = (long unsigned int) i;
                D.20819 = D.20818 * 8;
                D.20820 = pfds + D.20819;
                D.20820->revents = 0;
                i = i + 1;
                <D.18975>:
                if (i < allocated) goto <D.18974>; else goto <D.18976>;
                <D.18976>:
              }
              <D.20852>:
              D.20817 = data->pipe[0];
              D.20853 = read (D.20817, &one, 1);
              nread = (int) D.20853;
              if (nread <= 0) goto <D.20854>; else goto <D.20855>;
              <D.20854>:
              monoeg_g_free (pfds);
              D.20837 = async_results.capacity;
              if (D.20837 > 16) goto <D.20856>; else goto <D.20857>;
              <D.20856>:
              D.20840 = async_results.data;
              mono_gc_free_fixed (D.20840);
              <D.20857>:
              return;
              <D.20855>:
              D.20818 = (long unsigned int) i;
              D.20819 = D.20818 * 8;
              D.20820 = pfds + D.20819;
              D.20845 = data->newpfd.fd;
              D.20820->fd = D.20845;
              D.20818 = (long unsigned int) i;
              D.20819 = D.20818 * 8;
              D.20820 = pfds + D.20819;
              D.20858 = data->newpfd.events;
              D.20820->events = D.20858;
              D.20818 = (long unsigned int) i;
              D.20819 = D.20818 * 8;
              D.20820 = pfds + D.20819;
              D.20820->revents = 0;
              D.20859 = &data->newpfd;
              memset (D.20859, 0, 8);
              D.20860 = &data->new_sem;
              mono_sem_post (D.20860);
              if (i >= maxfd) goto <D.20861>; else goto <D.20862>;
              <D.20861>:
              maxfd = i + 1;
              <D.20862>:
              nsock = nsock + -1;
            }
            <D.20843>:
            if (nsock == 0) goto <D.20863>; else goto <D.20864>;
            <D.20863>:
            // predicted unlikely by continue predictor.
            goto <D.18977>;
            <D.20864>:
            {
              int ret;

              D.20865 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_lock (D.20865);
              if (ret != 0) goto <D.20866>; else goto <D.20867>;
              <D.20866>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
              <D.20867>:
              D.20868 = ret != 0;
              D.20869 = (long int) D.20868;
              D.20870 = __builtin_expect (D.20869, 0);
              if (D.20870 != 0) goto <D.20871>; else goto <D.20872>;
              <D.20871>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 273, "ret == 0");
              <D.20872>:
            }
            D.20873 = socket_io_data->inited;
            if (D.20873 == 3) goto <D.20874>; else goto <D.20875>;
            <D.20874>:
            monoeg_g_free (pfds);
            D.20837 = async_results.capacity;
            if (D.20837 > 16) goto <D.20876>; else goto <D.20877>;
            <D.20876>:
            D.20840 = async_results.data;
            mono_gc_free_fixed (D.20840);
            <D.20877>:
            {
              int ret;

              D.20865 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_unlock (D.20865);
              if (ret != 0) goto <D.20878>; else goto <D.20879>;
              <D.20878>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
              <D.20879>:
              D.20880 = ret != 0;
              D.20881 = (long int) D.20880;
              D.20882 = __builtin_expect (D.20881, 0);
              if (D.20882 != 0) goto <D.20883>; else goto <D.20884>;
              <D.20883>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 277, "ret == 0");
              <D.20884>:
            }
            return;
            <D.20875>:
            nresults = 0;
            async_results.size = 0;
            D.20840 = async_results.data;
            D.20837 = async_results.capacity;
            D.20885 = (long unsigned int) D.20837;
            D.20886 = D.20885 * 8;
            mono_gc_bzero_aligned (D.20840, D.20886);
            i = 1;
            goto <D.18984>;
            <D.18983>:
            D.20818 = (long unsigned int) i;
            D.20819 = D.20818 * 8;
            pfd = pfds + D.20819;
            D.20844 = pfd->fd;
            if (D.20844 == -1) goto <D.20887>; else goto <D.20889>;
            <D.20889>:
            D.20890 = pfd->revents;
            if (D.20890 == 0) goto <D.20887>; else goto <D.20888>;
            <D.20887>:
            // predicted unlikely by continue predictor.
            goto <D.18980>;
            <D.20888>:
            nsock = nsock + -1;
            D.20891 = socket_io_data->sock_to_state;
            D.20844 = pfd->fd;
            D.20892 = (long int) D.20844;
            D.20893 = (const void *) D.20892;
            list.50 = mono_g_hash_table_lookup (D.20891, D.20893);
            list = list.50;
            list.51 = list;
            if (list.51 != 0B) goto <D.20896>; else goto <D.20897>;
            <D.20896>:
            D.20890 = pfd->revents;
            D.20898 = (unsigned short) D.20890;
            D.20899 = (int) D.20898;
            D.20900 = D.20899 & 57;
            if (D.20900 != 0) goto <D.20901>; else goto <D.20902>;
            <D.20901>:
            ares = get_io_event (&list, 1);
            if (ares != 0B) goto <D.20903>; else goto <D.20904>;
            <D.20903>:
            D.20905 = async_results.size;
            D.20837 = async_results.capacity;
            if (D.20905 >= D.20837) goto <D.20906>; else goto <D.20907>;
            <D.20906>:
            {
              void * __tmp;

              D.20837 = async_results.capacity;
              D.20885 = (long unsigned int) D.20837;
              D.20908 = D.20885 * 16;
              D.20837 = async_results.capacity;
              D.20909 = D.20837 * 2;
              D.20910 = mono_gc_make_root_descr_all_refs (D.20909);
              __tmp = mono_gc_alloc_fixed (D.20908, D.20910);
              D.20840 = async_results.data;
              D.20837 = async_results.capacity;
              D.20885 = (long unsigned int) D.20837;
              D.20886 = D.20885 * 8;
              mono_gc_memmove_aligned (__tmp, D.20840, D.20886);
              D.20837 = async_results.capacity;
              if (D.20837 > 16) goto <D.20911>; else goto <D.20912>;
              <D.20911>:
              D.20840 = async_results.data;
              mono_gc_free_fixed (D.20840);
              <D.20912>:
              async_results.data = __tmp;
              D.20837 = async_results.capacity;
              D.20909 = D.20837 * 2;
              async_results.capacity = D.20909;
            }
            <D.20907>:
            D.20840 = async_results.data;
            D.20905 = async_results.size;
            D.20913 = D.20905;
            D.20914 = D.20913 + 1;
            async_results.size = D.20914;
            D.20915 = (long unsigned int) D.20913;
            D.20916 = D.20915 * 8;
            D.20917 = D.20840 + D.20916;
            *D.20917 = ares;
            nresults = nresults + 1;
            <D.20904>:
            <D.20902>:
            <D.20897>:
            list.51 = list;
            if (list.51 != 0B) goto <D.20918>; else goto <D.20919>;
            <D.20918>:
            D.20890 = pfd->revents;
            D.20898 = (unsigned short) D.20890;
            D.20899 = (int) D.20898;
            D.20920 = D.20899 & 60;
            if (D.20920 != 0) goto <D.20921>; else goto <D.20922>;
            <D.20921>:
            ares = get_io_event (&list, 4);
            if (ares != 0B) goto <D.20923>; else goto <D.20924>;
            <D.20923>:
            D.20905 = async_results.size;
            D.20837 = async_results.capacity;
            if (D.20905 >= D.20837) goto <D.20925>; else goto <D.20926>;
            <D.20925>:
            {
              void * __tmp;

              D.20837 = async_results.capacity;
              D.20885 = (long unsigned int) D.20837;
              D.20908 = D.20885 * 16;
              D.20837 = async_results.capacity;
              D.20909 = D.20837 * 2;
              D.20927 = mono_gc_make_root_descr_all_refs (D.20909);
              __tmp = mono_gc_alloc_fixed (D.20908, D.20927);
              D.20840 = async_results.data;
              D.20837 = async_results.capacity;
              D.20885 = (long unsigned int) D.20837;
              D.20886 = D.20885 * 8;
              mono_gc_memmove_aligned (__tmp, D.20840, D.20886);
              D.20837 = async_results.capacity;
              if (D.20837 > 16) goto <D.20928>; else goto <D.20929>;
              <D.20928>:
              D.20840 = async_results.data;
              mono_gc_free_fixed (D.20840);
              <D.20929>:
              async_results.data = __tmp;
              D.20837 = async_results.capacity;
              D.20909 = D.20837 * 2;
              async_results.capacity = D.20909;
            }
            <D.20926>:
            D.20840 = async_results.data;
            D.20905 = async_results.size;
            D.20930 = D.20905;
            D.20931 = D.20930 + 1;
            async_results.size = D.20931;
            D.20932 = (long unsigned int) D.20930;
            D.20933 = D.20932 * 8;
            D.20934 = D.20840 + D.20933;
            *D.20934 = ares;
            nresults = nresults + 1;
            <D.20924>:
            <D.20922>:
            <D.20919>:
            list.51 = list;
            if (list.51 != 0B) goto <D.20935>; else goto <D.20936>;
            <D.20935>:
            D.20891 = socket_io_data->sock_to_state;
            D.20844 = pfd->fd;
            D.20892 = (long int) D.20844;
            D.20937 = (void *) D.20892;
            list.51 = list;
            mono_g_hash_table_replace (D.20891, D.20937, list.51);
            list.51 = list;
            D.20938 = get_events_from_list (list.51);
            D.20939 = (short int) D.20938;
            pfd->events = D.20939;
            goto <D.20940>;
            <D.20936>:
            D.20891 = socket_io_data->sock_to_state;
            D.20844 = pfd->fd;
            D.20892 = (long int) D.20844;
            D.20893 = (const void *) D.20892;
            mono_g_hash_table_remove (D.20891, D.20893);
            pfd->fd = -1;
            D.20941 = maxfd + -1;
            if (D.20941 == i) goto <D.20942>; else goto <D.20943>;
            <D.20942>:
            maxfd = maxfd + -1;
            <D.20943>:
            <D.20940>:
            <D.18980>:
            i = i + 1;
            <D.18984>:
            if (i < maxfd) goto <D.20944>; else goto <D.18985>;
            <D.20944>:
            if (nsock > 0) goto <D.18983>; else goto <D.18985>;
            <D.18985>:
            {
              int ret;

              D.20865 = &socket_io_data->io_lock.mutex;
              ret = pthread_mutex_unlock (D.20865);
              if (ret != 0) goto <D.20945>; else goto <D.20946>;
              <D.20945>:
              monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
              <D.20946>:
              D.20947 = ret != 0;
              D.20948 = (long int) D.20947;
              D.20949 = __builtin_expect (D.20948, 0);
              if (D.20949 != 0) goto <D.20950>; else goto <D.20951>;
              <D.20950>:
              monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 317, "ret == 0");
              <D.20951>:
            }
            D.20840 = async_results.data;
            threadpool_append_jobs (&async_io_tp, D.20840, nresults);
            async_results.size = 0;
            D.20840 = async_results.data;
            D.20837 = async_results.capacity;
            D.20885 = (long unsigned int) D.20837;
            D.20886 = D.20885 * 8;
            mono_gc_bzero_aligned (D.20840, D.20886);
          }
        finally
          {
            one = {CLOBBER};
            list = {CLOBBER};
          }
      }
      <D.18977>:
      goto <D.18987>;
    }
  finally
    {
      async_results = {CLOBBER};
    }
}


mark_bad_fds (struct mono_pollfd * pfds, int nfds)
{
  long unsigned int D.20957;
  long unsigned int D.20958;
  int D.20959;
  int * D.20965;
  int D.20966;
  short int D.20968;
  short int D.20969;
  int D.20972;
  int i;
  int ret;
  struct mono_pollfd * pfd;
  int count;

  count = 0;
  i = 0;
  goto <D.18942>;
  <D.18941>:
  D.20957 = (long unsigned int) i;
  D.20958 = D.20957 * 8;
  pfd = pfds + D.20958;
  D.20959 = pfd->fd;
  if (D.20959 == -1) goto <D.20960>; else goto <D.20961>;
  <D.20960>:
  // predicted unlikely by continue predictor.
  goto <D.18940>;
  <D.20961>:
  ret = mono_poll (pfd, 1, 0);
  if (ret == -1) goto <D.20964>; else goto <D.20962>;
  <D.20964>:
  D.20965 = __errno_location ();
  D.20966 = *D.20965;
  if (D.20966 == 9) goto <D.20967>; else goto <D.20962>;
  <D.20967>:
  D.20968 = pfd->revents;
  D.20969 = D.20968 | 32;
  pfd->revents = D.20969;
  count = count + 1;
  goto <D.20963>;
  <D.20962>:
  if (ret == 1) goto <D.20970>; else goto <D.20971>;
  <D.20970>:
  count = count + 1;
  <D.20971>:
  <D.20963>:
  <D.18940>:
  i = i + 1;
  <D.18942>:
  if (i < nfds) goto <D.18941>; else goto <D.18943>;
  <D.18943>:
  D.20972 = count;
  return D.20972;
}


socket_io_cleanup (struct SocketIOData * data)
{
  union mono_mutex_t * D.20974;
  _Bool D.20977;
  long int D.20978;
  long int D.20979;
  int D.20982;
  _Bool D.20987;
  long int D.20988;
  long int D.20989;
  void (*<Tc09>) (void *) D.20992;
  void * D.20993;
  _Bool D.20996;
  long int D.20997;
  long int D.20998;

  {
    int ret;

    D.20974 = &data->io_lock.mutex;
    ret = pthread_mutex_lock (D.20974);
    if (ret != 0) goto <D.20975>; else goto <D.20976>;
    <D.20975>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20976>:
    D.20977 = ret != 0;
    D.20978 = (long int) D.20977;
    D.20979 = __builtin_expect (D.20978, 0);
    if (D.20979 != 0) goto <D.20980>; else goto <D.20981>;
    <D.20980>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 317, "ret == 0");
    <D.20981>:
  }
  D.20982 = data->inited;
  if (D.20982 != 2) goto <D.20983>; else goto <D.20984>;
  <D.20983>:
  {
    int ret;

    D.20974 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20974);
    if (ret != 0) goto <D.20985>; else goto <D.20986>;
    <D.20985>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20986>:
    D.20987 = ret != 0;
    D.20988 = (long int) D.20987;
    D.20989 = __builtin_expect (D.20988, 0);
    if (D.20989 != 0) goto <D.20990>; else goto <D.20991>;
    <D.20990>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 319, "ret == 0");
    <D.20991>:
  }
  return;
  <D.20984>:
  data->inited = 3;
  D.20992 = data->shutdown;
  D.20993 = data->event_data;
  D.20992 (D.20993);
  {
    int ret;

    D.20974 = &data->io_lock.mutex;
    ret = pthread_mutex_unlock (D.20974);
    if (ret != 0) goto <D.20994>; else goto <D.20995>;
    <D.20994>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20995>:
    D.20996 = ret != 0;
    D.20997 = (long int) D.20996;
    D.20998 = __builtin_expect (D.20997, 0);
    if (D.20998 != 0) goto <D.20999>; else goto <D.21000>;
    <D.20999>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 324, "ret == 0");
    <D.21000>:
  }
}


read (int __fd, void * __buf, size_t __nbytes)
{
  long unsigned int D.21002;
  int D.21005;
  ssize_t D.21008;
  long unsigned int D.21009;
  long unsigned int D.21010;
  long unsigned int D.21013;

  D.21002 = __builtin_object_size (__buf, 0);
  if (D.21002 != 18446744073709551615) goto <D.21003>; else goto <D.21004>;
  <D.21003>:
  D.21005 = __builtin_constant_p (__nbytes);
  if (D.21005 == 0) goto <D.21006>; else goto <D.21007>;
  <D.21006>:
  D.21009 = __builtin_object_size (__buf, 0);
  D.21008 = __read_chk (__fd, __buf, __nbytes, D.21009);
  return D.21008;
  <D.21007>:
  D.21010 = __builtin_object_size (__buf, 0);
  if (D.21010 < __nbytes) goto <D.21011>; else goto <D.21012>;
  <D.21011>:
  D.21013 = __builtin_object_size (__buf, 0);
  D.21008 = __read_chk_warn (__fd, __buf, __nbytes, D.21013);
  return D.21008;
  <D.21012>:
  <D.21004>:
  D.21008 = __read_alias (__fd, __buf, __nbytes);
  return D.21008;
}


tp_poll_modify (void * p, int fd, int operation, int events, gboolean is_new)
{
  union mono_mutex_t * D.21015;
  _Bool D.21018;
  long int D.21019;
  long int D.21020;
  union MonoSemType * D.21023;
  short int D.21024;
  char D.21025;
  int D.21026;
  long int D.21027;
  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.21015 = &socket_io_data->io_lock.mutex;
        ret = pthread_mutex_unlock (D.21015);
        if (ret != 0) goto <D.21016>; else goto <D.21017>;
        <D.21016>:
        monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
        <D.21017>:
        D.21018 = ret != 0;
        D.21019 = (long int) D.21018;
        D.21020 = __builtin_expect (D.21019, 0);
        if (D.21020 != 0) goto <D.21021>; else goto <D.21022>;
        <D.21021>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/metadata/tpool-poll.c", 87, "ret == 0");
        <D.21022>:
      }
      D.21023 = &data->new_sem;
      mono_sem_wait (D.21023, 0);
      data->newpfd.fd = fd;
      D.21024 = (short int) events;
      data->newpfd.events = D.21024;
      data->newpfd.revents = 0;
      D.21025 = (char) operation;
      msg[0] = D.21025;
      D.21026 = data->pipe[1];
      D.21027 = write (D.21026, &msg, 1);
      unused = (int) D.21027;
    }
  finally
    {
      msg = {CLOBBER};
    }
}


tp_poll_shutdown (void * event_data)
{
  int D.21028;
  int D.21031;
  union MonoSemType * D.21034;
  struct tp_poll_data * data;

  data = event_data;
  D.21028 = data->pipe[0];
  if (D.21028 >= 0) goto <D.21029>; else goto <D.21030>;
  <D.21029>:
  D.21028 = data->pipe[0];
  close (D.21028);
  <D.21030>:
  D.21031 = data->pipe[1];
  if (D.21031 >= 0) goto <D.21032>; else goto <D.21033>;
  <D.21032>:
  D.21031 = data->pipe[1];
  close (D.21031);
  <D.21033>:
  data->pipe[0] = -1;
  data->pipe[1] = -1;
  D.21034 = &data->new_sem;
  sem_destroy (D.21034);
}


get_events_from_list (struct MonoMList * list)
{
  int D.21035;
  int D.21037;
  struct MonoSocketAsyncResult * state;
  int events;

  events = 0;
  goto <D.19218>;
  <D.19217>:
  D.21035 = get_event_from_state (state);
  events = D.21035 | events;
  list = mono_mlist_next (list);
  <D.19218>:
  if (list != 0B) goto <D.21036>; else goto <D.19219>;
  <D.21036>:
  state = mono_mlist_get_data (list);
  if (state != 0B) goto <D.19217>; else goto <D.19219>;
  <D.19219>:
  D.21037 = events;
  return D.21037;
}


mono_thread_pool_add (struct MonoObject * target, struct MonoMethodMessage * msg, struct MonoDelegate * async_callback, struct MonoObject * state)
{
  struct MonoClass * async_call_klass.52;
  struct MonoMethodMessage * * D.21040;
  struct MonoObject * * D.21041;
  struct MonoVTable * D.21044;
  struct MonoClass * D.21045;
  struct MonoMethod * D.21046;
  struct MonoDelegate * * D.21047;
  struct MonoObject * D.21048;
  struct MonoObject * * D.21049;
  int D.21050;
  struct MonoAsyncResult * D.21053;
  struct MonoDomain * domain;
  struct MonoAsyncResult * ares;
  struct ASyncCall * ac;

  domain = mono_domain_get ();
  async_call_klass.52 = async_call_klass;
  ac = mono_object_new (domain, async_call_klass.52);
  D.21040 = &ac->msg;
  mono_gc_wbarrier_set_field (ac, D.21040, msg);
  D.21041 = &ac->state;
  mono_gc_wbarrier_set_field (ac, D.21041, state);
  if (async_callback != 0B) goto <D.21042>; else goto <D.21043>;
  <D.21042>:
  D.21044 = MEM[(struct MonoObject *)async_callback].vtable;
  D.21045 = D.21044->klass;
  D.21046 = mono_get_delegate_invoke (D.21045);
  ac->cb_method = D.21046;
  D.21047 = &ac->cb_target;
  mono_gc_wbarrier_set_field (ac, D.21047, async_callback);
  <D.21043>:
  D.21048 = ac->state;
  ares = mono_async_result_new (domain, 0B, D.21048, 0B, ac);
  D.21049 = &ares->async_delegate;
  mono_gc_wbarrier_set_field (ares, D.21049, target);
  D.21050 = socket_io_filter (target, state);
  if (D.21050 != 0) goto <D.21051>; else goto <D.21052>;
  <D.21051>:
  socket_io_add (ares, state);
  D.21053 = ares;
  return D.21053;
  <D.21052>:
  threadpool_append_job (&async_tp, ares);
  D.21053 = ares;
  return D.21053;
}


socket_io_filter (struct MonoObject * target, struct MonoObject * state)
{
  gboolean D.21058;
  struct MonoVTable * D.21059;
  struct MonoClass * socket_async_call_klass.53;
  int D.21063;
  struct MonoClass * process_async_call_klass.54;
  int D.21069;
  unsigned int op.55;
  gint op;
  struct MonoSocketAsyncResult * sock_res;
  struct MonoClass * klass;
  struct MonoDomain * domain;

  if (target == 0B) goto <D.21055>; else goto <D.21057>;
  <D.21057>:
  if (state == 0B) goto <D.21055>; else goto <D.21056>;
  <D.21055>:
  D.21058 = 0;
  return D.21058;
  <D.21056>:
  D.21059 = target->vtable;
  domain = D.21059->domain;
  D.21059 = target->vtable;
  klass = D.21059->klass;
  socket_async_call_klass.53 = socket_async_call_klass;
  if (socket_async_call_klass.53 == 0B) goto <D.21061>; else goto <D.21062>;
  <D.21061>:
  D.21063 = is_socketasynccall (domain, klass);
  if (D.21063 != 0) goto <D.21064>; else goto <D.21065>;
  <D.21064>:
  socket_async_call_klass = klass;
  <D.21065>:
  <D.21062>:
  process_async_call_klass.54 = process_async_call_klass;
  if (process_async_call_klass.54 == 0B) goto <D.21067>; else goto <D.21068>;
  <D.21067>:
  D.21069 = is_sdp_asyncreadhandler (domain, klass);
  if (D.21069 != 0) goto <D.21070>; else goto <D.21071>;
  <D.21070>:
  process_async_call_klass = klass;
  <D.21071>:
  <D.21068>:
  socket_async_call_klass.53 = socket_async_call_klass;
  if (klass != socket_async_call_klass.53) goto <D.21072>; else goto <D.21073>;
  <D.21072>:
  process_async_call_klass.54 = process_async_call_klass;
  if (klass != process_async_call_klass.54) goto <D.21074>; else goto <D.21075>;
  <D.21074>:
  D.21058 = 0;
  return D.21058;
  <D.21075>:
  <D.21073>:
  sock_res = state;
  op = sock_res->operation;
  op.55 = (unsigned int) op;
  if (op.55 > 13) goto <D.21077>; else goto <D.21078>;
  <D.21077>:
  D.21058 = 0;
  return D.21058;
  <D.21078>:
  D.21058 = 1;
  return D.21058;
}


is_socketasynccall (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.21080;
  int iftmp.56;
  struct MonoClass * D.21084;
  int D.21086;
  int D.19131;
  int iftmp.57;
  int D.19130;
  const char[16] * D.21091;
  unsigned char D.21092;
  int D.21093;
  unsigned char D.21094;
  int D.21095;
  const unsigned char * D.21100;
  unsigned char D.21101;
  int D.21102;
  const unsigned char * D.21103;
  unsigned char D.21104;
  int D.21105;
  const unsigned char * D.21110;
  unsigned char D.21111;
  int D.21112;
  const unsigned char * D.21113;
  unsigned char D.21114;
  int D.21115;
  const unsigned char * D.21120;
  unsigned char D.21121;
  int D.21122;
  const unsigned char * D.21123;
  unsigned char D.21124;
  int D.21125;
  const char * D.21127;

  D.21084 = klass->nested_in;
  if (D.21084 != 0B) goto <D.21085>; else goto <D.21082>;
  <D.21085>:
  D.21084 = klass->nested_in;
  D.21086 = is_socket (domain, D.21084);
  if (D.21086 != 0) goto <D.21087>; else goto <D.21082>;
  <D.21087>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.21091 = "SocketAsyncCall";
      D.21092 = MEM[(const unsigned char *)D.21091];
      D.21093 = (int) D.21092;
      D.21094 = *__s2;
      D.21095 = (int) D.21094;
      __result = D.21093 - D.21095;
      {
        if (__s2_len != 0) goto <D.21096>; else goto <D.21097>;
        <D.21096>:
        if (__result == 0) goto <D.21098>; else goto <D.21099>;
        <D.21098>:
        D.21100 = &MEM[(void *)"SocketAsyncCall" + 1B];
        D.21101 = *D.21100;
        D.21102 = (int) D.21101;
        D.21103 = __s2 + 1;
        D.21104 = *D.21103;
        D.21105 = (int) D.21104;
        __result = D.21102 - D.21105;
        if (__s2_len > 1) goto <D.21106>; else goto <D.21107>;
        <D.21106>:
        if (__result == 0) goto <D.21108>; else goto <D.21109>;
        <D.21108>:
        D.21110 = &MEM[(void *)"SocketAsyncCall" + 2B];
        D.21111 = *D.21110;
        D.21112 = (int) D.21111;
        D.21113 = __s2 + 2;
        D.21114 = *D.21113;
        D.21115 = (int) D.21114;
        __result = D.21112 - D.21115;
        if (__s2_len > 2) goto <D.21116>; else goto <D.21117>;
        <D.21116>:
        if (__result == 0) goto <D.21118>; else goto <D.21119>;
        <D.21118>:
        D.21120 = &MEM[(void *)"SocketAsyncCall" + 3B];
        D.21121 = *D.21120;
        D.21122 = (int) D.21121;
        D.21123 = __s2 + 3;
        D.21124 = *D.21123;
        D.21125 = (int) D.21124;
        __result = D.21122 - D.21125;
        <D.21119>:
        <D.21117>:
        <D.21109>:
        <D.21107>:
        <D.21099>:
        <D.21097>:
      }
      D.19130 = __result;
    }
    iftmp.57 = -D.19130;
    goto <D.21126>;
    <D.21090>:
    D.21127 = klass->name;
    iftmp.57 = __builtin_strcmp (D.21127, "SocketAsyncCall");
    <D.21126>:
    D.19131 = iftmp.57;
  }
  if (D.19131 == 0) goto <D.21128>; else goto <D.21082>;
  <D.21128>:
  iftmp.56 = 1;
  goto <D.21083>;
  <D.21082>:
  iftmp.56 = 0;
  <D.21083>:
  D.21080 = iftmp.56;
  return D.21080;
}


is_sdp_asyncreadhandler (struct MonoDomain * domain, struct MonoClass * klass)
{
  gboolean D.21130;
  int iftmp.58;
  struct MonoClass * D.21134;
  int D.21136;
  int D.19188;
  int iftmp.59;
  int D.19187;
  const char[17] * D.21141;
  unsigned char D.21142;
  int D.21143;
  unsigned char D.21144;
  int D.21145;
  const unsigned char * D.21150;
  unsigned char D.21151;
  int D.21152;
  const unsigned char * D.21153;
  unsigned char D.21154;
  int D.21155;
  const unsigned char * D.21160;
  unsigned char D.21161;
  int D.21162;
  const unsigned char * D.21163;
  unsigned char D.21164;
  int D.21165;
  const unsigned char * D.21170;
  unsigned char D.21171;
  int D.21172;
  const unsigned char * D.21173;
  unsigned char D.21174;
  int D.21175;
  const char * D.21177;

  D.21134 = klass->nested_in;
  if (D.21134 != 0B) goto <D.21135>; else goto <D.21132>;
  <D.21135>:
  D.21134 = klass->nested_in;
  D.21136 = is_sd_process (domain, D.21134);
  if (D.21136 != 0) goto <D.21137>; else goto <D.21132>;
  <D.21137>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.21141 = "AsyncReadHandler";
      D.21142 = MEM[(const unsigned char *)D.21141];
      D.21143 = (int) D.21142;
      D.21144 = *__s2;
      D.21145 = (int) D.21144;
      __result = D.21143 - D.21145;
      {
        if (__s2_len != 0) goto <D.21146>; else goto <D.21147>;
        <D.21146>:
        if (__result == 0) goto <D.21148>; else goto <D.21149>;
        <D.21148>:
        D.21150 = &MEM[(void *)"AsyncReadHandler" + 1B];
        D.21151 = *D.21150;
        D.21152 = (int) D.21151;
        D.21153 = __s2 + 1;
        D.21154 = *D.21153;
        D.21155 = (int) D.21154;
        __result = D.21152 - D.21155;
        if (__s2_len > 1) goto <D.21156>; else goto <D.21157>;
        <D.21156>:
        if (__result == 0) goto <D.21158>; else goto <D.21159>;
        <D.21158>:
        D.21160 = &MEM[(void *)"AsyncReadHandler" + 2B];
        D.21161 = *D.21160;
        D.21162 = (int) D.21161;
        D.21163 = __s2 + 2;
        D.21164 = *D.21163;
        D.21165 = (int) D.21164;
        __result = D.21162 - D.21165;
        if (__s2_len > 2) goto <D.21166>; else goto <D.21167>;
        <D.21166>:
        if (__result == 0) goto <D.21168>; else goto <D.21169>;
        <D.21168>:
        D.21170 = &MEM[(void *)"AsyncReadHandler" + 3B];
        D.21171 = *D.21170;
        D.21172 = (int) D.21171;
        D.21173 = __s2 + 3;
        D.21174 = *D.21173;
        D.21175 = (int) D.21174;
        __result = D.21172 - D.21175;
        <D.21169>:
        <D.21167>:
        <D.21159>:
        <D.21157>:
        <D.21149>:
        <D.21147>:
      }
      D.19187 = __result;
    }
    iftmp.59 = -D.19187;
    goto <D.21176>;
    <D.21140>:
    D.21177 = klass->name;
    iftmp.59 = __builtin_strcmp (D.21177, "AsyncReadHandler");
    <D.21176>:
    D.19188 = iftmp.59;
  }
  if (D.19188 == 0) goto <D.21178>; else goto <D.21132>;
  <D.21178>:
  iftmp.58 = 1;
  goto <D.21133>;
  <D.21132>:
  iftmp.58 = 0;
  <D.21133>:
  D.21130 = iftmp.58;
  return D.21130;
}


is_sd_process (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.21180;
  gboolean D.21183;
  _Bool D.21184;
  int D.21185;
  int D.19166;
  int iftmp.60;
  int D.19162;
  const char[8] * D.21191;
  unsigned char D.21192;
  int D.21193;
  unsigned char D.21194;
  int D.21195;
  const unsigned char * D.21200;
  unsigned char D.21201;
  int D.21202;
  const unsigned char * D.21203;
  unsigned char D.21204;
  int D.21205;
  const unsigned char * D.21210;
  unsigned char D.21211;
  int D.21212;
  const unsigned char * D.21213;
  unsigned char D.21214;
  int D.21215;
  const unsigned char * D.21220;
  unsigned char D.21221;
  int D.21222;
  const unsigned char * D.21223;
  unsigned char D.21224;
  int D.21225;
  const char * D.21227;
  int D.19175;
  int iftmp.61;
  int D.19171;
  const char[19] * D.21233;
  unsigned char D.21234;
  int D.21235;
  unsigned char D.21236;
  int D.21237;
  const unsigned char * D.21242;
  unsigned char D.21243;
  int D.21244;
  const unsigned char * D.21245;
  unsigned char D.21246;
  int D.21247;
  const unsigned char * D.21252;
  unsigned char D.21253;
  int D.21254;
  const unsigned char * D.21255;
  unsigned char D.21256;
  int D.21257;
  const unsigned char * D.21262;
  unsigned char D.21263;
  int D.21264;
  const unsigned char * D.21265;
  unsigned char D.21266;
  int D.21267;
  const char * D.21269;

  D.21180 = domain->process_class;
  if (D.21180 != 0B) goto <D.21181>; else goto <D.21182>;
  <D.21181>:
  D.21180 = domain->process_class;
  D.21184 = D.21180 == klass;
  D.21183 = (gboolean) D.21184;
  return D.21183;
  <D.21182>:
  D.21185 = is_system_type (domain, klass);
  if (D.21185 != 0) goto <D.21186>; else goto <D.21187>;
  <D.21186>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.21191 = "Process";
      D.21192 = MEM[(const unsigned char *)D.21191];
      D.21193 = (int) D.21192;
      D.21194 = *__s2;
      D.21195 = (int) D.21194;
      __result = D.21193 - D.21195;
      {
        if (__s1_len != 0) goto <D.21196>; else goto <D.21197>;
        <D.21196>:
        if (__result == 0) goto <D.21198>; else goto <D.21199>;
        <D.21198>:
        D.21200 = &MEM[(void *)"Process" + 1B];
        D.21201 = *D.21200;
        D.21202 = (int) D.21201;
        D.21203 = __s2 + 1;
        D.21204 = *D.21203;
        D.21205 = (int) D.21204;
        __result = D.21202 - D.21205;
        if (__s1_len > 1) goto <D.21206>; else goto <D.21207>;
        <D.21206>:
        if (__result == 0) goto <D.21208>; else goto <D.21209>;
        <D.21208>:
        D.21210 = &MEM[(void *)"Process" + 2B];
        D.21211 = *D.21210;
        D.21212 = (int) D.21211;
        D.21213 = __s2 + 2;
        D.21214 = *D.21213;
        D.21215 = (int) D.21214;
        __result = D.21212 - D.21215;
        if (__s1_len > 2) goto <D.21216>; else goto <D.21217>;
        <D.21216>:
        if (__result == 0) goto <D.21218>; else goto <D.21219>;
        <D.21218>:
        D.21220 = &MEM[(void *)"Process" + 3B];
        D.21221 = *D.21220;
        D.21222 = (int) D.21221;
        D.21223 = __s2 + 3;
        D.21224 = *D.21223;
        D.21225 = (int) D.21224;
        __result = D.21222 - D.21225;
        <D.21219>:
        <D.21217>:
        <D.21209>:
        <D.21207>:
        <D.21199>:
        <D.21197>:
      }
      D.19162 = __result;
    }
    iftmp.60 = D.19162;
    goto <D.21226>;
    <D.21190>:
    D.21227 = klass->name;
    iftmp.60 = __builtin_strcmp ("Process", D.21227);
    <D.21226>:
    D.19166 = iftmp.60;
  }
  if (D.19166 == 0) goto <D.21228>; else goto <D.21229>;
  <D.21228>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.21233 = "System.Diagnostics";
      D.21234 = MEM[(const unsigned char *)D.21233];
      D.21235 = (int) D.21234;
      D.21236 = *__s2;
      D.21237 = (int) D.21236;
      __result = D.21235 - D.21237;
      {
        if (__s1_len != 0) goto <D.21238>; else goto <D.21239>;
        <D.21238>:
        if (__result == 0) goto <D.21240>; else goto <D.21241>;
        <D.21240>:
        D.21242 = &MEM[(void *)"System.Diagnostics" + 1B];
        D.21243 = *D.21242;
        D.21244 = (int) D.21243;
        D.21245 = __s2 + 1;
        D.21246 = *D.21245;
        D.21247 = (int) D.21246;
        __result = D.21244 - D.21247;
        if (__s1_len > 1) goto <D.21248>; else goto <D.21249>;
        <D.21248>:
        if (__result == 0) goto <D.21250>; else goto <D.21251>;
        <D.21250>:
        D.21252 = &MEM[(void *)"System.Diagnostics" + 2B];
        D.21253 = *D.21252;
        D.21254 = (int) D.21253;
        D.21255 = __s2 + 2;
        D.21256 = *D.21255;
        D.21257 = (int) D.21256;
        __result = D.21254 - D.21257;
        if (__s1_len > 2) goto <D.21258>; else goto <D.21259>;
        <D.21258>:
        if (__result == 0) goto <D.21260>; else goto <D.21261>;
        <D.21260>:
        D.21262 = &MEM[(void *)"System.Diagnostics" + 3B];
        D.21263 = *D.21262;
        D.21264 = (int) D.21263;
        D.21265 = __s2 + 3;
        D.21266 = *D.21265;
        D.21267 = (int) D.21266;
        __result = D.21264 - D.21267;
        <D.21261>:
        <D.21259>:
        <D.21251>:
        <D.21249>:
        <D.21241>:
        <D.21239>:
      }
      D.19171 = __result;
    }
    iftmp.61 = D.19171;
    goto <D.21268>;
    <D.21232>:
    D.21269 = klass->name_space;
    iftmp.61 = __builtin_strcmp ("System.Diagnostics", D.21269);
    <D.21268>:
    D.19175 = iftmp.61;
  }
  if (D.19175 == 0) goto <D.21270>; else goto <D.21271>;
  <D.21270>:
  domain->process_class = klass;
  D.21183 = 1;
  return D.21183;
  <D.21271>:
  <D.21229>:
  <D.21187>:
  D.21183 = 0;
  return D.21183;
}


mono_thread_pool_finish (struct MonoAsyncResult * ares, struct MonoArray * * out_args, struct MonoObject * * exc)
{
  unsigned char D.21273;
  struct MonoException * D.21276;
  struct MonoObject * D.21277;
  unsigned char D.21278;
  struct MonoObject * D.21281;
  _Bool D.21284;
  long int D.21285;
  long int D.21286;
  struct MonoObject * * D.21289;
  struct MonoVTable * D.21290;
  struct MonoDomain * D.21291;
  struct MonoWaitHandle * D.21292;
  _Bool D.21295;
  long int D.21296;
  long int D.21297;
  struct MonoMethodMessage * D.21300;
  struct MonoObject * D.21301;
  struct MonoArray * D.21302;
  struct ASyncCall * ac;
  void * wait_event;

  *exc = 0B;
  *out_args = 0B;
  mono_monitor_enter (ares);
  D.21273 = ares->endinvoke_called;
  if (D.21273 != 0) goto <D.21274>; else goto <D.21275>;
  <D.21274>:
  D.21276 = mono_get_exception_invalid_operation (0B);
  *exc = D.21276;
  mono_monitor_exit (ares);
  D.21277 = 0B;
  return D.21277;
  <D.21275>:
  ares->endinvoke_called = 1;
  D.21278 = ares->completed;
  if (D.21278 == 0) goto <D.21279>; else goto <D.21280>;
  <D.21279>:
  D.21281 = ares->handle;
  if (D.21281 == 0B) goto <D.21282>; else goto <D.21283>;
  <D.21282>:
  wait_event = CreateEvent (0B, 1, 0, 0B);
  D.21284 = wait_event == 0B;
  D.21285 = (long int) D.21284;
  D.21286 = __builtin_expect (D.21285, 0);
  if (D.21286 != 0) goto <D.21287>; else goto <D.21288>;
  <D.21287>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 958, "wait_event != 0");
  <D.21288>:
  D.21289 = &ares->handle;
  D.21290 = MEM[(struct MonoObject *)ares].vtable;
  D.21291 = D.21290->domain;
  D.21292 = mono_wait_handle_new (D.21291, wait_event);
  mono_gc_wbarrier_set_field (ares, D.21289, D.21292);
  goto <D.21293>;
  <D.21283>:
  D.21281 = ares->handle;
  wait_event = mono_wait_handle_get_handle (D.21281);
  <D.21293>:
  mono_monitor_exit (ares);
  WaitForSingleObjectEx (wait_event, 4294967295, 1);
  goto <D.21294>;
  <D.21280>:
  mono_monitor_exit (ares);
  <D.21294>:
  ac = ares->object_data;
  D.21295 = ac == 0B;
  D.21296 = (long int) D.21295;
  D.21297 = __builtin_expect (D.21296, 0);
  if (D.21297 != 0) goto <D.21298>; else goto <D.21299>;
  <D.21298>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 970, "ac != NULL");
  <D.21299>:
  D.21300 = ac->msg;
  D.21301 = D.21300->exc;
  *exc = D.21301;
  D.21302 = ac->out_args;
  *out_args = D.21302;
  D.21277 = ac->res;
  return D.21277;
}


mono_thread_pool_cleanup ()
{
  int D.21304;
  struct MonoCQ * D.21307;
  int D.21310;
  struct GPtrArray * wsqs.62;
  _Bool D.21318;
  long int D.21319;
  long int D.21320;
  _Bool D.21327;
  long int D.21328;
  long int D.21329;

  D.21304 = InterlockedExchange (&async_io_tp.pool_status, 2);
  if (D.21304 == 1) goto <D.21305>; else goto <D.21306>;
  <D.21305>:
  socket_io_cleanup (&socket_io_data);
  threadpool_kill_idle_threads (&async_io_tp);
  <D.21306>:
  D.21307 = async_io_tp.queue;
  if (D.21307 != 0B) goto <D.21308>; else goto <D.21309>;
  <D.21308>:
  sem_destroy (&async_io_tp.new_job);
  threadpool_free_queue (&async_io_tp);
  <D.21309>:
  D.21310 = InterlockedExchange (&async_tp.pool_status, 2);
  if (D.21310 == 1) goto <D.21311>; else goto <D.21312>;
  <D.21311>:
  threadpool_kill_idle_threads (&async_tp);
  threadpool_free_queue (&async_tp);
  <D.21312>:
  wsqs.62 = wsqs;
  if (wsqs.62 != 0B) goto <D.21314>; else goto <D.21315>;
  <D.21314>:
  {
    int ret;

    ret = pthread_mutex_lock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.21316>; else goto <D.21317>;
    <D.21316>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.21317>:
    D.21318 = ret != 0;
    D.21319 = (long int) D.21318;
    D.21320 = __builtin_expect (D.21319, 0);
    if (D.21320 != 0) goto <D.21321>; else goto <D.21322>;
    <D.21321>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1009, "ret == 0");
    <D.21322>:
  }
  mono_wsq_cleanup ();
  wsqs.62 = wsqs;
  if (wsqs.62 != 0B) goto <D.21323>; else goto <D.21324>;
  <D.21323>:
  wsqs.62 = wsqs;
  monoeg_g_ptr_array_free (wsqs.62, 1);
  <D.21324>:
  wsqs = 0B;
  {
    int ret;

    ret = pthread_mutex_unlock (&wsqs_lock.mutex);
    if (ret != 0) goto <D.21325>; else goto <D.21326>;
    <D.21325>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21326>:
    D.21327 = ret != 0;
    D.21328 = (long int) D.21327;
    D.21329 = __builtin_expect (D.21328, 0);
    if (D.21329 != 0) goto <D.21330>; else goto <D.21331>;
    <D.21330>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1014, "ret == 0");
    <D.21331>:
  }
  sem_destroy (&async_tp.new_job);
  <D.21315>:
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int old_val.63;
  unsigned int new_val.64;
  unsigned int D.21334;
  int D.21335;
  gint32 D.21336;
  gint32 old_val;

  <D.17837>:
  old_val = *val;
  old_val.63 = (unsigned int) old_val;
  new_val.64 = (unsigned int) new_val;
  D.21334 = __sync_val_compare_and_swap_4 (val, old_val.63, new_val.64);
  D.21335 = (int) D.21334;
  if (D.21335 != old_val) goto <D.17837>; else goto <D.17838>;
  <D.17838>:
  D.21336 = old_val;
  return D.21336;
}


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

  D.21338 = &tp->max_threads;
  n = InterlockedCompareExchange (D.21338, 0, -1);
  goto <D.19385>;
  <D.19384>:
  n = n + -1;
  D.21339 = &tp->new_job;
  mono_sem_post (D.21339);
  <D.19385>:
  if (n != 0) goto <D.19384>; else goto <D.19386>;
  <D.19386>:
}


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

  D.21340 = tp->queue;
  mono_cq_destroy (D.21340);
  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.21341;
  _Bool D.21342;
  long int D.21343;
  long int D.21344;
  _Bool D.21349;
  long int D.21350;
  long int D.21351;
  struct MonoGHashTable * D.21354;
  _Bool D.21359;
  long int D.21360;
  long int D.21361;
  int D.21364;
  unsigned int timeout.65;
  unsigned int D.21372;
  unsigned int D.21373;
  int D.21376;
  gboolean D.21377;
  void * sem_handle;
  int result;
  guint32 start_time;

  result = 1;
  start_time = 0;
  D.21341 = domain->state;
  D.21342 = D.21341 != 2;
  D.21343 = (long int) D.21342;
  D.21344 = __builtin_expect (D.21343, 0);
  if (D.21344 != 0) goto <D.21345>; else goto <D.21346>;
  <D.21345>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1159, "domain->state == MONO_APPDOMAIN_UNLOADING");
  <D.21346>:
  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.21347>; else goto <D.21348>;
    <D.21347>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.21348>:
    D.21349 = ret != 0;
    D.21350 = (long int) D.21349;
    D.21351 = __builtin_expect (D.21350, 0);
    if (D.21351 != 0) goto <D.21352>; else goto <D.21353>;
    <D.21352>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1164, "ret == 0");
    <D.21353>:
  }
  D.21354 = socket_io_data.sock_to_state;
  if (D.21354 != 0B) goto <D.21355>; else goto <D.21356>;
  <D.21355>:
  D.21354 = socket_io_data.sock_to_state;
  mono_g_hash_table_foreach_remove (D.21354, remove_sockstate_for_domain, domain);
  <D.21356>:
  {
    int ret;

    ret = pthread_mutex_unlock (&socket_io_data.io_lock.mutex);
    if (ret != 0) goto <D.21357>; else goto <D.21358>;
    <D.21357>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.21358>:
    D.21359 = ret != 0;
    D.21360 = (long int) D.21359;
    D.21361 = __builtin_expect (D.21360, 0);
    if (D.21361 != 0) goto <D.21362>; else goto <D.21363>;
    <D.21362>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "threadpool.c", 1168, "ret == 0");
    <D.21363>:
  }
  sem_handle = CreateSemaphore (0B, 0, 1, 0B);
  domain->cleanup_semaphore = sem_handle;
  mono_memory_write_barrier ();
  D.21364 = domain->threadpool_jobs;
  if (D.21364 != 0) goto <D.21365>; else goto <D.21366>;
  <D.21365>:
  if (timeout != -1) goto <D.21367>; else goto <D.21368>;
  <D.21367>:
  start_time = mono_msec_ticks ();
  <D.21368>:
  <D.21366>:
  goto <D.19461>;
  <D.19460>:
  timeout.65 = (unsigned int) timeout;
  WaitForSingleObject (sem_handle, timeout.65);
  if (timeout != -1) goto <D.21370>; else goto <D.21371>;
  <D.21370>:
  D.21372 = mono_msec_ticks ();
  D.21373 = D.21372 - start_time;
  timeout.65 = (unsigned int) timeout;
  if (D.21373 > timeout.65) goto <D.21374>; else goto <D.21375>;
  <D.21374>:
  result = 0;
  goto <D.19459>;
  <D.21375>:
  <D.21371>:
  <D.19461>:
  D.21376 = domain->threadpool_jobs;
  if (D.21376 != 0) goto <D.19460>; else goto <D.19459>;
  <D.19459>:
  domain->cleanup_semaphore = 0B;
  CloseHandle (sem_handle);
  D.21377 = result;
  return D.21377;
}


remove_sockstate_for_domain (void * key, void * value, void * user_data)
{
  struct MonoVTable * D.21379;
  struct MonoDomain * D.21380;
  gboolean D.21383;
  struct MonoMList * list;
  gboolean remove;

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

    data = mono_mlist_get_data (list);
    D.21379 = data->vtable;
    D.21380 = D.21379->domain;
    if (D.21380 == user_data) goto <D.21381>; else goto <D.21382>;
    <D.21381>:
    remove = 1;
    mono_mlist_set_data (list, 0B);
    <D.21382>:
    list = mono_mlist_next (list);
  }
  <D.19448>:
  if (list != 0B) goto <D.19447>; else goto <D.19449>;
  <D.19449>:
  D.21383 = remove;
  return D.21383;
}


threadpool_clear_queue (struct ThreadPool * tp, struct MonoDomain * domain)
{
  struct MonoObject * obj.66;
  struct MonoVTable * D.21390;
  struct MonoDomain * D.21391;
  int D.21394;
  int D.21395;
  struct MonoObject * D.21398;
  struct MonoObject * obj;
  struct MonoMList * other;
  struct MonoCQ * queue;

  try
    {
      other = 0B;
      queue = tp->queue;
      if (queue == 0B) goto <D.21385>; else goto <D.21386>;
      <D.21385>:
      return;
      <D.21386>:
      goto <D.19433>;
      <D.19434>:
      obj.66 = obj;
      if (obj.66 == 0B) goto <D.21388>; else goto <D.21389>;
      <D.21388>:
      // predicted unlikely by continue predictor.
      goto <D.19433>;
      <D.21389>:
      obj.66 = obj;
      D.21390 = obj.66->vtable;
      D.21391 = D.21390->domain;
      if (D.21391 != domain) goto <D.21392>; else goto <D.21393>;
      <D.21392>:
      obj.66 = obj;
      other = mono_mlist_prepend (other, obj.66);
      <D.21393>:
      obj.66 = obj;
      threadpool_jobs_dec (obj.66);
      <D.19433>:
      D.21394 = mono_cq_dequeue (queue, &obj);
      if (D.21394 != 0) goto <D.19434>; else goto <D.19435>;
      <D.19435>:
      D.21395 = mono_runtime_is_shutting_down ();
      if (D.21395 != 0) goto <D.21396>; else goto <D.21397>;
      <D.21396>:
      return;
      <D.21397>:
      goto <D.19437>;
      <D.19436>:
      D.21398 = mono_mlist_get_data (other);
      threadpool_append_job (tp, D.21398);
      other = mono_mlist_next (other);
      <D.19437>:
      if (other != 0B) goto <D.19436>; else goto <D.19438>;
      <D.19438>:
    }
  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.21402;

  D.21402 = 0;
  return D.21402;
}


ves_icall_System_Threading_ThreadPool_GetAvailableThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.21404;
  int D.21405;
  int D.21406;
  int D.21407;
  int D.21408;
  int D.21409;

  D.21404 = async_tp.max_threads;
  D.21405 = async_tp.busy_threads;
  D.21406 = D.21404 - D.21405;
  *workerThreads = D.21406;
  D.21407 = async_io_tp.max_threads;
  D.21408 = async_io_tp.busy_threads;
  D.21409 = D.21407 - D.21408;
  *completionPortThreads = D.21409;
}


ves_icall_System_Threading_ThreadPool_GetMaxThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.21410;
  int D.21411;

  D.21410 = async_tp.max_threads;
  *workerThreads = D.21410;
  D.21411 = async_io_tp.max_threads;
  *completionPortThreads = D.21411;
}


ves_icall_System_Threading_ThreadPool_GetMinThreads (gint * workerThreads, gint * completionPortThreads)
{
  int D.21412;
  int D.21413;

  D.21412 = async_tp.min_threads;
  *workerThreads = D.21412;
  D.21413 = async_io_tp.min_threads;
  *completionPortThreads = D.21413;
}


ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, gint completionPortThreads)
{
  MonoBoolean D.21417;
  int D.21421;
  struct MonoDomain * D.21424;
  int D.21425;
  struct MonoDomain * D.21428;
  gint max_threads;
  gint max_io_threads;

  max_threads = async_tp.max_threads;
  if (workerThreads <= 0) goto <D.21414>; else goto <D.21416>;
  <D.21416>:
  if (workerThreads > max_threads) goto <D.21414>; else goto <D.21415>;
  <D.21414>:
  D.21417 = 0;
  return D.21417;
  <D.21415>:
  max_io_threads = async_io_tp.max_threads;
  if (completionPortThreads <= 0) goto <D.21418>; else goto <D.21420>;
  <D.21420>:
  if (completionPortThreads > max_io_threads) goto <D.21418>; else goto <D.21419>;
  <D.21418>:
  D.21417 = 0;
  return D.21417;
  <D.21419>:
  InterlockedExchange (&async_tp.min_threads, workerThreads);
  InterlockedExchange (&async_io_tp.min_threads, completionPortThreads);
  D.21421 = async_tp.nthreads;
  if (D.21421 < workerThreads) goto <D.21422>; else goto <D.21423>;
  <D.21422>:
  D.21424 = mono_get_root_domain ();
  mono_thread_create_internal (D.21424, threadpool_start_idle_threads, &async_tp, 1, 0, 262144);
  <D.21423>:
  D.21425 = async_io_tp.nthreads;
  if (D.21425 < completionPortThreads) goto <D.21426>; else goto <D.21427>;
  <D.21426>:
  D.21428 = mono_get_root_domain ();
  mono_thread_create_internal (D.21428, threadpool_start_idle_threads, &async_io_tp, 1, 0, 262144);
  <D.21427>:
  D.21417 = 1;
  return D.21417;
}


ves_icall_System_Threading_ThreadPool_SetMaxThreads (gint workerThreads, gint completionPortThreads)
{
  MonoBoolean D.21433;
  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.21430>; else goto <D.21432>;
  <D.21432>:
  if (workerThreads < cpu_count) goto <D.21430>; else goto <D.21431>;
  <D.21430>:
  D.21433 = 0;
  return D.21433;
  <D.21431>:
  min_io_threads = async_io_tp.min_threads;
  if (completionPortThreads < min_io_threads) goto <D.21434>; else goto <D.21436>;
  <D.21436>:
  if (completionPortThreads < cpu_count) goto <D.21434>; else goto <D.21435>;
  <D.21434>:
  D.21433 = 0;
  return D.21433;
  <D.21435>:
  InterlockedExchange (&async_tp.max_threads, workerThreads);
  InterlockedExchange (&async_io_tp.max_threads, completionPortThreads);
  D.21433 = 1;
  return D.21433;
}


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.21438;
  struct MonoVTable * D.21441;
  struct MonoDomain * D.21442;
  struct MonoClass * D.21445;
  int D.21448;
  struct MonoInternalThread * D.21453;

  D.21438 = mono_runtime_unhandled_exception_policy_get ();
  if (D.21438 == 1) goto <D.21439>; else goto <D.21440>;
  <D.21439>:
  {
    gboolean unloaded;
    struct MonoClass * klass;

    D.21441 = exc->vtable;
    klass = D.21441->klass;
    D.21441 = exc->vtable;
    D.21442 = D.21441->domain;
    unloaded = is_appdomainunloaded_exception (D.21442, klass);
    if (unloaded == 0) goto <D.21443>; else goto <D.21444>;
    <D.21443>:
    D.21445 = mono_defaults.threadabortexception_class;
    if (D.21445 != klass) goto <D.21446>; else goto <D.21447>;
    <D.21446>:
    mono_unhandled_exception (exc);
    D.21448 = mono_environment_exitcode_get ();
    if (D.21448 == 1) goto <D.21449>; else goto <D.21450>;
    <D.21449>:
    exit (255);
    <D.21450>:
    <D.21447>:
    <D.21444>:
    D.21445 = mono_defaults.threadabortexception_class;
    if (D.21445 == klass) goto <D.21451>; else goto <D.21452>;
    <D.21451>:
    D.21453 = mono_thread_internal_current ();
    mono_thread_internal_reset_abort (D.21453);
    <D.21452>:
  }
  <D.21440>:
}


is_appdomainunloaded_exception (struct MonoDomain * domain, struct MonoClass * klass)
{
  struct MonoClass * D.21454;
  gboolean D.21457;
  _Bool D.21458;
  int D.21459;
  int D.19144;
  int iftmp.67;
  int D.19140;
  const char[27] * D.21465;
  unsigned char D.21466;
  int D.21467;
  unsigned char D.21468;
  int D.21469;
  const unsigned char * D.21474;
  unsigned char D.21475;
  int D.21476;
  const unsigned char * D.21477;
  unsigned char D.21478;
  int D.21479;
  const unsigned char * D.21484;
  unsigned char D.21485;
  int D.21486;
  const unsigned char * D.21487;
  unsigned char D.21488;
  int D.21489;
  const unsigned char * D.21494;
  unsigned char D.21495;
  int D.21496;
  const unsigned char * D.21497;
  unsigned char D.21498;
  int D.21499;
  const char * D.21501;
  int D.19153;
  int iftmp.68;
  int D.19149;
  const char[7] * D.21507;
  unsigned char D.21508;
  int D.21509;
  unsigned char D.21510;
  int D.21511;
  const unsigned char * D.21516;
  unsigned char D.21517;
  int D.21518;
  const unsigned char * D.21519;
  unsigned char D.21520;
  int D.21521;
  const unsigned char * D.21526;
  unsigned char D.21527;
  int D.21528;
  const unsigned char * D.21529;
  unsigned char D.21530;
  int D.21531;
  const unsigned char * D.21536;
  unsigned char D.21537;
  int D.21538;
  const unsigned char * D.21539;
  unsigned char D.21540;
  int D.21541;
  const char * D.21543;

  D.21454 = domain->ad_unloaded_ex_class;
  if (D.21454 != 0B) goto <D.21455>; else goto <D.21456>;
  <D.21455>:
  D.21454 = domain->ad_unloaded_ex_class;
  D.21458 = D.21454 == klass;
  D.21457 = (gboolean) D.21458;
  return D.21457;
  <D.21456>:
  D.21459 = is_corlib_type (domain, klass);
  if (D.21459 != 0) goto <D.21460>; else goto <D.21461>;
  <D.21460>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name;
      D.21465 = "AppDomainUnloadedException";
      D.21466 = MEM[(const unsigned char *)D.21465];
      D.21467 = (int) D.21466;
      D.21468 = *__s2;
      D.21469 = (int) D.21468;
      __result = D.21467 - D.21469;
      {
        if (__s1_len != 0) goto <D.21470>; else goto <D.21471>;
        <D.21470>:
        if (__result == 0) goto <D.21472>; else goto <D.21473>;
        <D.21472>:
        D.21474 = &MEM[(void *)"AppDomainUnloadedException" + 1B];
        D.21475 = *D.21474;
        D.21476 = (int) D.21475;
        D.21477 = __s2 + 1;
        D.21478 = *D.21477;
        D.21479 = (int) D.21478;
        __result = D.21476 - D.21479;
        if (__s1_len > 1) goto <D.21480>; else goto <D.21481>;
        <D.21480>:
        if (__result == 0) goto <D.21482>; else goto <D.21483>;
        <D.21482>:
        D.21484 = &MEM[(void *)"AppDomainUnloadedException" + 2B];
        D.21485 = *D.21484;
        D.21486 = (int) D.21485;
        D.21487 = __s2 + 2;
        D.21488 = *D.21487;
        D.21489 = (int) D.21488;
        __result = D.21486 - D.21489;
        if (__s1_len > 2) goto <D.21490>; else goto <D.21491>;
        <D.21490>:
        if (__result == 0) goto <D.21492>; else goto <D.21493>;
        <D.21492>:
        D.21494 = &MEM[(void *)"AppDomainUnloadedException" + 3B];
        D.21495 = *D.21494;
        D.21496 = (int) D.21495;
        D.21497 = __s2 + 3;
        D.21498 = *D.21497;
        D.21499 = (int) D.21498;
        __result = D.21496 - D.21499;
        <D.21493>:
        <D.21491>:
        <D.21483>:
        <D.21481>:
        <D.21473>:
        <D.21471>:
      }
      D.19140 = __result;
    }
    iftmp.67 = D.19140;
    goto <D.21500>;
    <D.21464>:
    D.21501 = klass->name;
    iftmp.67 = __builtin_strcmp ("AppDomainUnloadedException", D.21501);
    <D.21500>:
    D.19144 = iftmp.67;
  }
  if (D.19144 == 0) goto <D.21502>; else goto <D.21503>;
  <D.21502>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = klass->name_space;
      D.21507 = "System";
      D.21508 = MEM[(const unsigned char *)D.21507];
      D.21509 = (int) D.21508;
      D.21510 = *__s2;
      D.21511 = (int) D.21510;
      __result = D.21509 - D.21511;
      {
        if (__s1_len != 0) goto <D.21512>; else goto <D.21513>;
        <D.21512>:
        if (__result == 0) goto <D.21514>; else goto <D.21515>;
        <D.21514>:
        D.21516 = &MEM[(void *)"System" + 1B];
        D.21517 = *D.21516;
        D.21518 = (int) D.21517;
        D.21519 = __s2 + 1;
        D.21520 = *D.21519;
        D.21521 = (int) D.21520;
        __result = D.21518 - D.21521;
        if (__s1_len > 1) goto <D.21522>; else goto <D.21523>;
        <D.21522>:
        if (__result == 0) goto <D.21524>; else goto <D.21525>;
        <D.21524>:
        D.21526 = &MEM[(void *)"System" + 2B];
        D.21527 = *D.21526;
        D.21528 = (int) D.21527;
        D.21529 = __s2 + 2;
        D.21530 = *D.21529;
        D.21531 = (int) D.21530;
        __result = D.21528 - D.21531;
        if (__s1_len > 2) goto <D.21532>; else goto <D.21533>;
        <D.21532>:
        if (__result == 0) goto <D.21534>; else goto <D.21535>;
        <D.21534>:
        D.21536 = &MEM[(void *)"System" + 3B];
        D.21537 = *D.21536;
        D.21538 = (int) D.21537;
        D.21539 = __s2 + 3;
        D.21540 = *D.21539;
        D.21541 = (int) D.21540;
        __result = D.21538 - D.21541;
        <D.21535>:
        <D.21533>:
        <D.21525>:
        <D.21523>:
        <D.21515>:
        <D.21513>:
      }
      D.19149 = __result;
    }
    iftmp.68 = D.19149;
    goto <D.21542>;
    <D.21506>:
    D.21543 = klass->name_space;
    iftmp.68 = __builtin_strcmp ("System", D.21543);
    <D.21542>:
    D.19153 = iftmp.68;
  }
  if (D.19153 == 0) goto <D.21544>; else goto <D.21545>;
  <D.21544>:
  domain->ad_unloaded_ex_class = klass;
  D.21457 = 1;
  return D.21457;
  <D.21545>:
  <D.21503>:
  <D.21461>:
  D.21457 = 0;
  return D.21457;
}


mono_thread_pool_suspend ()
{
  suspended = 1;
}


mono_thread_pool_resume ()
{
  suspended = 0;
}


