__attribute__((visibility ("hidden")))
mono_wsq_init ()
{
  int wsq_tlskey_inited.0;

  wsq_tlskey_inited.0 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.0 != 0) goto <D.16568>; else goto <D.16569>;
  <D.16568>:
  return;
  <D.16569>:
  mono_native_tls_alloc (&wsq_tlskey, 0B);
  wsq_tlskey_inited = 1;
}


mono_native_tls_alloc (pthread_key_t * key, void * destructor)
{
  int D.16571;
  void (*<Tc6>) (void *) destructor.1;
  int D.16573;
  _Bool D.16574;

  destructor.1 = (void (*<Tc6>) (void *)) destructor;
  D.16573 = pthread_key_create (key, destructor.1);
  D.16574 = D.16573 == 0;
  D.16571 = (int) D.16574;
  return D.16571;
}


__attribute__((visibility ("hidden")))
mono_wsq_cleanup ()
{
  int wsq_tlskey_inited.2;
  unsigned int wsq_tlskey.3;

  wsq_tlskey_inited.2 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.2 == 0) goto <D.16577>; else goto <D.16578>;
  <D.16577>:
  return;
  <D.16578>:
  wsq_tlskey.3 = wsq_tlskey;
  mono_native_tls_free (wsq_tlskey.3);
  wsq_tlskey_inited = 0;
}


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


__attribute__((visibility ("hidden")))
mono_wsq_create ()
{
  int wsq_tlskey_inited.4;
  struct MonoWSQ * D.16584;
  struct MonoArray * * D.16587;
  void * D.16588;
  struct MonoClass * D.16526;
  struct MonoClass * tmp_klass.5;
  struct MonoClass * D.16592;
  struct MonoClass * tmp_klass.6;
  _Bool D.16594;
  long int D.16595;
  long int D.16596;
  struct MonoVTable * D.16599;
  struct MonoArray * D.16600;
  union MonoSemType * D.16601;
  unsigned int wsq_tlskey.7;
  int D.16603;
  struct MonoWSQ * wsq;
  struct MonoDomain * root;

  wsq_tlskey_inited.4 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.4 == 0) goto <D.16582>; else goto <D.16583>;
  <D.16582>:
  D.16584 = 0B;
  return D.16584;
  <D.16583>:
  wsq = monoeg_malloc0 (56);
  wsq->mask = 31;
  if (0 != 0) goto <D.16585>; else goto <D.16586>;
  <D.16585>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-wsq.c", 64, "sizeof (wsq->queue) == sizeof (MonoObject*)");
  <D.16586>:
  D.16587 = &wsq->queue;
  D.16588 = mono_gc_make_root_descr_all_refs (1);
  mono_gc_register_root (D.16587, 8, D.16588);
  root = mono_get_root_domain ();
  {
    static struct MonoClass * tmp_klass;

    {
      tmp_klass.5 = tmp_klass;
      if (tmp_klass.5 == 0B) goto <D.16590>; else goto <D.16591>;
      <D.16590>:
      D.16592 = mono_defaults.object_class;
      tmp_klass.6 = mono_array_class_get (D.16592, 1);
      tmp_klass = tmp_klass.6;
      tmp_klass.5 = tmp_klass;
      D.16594 = tmp_klass.5 == 0B;
      D.16595 = (long int) D.16594;
      D.16596 = __builtin_expect (D.16595, 0);
      if (D.16596 != 0) goto <D.16597>; else goto <D.16598>;
      <D.16597>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-wsq.c", 66, "tmp_klass");
      <D.16598>:
      <D.16591>:
    }
    D.16526 = tmp_klass;
  }
  D.16599 = mono_class_vtable (root, D.16526);
  D.16600 = mono_array_new_specific (D.16599, 32);
  wsq->queue = D.16600;
  D.16601 = &wsq->lock;
  sem_init (D.16601, 0, 1);
  wsq_tlskey.7 = wsq_tlskey;
  D.16603 = mono_native_tls_set_value (wsq_tlskey.7, wsq);
  if (D.16603 == 0) goto <D.16604>; else goto <D.16605>;
  <D.16604>:
  mono_wsq_destroy (wsq);
  wsq = 0B;
  <D.16605>:
  D.16584 = wsq;
  return D.16584;
}


mono_native_tls_set_value (pthread_key_t key, void * value)
{
  int D.16607;
  int D.16608;
  _Bool D.16609;

  D.16608 = pthread_setspecific (key, value);
  D.16609 = D.16608 == 0;
  D.16607 = (int) D.16609;
  return D.16607;
}


__attribute__((visibility ("hidden")))
mono_wsq_destroy (struct MonoWSQ * wsq)
{
  struct MonoArray * D.16614;
  int D.16615;
  _Bool D.16616;
  long int D.16617;
  long int D.16618;
  struct MonoArray * * D.16621;
  union MonoSemType * D.16622;
  int wsq_tlskey_inited.8;
  unsigned int wsq_tlskey.9;
  void * D.16627;

  if (wsq == 0B) goto <D.16611>; else goto <D.16613>;
  <D.16613>:
  D.16614 = wsq->queue;
  if (D.16614 == 0B) goto <D.16611>; else goto <D.16612>;
  <D.16611>:
  return;
  <D.16612>:
  D.16615 = mono_wsq_count (wsq);
  D.16616 = D.16615 != 0;
  D.16617 = (long int) D.16616;
  D.16618 = __builtin_expect (D.16617, 0);
  if (D.16618 != 0) goto <D.16619>; else goto <D.16620>;
  <D.16619>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-wsq.c", 81, "mono_wsq_count (wsq) == 0");
  <D.16620>:
  D.16621 = &wsq->queue;
  mono_gc_deregister_root (D.16621);
  D.16622 = &wsq->lock;
  sem_destroy (D.16622);
  memset (wsq, 0, 56);
  wsq_tlskey_inited.8 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.8 != 0) goto <D.16624>; else goto <D.16625>;
  <D.16624>:
  wsq_tlskey.9 = wsq_tlskey;
  D.16627 = pthread_getspecific (wsq_tlskey.9);
  if (D.16627 == wsq) goto <D.16628>; else goto <D.16629>;
  <D.16628>:
  wsq_tlskey.9 = wsq_tlskey;
  mono_native_tls_set_value (wsq_tlskey.9, 0B);
  <D.16629>:
  <D.16625>:
  monoeg_g_free (wsq);
}


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

  D.16632 = __builtin_object_size (__dest, 0);
  D.16631 = __builtin___memset_chk (__dest, __ch, __len, D.16632);
  return D.16631;
}


__attribute__((visibility ("hidden")))
mono_wsq_count (struct MonoWSQ * wsq)
{
  gint D.16636;
  int D.16637;
  int D.16638;
  int D.16639;
  int D.16640;

  if (wsq == 0B) goto <D.16634>; else goto <D.16635>;
  <D.16634>:
  D.16636 = 0;
  return D.16636;
  <D.16635>:
  D.16637 = wsq->tail;
  D.16638 = wsq->head;
  D.16639 = D.16637 - D.16638;
  D.16640 = wsq->mask;
  D.16636 = D.16639 & D.16640;
  return D.16636;
}


__attribute__((visibility ("hidden")))
mono_wsq_local_push (void * obj)
{
  int wsq_tlskey_inited.10;
  gboolean D.16646;
  unsigned int wsq_tlskey.11;
  int D.16650;
  int D.16651;
  int D.16652;
  struct MonoArray * D.16655;
  int D.16656;
  long unsigned int D.16657;
  int D.16658;
  union MonoSemType * D.16659;
  int D.16660;
  int D.16661;
  long unsigned int D.16664;
  struct MonoDomain * D.16665;
  struct MonoClass * D.16545;
  struct MonoClass * tmp_klass.12;
  struct MonoClass * D.16669;
  struct MonoClass * tmp_klass.13;
  _Bool D.16671;
  long int D.16672;
  long int D.16673;
  struct MonoVTable * D.16676;
  int D.16677;
  long unsigned int D.16678;
  long unsigned int D.16679;
  int D.16680;
  int D.16681;
  long unsigned int D.16682;
  char * D.16683;
  struct MonoObject * D.16684;
  char * D.16685;
  long unsigned int D.16686;
  long unsigned int D.16687;
  int D.16688;
  int D.16689;
  int tail;
  int head;
  int count;
  struct MonoWSQ * wsq;

  if (obj == 0B) goto <D.16642>; else goto <D.16644>;
  <D.16644>:
  wsq_tlskey_inited.10 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.10 == 0) goto <D.16642>; else goto <D.16643>;
  <D.16642>:
  D.16646 = 0;
  return D.16646;
  <D.16643>:
  wsq_tlskey.11 = wsq_tlskey;
  wsq = pthread_getspecific (wsq_tlskey.11);
  if (wsq == 0B) goto <D.16648>; else goto <D.16649>;
  <D.16648>:
  D.16646 = 0;
  return D.16646;
  <D.16649>:
  tail = wsq->tail;
  D.16650 = wsq->head;
  D.16651 = wsq->mask;
  D.16652 = D.16650 + D.16651;
  if (D.16652 > tail) goto <D.16653>; else goto <D.16654>;
  <D.16653>:
  {
    void * * __p;

    D.16655 = wsq->queue;
    D.16651 = wsq->mask;
    D.16656 = D.16651 & tail;
    D.16657 = (long unsigned int) D.16656;
    __p = mono_array_addr_with_size (D.16655, 8, D.16657);
    D.16655 = wsq->queue;
    mono_gc_wbarrier_set_arrayref (D.16655, __p, obj);
  }
  D.16658 = tail + 1;
  wsq->tail = D.16658;
  D.16646 = 1;
  return D.16646;
  <D.16654>:
  D.16659 = &wsq->lock;
  mono_sem_wait (D.16659, 0);
  head = wsq->head;
  D.16660 = wsq->tail;
  D.16661 = wsq->head;
  count = D.16660 - D.16661;
  D.16651 = wsq->mask;
  if (D.16651 <= count) goto <D.16662>; else goto <D.16663>;
  <D.16662>:
  {
    struct MonoArray * new_array;
    int length;
    int i;

    D.16655 = wsq->queue;
    D.16664 = mono_array_length (D.16655);
    length = (int) D.16664;
    D.16665 = mono_get_root_domain ();
    {
      static struct MonoClass * tmp_klass;

      {
        tmp_klass.12 = tmp_klass;
        if (tmp_klass.12 == 0B) goto <D.16667>; else goto <D.16668>;
        <D.16667>:
        D.16669 = mono_defaults.object_class;
        tmp_klass.13 = mono_array_class_get (D.16669, 1);
        tmp_klass = tmp_klass.13;
        tmp_klass.12 = tmp_klass;
        D.16671 = tmp_klass.12 == 0B;
        D.16672 = (long int) D.16671;
        D.16673 = __builtin_expect (D.16672, 0);
        if (D.16673 != 0) goto <D.16674>; else goto <D.16675>;
        <D.16674>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-wsq.c", 132, "tmp_klass");
        <D.16675>:
        <D.16668>:
      }
      D.16545 = tmp_klass;
    }
    D.16676 = mono_class_vtable (D.16665, D.16545);
    D.16677 = length * 2;
    D.16678 = (long unsigned int) D.16677;
    new_array = mono_array_new_specific (D.16676, D.16678);
    i = 0;
    goto <D.16548>;
    <D.16547>:
    {
      void * * __p;

      D.16679 = (long unsigned int) i;
      __p = mono_array_addr_with_size (new_array, 8, D.16679);
      D.16655 = wsq->queue;
      D.16680 = i + head;
      D.16651 = wsq->mask;
      D.16681 = D.16680 & D.16651;
      D.16682 = (long unsigned int) D.16681;
      D.16683 = mono_array_addr_with_size (D.16655, 8, D.16682);
      D.16684 = MEM[(struct MonoObject * *)D.16683];
      mono_gc_wbarrier_set_arrayref (new_array, __p, D.16684);
    }
    i = i + 1;
    <D.16548>:
    if (i < length) goto <D.16547>; else goto <D.16549>;
    <D.16549>:
    D.16655 = wsq->queue;
    D.16685 = mono_array_addr_with_size (D.16655, 8, 0);
    D.16686 = (long unsigned int) length;
    D.16687 = D.16686 * 8;
    mono_gc_bzero_aligned (D.16685, D.16687);
    wsq->queue = new_array;
    wsq->head = 0;
    tail = count;
    wsq->tail = tail;
    D.16651 = wsq->mask;
    D.16688 = D.16651 << 1;
    D.16689 = D.16688 | 1;
    wsq->mask = D.16689;
  }
  <D.16663>:
  {
    void * * __p;

    D.16655 = wsq->queue;
    D.16651 = wsq->mask;
    D.16656 = D.16651 & tail;
    D.16657 = (long unsigned int) D.16656;
    __p = mono_array_addr_with_size (D.16655, 8, D.16657);
    D.16655 = wsq->queue;
    mono_gc_wbarrier_set_arrayref (D.16655, __p, obj);
  }
  D.16658 = tail + 1;
  wsq->tail = D.16658;
  D.16659 = &wsq->lock;
  mono_sem_post (D.16659);
  D.16646 = 1;
  return D.16646;
}


__attribute__((visibility ("hidden")))
mono_wsq_local_pop (void * * ptr)
{
  int wsq_tlskey_inited.14;
  gboolean D.16695;
  unsigned int wsq_tlskey.15;
  int D.16699;
  volatile gint * D.16702;
  int D.16703;
  struct MonoArray * D.16706;
  int D.16707;
  int D.16708;
  long unsigned int D.16709;
  char * D.16710;
  void * D.16711;
  union MonoSemType * D.16712;
  int D.16713;
  char * D.16716;
  void * D.16717;
  int D.16719;
  int tail;
  gboolean res;
  struct MonoWSQ * wsq;

  if (ptr == 0B) goto <D.16691>; else goto <D.16693>;
  <D.16693>:
  wsq_tlskey_inited.14 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.14 == 0) goto <D.16691>; else goto <D.16692>;
  <D.16691>:
  D.16695 = 0;
  return D.16695;
  <D.16692>:
  wsq_tlskey.15 = wsq_tlskey;
  wsq = pthread_getspecific (wsq_tlskey.15);
  if (wsq == 0B) goto <D.16697>; else goto <D.16698>;
  <D.16697>:
  D.16695 = 0;
  return D.16695;
  <D.16698>:
  tail = wsq->tail;
  D.16699 = wsq->head;
  if (D.16699 >= tail) goto <D.16700>; else goto <D.16701>;
  <D.16700>:
  D.16695 = 0;
  return D.16695;
  <D.16701>:
  tail = tail + -1;
  D.16702 = &wsq->tail;
  InterlockedExchange (D.16702, tail);
  D.16703 = wsq->head;
  if (D.16703 <= tail) goto <D.16704>; else goto <D.16705>;
  <D.16704>:
  D.16706 = wsq->queue;
  D.16707 = wsq->mask;
  D.16708 = D.16707 & tail;
  D.16709 = (long unsigned int) D.16708;
  D.16710 = mono_array_addr_with_size (D.16706, 8, D.16709);
  D.16711 = MEM[(void * *)D.16710];
  *ptr = D.16711;
  {
    void * * __p;

    D.16706 = wsq->queue;
    D.16707 = wsq->mask;
    D.16708 = D.16707 & tail;
    D.16709 = (long unsigned int) D.16708;
    __p = mono_array_addr_with_size (D.16706, 8, D.16709);
    *__p = 0B;
  }
  D.16695 = 1;
  return D.16695;
  <D.16705>:
  D.16712 = &wsq->lock;
  mono_sem_wait (D.16712, 0);
  D.16713 = wsq->head;
  if (D.16713 <= tail) goto <D.16714>; else goto <D.16715>;
  <D.16714>:
  D.16706 = wsq->queue;
  D.16707 = wsq->mask;
  D.16708 = D.16707 & tail;
  D.16709 = (long unsigned int) D.16708;
  D.16716 = mono_array_addr_with_size (D.16706, 8, D.16709);
  D.16717 = MEM[(void * *)D.16716];
  *ptr = D.16717;
  {
    void * * __p;

    D.16706 = wsq->queue;
    D.16707 = wsq->mask;
    D.16708 = D.16707 & tail;
    D.16709 = (long unsigned int) D.16708;
    __p = mono_array_addr_with_size (D.16706, 8, D.16709);
    *__p = 0B;
  }
  res = 1;
  goto <D.16718>;
  <D.16715>:
  D.16719 = tail + 1;
  wsq->tail = D.16719;
  res = 0;
  <D.16718>:
  D.16712 = &wsq->lock;
  mono_sem_post (D.16712);
  D.16695 = res;
  return D.16695;
}


InterlockedExchange (volatile gint32 * val, gint32 new_val)
{
  unsigned int old_val.16;
  unsigned int new_val.17;
  unsigned int D.16723;
  int D.16724;
  gint32 D.16725;
  gint32 old_val;

  <D.16427>:
  old_val = *val;
  old_val.16 = (unsigned int) old_val;
  new_val.17 = (unsigned int) new_val;
  D.16723 = __sync_val_compare_and_swap_4 (val, old_val.16, new_val.17);
  D.16724 = (int) D.16723;
  if (D.16724 != old_val) goto <D.16427>; else goto <D.16428>;
  <D.16428>:
  D.16725 = old_val;
  return D.16725;
}


__attribute__((visibility ("hidden")))
mono_wsq_try_steal (struct MonoWSQ * wsq, void * * ptr, guint32 ms_timeout)
{
  void * D.16731;
  int wsq_tlskey_inited.18;
  unsigned int wsq_tlskey.19;
  void * D.16735;
  union MonoSemType * D.16738;
  int D.16739;
  volatile gint * D.16742;
  int D.16743;
  int D.16744;
  struct MonoArray * D.16747;
  int D.16748;
  int D.16749;
  long unsigned int D.16750;
  char * D.16751;
  void * D.16752;

  if (wsq == 0B) goto <D.16727>; else goto <D.16729>;
  <D.16729>:
  if (ptr == 0B) goto <D.16727>; else goto <D.16730>;
  <D.16730>:
  D.16731 = *ptr;
  if (D.16731 != 0B) goto <D.16727>; else goto <D.16732>;
  <D.16732>:
  wsq_tlskey_inited.18 = wsq_tlskey_inited;
  if (wsq_tlskey_inited.18 == 0) goto <D.16727>; else goto <D.16728>;
  <D.16727>:
  return;
  <D.16728>:
  wsq_tlskey.19 = wsq_tlskey;
  D.16735 = pthread_getspecific (wsq_tlskey.19);
  if (D.16735 == wsq) goto <D.16736>; else goto <D.16737>;
  <D.16736>:
  return;
  <D.16737>:
  D.16738 = &wsq->lock;
  D.16739 = mono_sem_timedwait (D.16738, ms_timeout, 0);
  if (D.16739 == 0) goto <D.16740>; else goto <D.16741>;
  <D.16740>:
  {
    int head;

    head = wsq->head;
    D.16742 = &wsq->head;
    D.16743 = head + 1;
    InterlockedExchange (D.16742, D.16743);
    D.16744 = wsq->tail;
    if (D.16744 > head) goto <D.16745>; else goto <D.16746>;
    <D.16745>:
    D.16747 = wsq->queue;
    D.16748 = wsq->mask;
    D.16749 = D.16748 & head;
    D.16750 = (long unsigned int) D.16749;
    D.16751 = mono_array_addr_with_size (D.16747, 8, D.16750);
    D.16752 = MEM[(void * *)D.16751];
    *ptr = D.16752;
    {
      void * * __p;

      D.16747 = wsq->queue;
      D.16748 = wsq->mask;
      D.16749 = D.16748 & head;
      D.16750 = (long unsigned int) D.16749;
      __p = mono_array_addr_with_size (D.16747, 8, D.16750);
      *__p = 0B;
    }
    goto <D.16753>;
    <D.16746>:
    wsq->head = head;
    <D.16753>:
    D.16738 = &wsq->lock;
    mono_sem_post (D.16738);
  }
  <D.16741>:
}


