mono_lock_free_queue_init (struct MonoLockFreeQueue * q)
{
  struct MonoLockFreeQueueNode * volatile iftmp.0;
  _Bool D.5664;
  int D.5665;
  struct MonoLockFreeQueueNode * D.5666;
  struct MonoLockFreeQueueNode * D.5667;
  int i;

  i = 0;
  goto <D.5609>;
  <D.5608>:
  if (i == 0) goto <D.5661>; else goto <D.5662>;
  <D.5661>:
  iftmp.0 = -2B;
  goto <D.5663>;
  <D.5662>:
  iftmp.0 = -3B;
  <D.5663>:
  q->dummies[i].node.next = iftmp.0;
  D.5664 = i == 0;
  D.5665 = (int) D.5664;
  q->dummies[i].in_use = D.5665;
  i = i + 1;
  <D.5609>:
  if (i <= 1) goto <D.5608>; else goto <D.5610>;
  <D.5610>:
  D.5666 = &q->dummies[0].node;
  D.5667 = D.5666;
  q->tail = D.5667;
  q->head = D.5667;
  q->has_dummy = 1;
}


mono_lock_free_queue_node_init (struct MonoLockFreeQueueNode * node, gboolean to_be_freed)
{
  struct MonoLockFreeQueueNode * volatile iftmp.1;

  if (to_be_freed != 0) goto <D.5669>; else goto <D.5670>;
  <D.5669>:
  iftmp.1 = -1B;
  goto <D.5671>;
  <D.5670>:
  iftmp.1 = -3B;
  <D.5671>:
  node->next = iftmp.1;
}


mono_lock_free_queue_node_free (struct MonoLockFreeQueueNode * node)
{
  struct MonoLockFreeQueueNode * D.5672;
  _Bool D.5673;
  long int D.5674;
  long int D.5675;

  D.5672 = node->next;
  D.5673 = D.5672 != -1B;
  D.5674 = (long int) D.5673;
  D.5675 = __builtin_expect (D.5674, 0);
  if (D.5675 != 0) goto <D.5676>; else goto <D.5677>;
  <D.5676>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 92, "node->next == INVALID_NEXT");
  <D.5677>:
  node->next = -3B;
}


mono_lock_free_queue_enqueue (struct MonoLockFreeQueue * q, struct MonoLockFreeQueueNode * node)
{
  struct MonoLockFreeQueueNode * D.5678;
  _Bool D.5679;
  long int D.5680;
  long int D.5681;
  struct MonoLockFreeQueueNode * volatile * D.5684;
  struct MonoLockFreeQueueNode * D.5685;
  int iftmp.2;
  _Bool D.5693;
  long int D.5694;
  long int D.5695;
  _Bool D.5698;
  long int D.5699;
  long int D.5700;
  struct MonoLockFreeQueueNode * volatile * D.5705;
  void * D.5706;
  struct MonoLockFreeQueueNode * volatile * D.5709;
  struct MonoLockFreeQueueNode * volatile * D.5712;
  struct MonoThreadHazardPointers * hp;
  struct MonoLockFreeQueueNode * tail;

  hp = mono_hazard_pointer_get ();
  D.5678 = node->next;
  D.5679 = D.5678 != -3B;
  D.5680 = (long int) D.5679;
  D.5681 = __builtin_expect (D.5680, 0);
  if (D.5681 != 0) goto <D.5682>; else goto <D.5683>;
  <D.5682>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 111, "node->next == FREE_NEXT");
  <D.5683>:
  node->next = -2B;
  <D.5626>:
  {
    struct MonoLockFreeQueueNode * next;

    D.5684 = &q->tail;
    tail = get_hazardous_pointer (D.5684, hp, 0);
    mono_memory_read_barrier ();
    next = tail->next;
    mono_memory_read_barrier ();
    D.5685 = q->tail;
    if (D.5685 == tail) goto <D.5686>; else goto <D.5687>;
    <D.5686>:
    if (next == -1B) goto <D.5689>; else goto <D.5692>;
    <D.5692>:
    if (next == -3B) goto <D.5689>; else goto <D.5690>;
    <D.5689>:
    iftmp.2 = 1;
    goto <D.5691>;
    <D.5690>:
    iftmp.2 = 0;
    <D.5691>:
    D.5693 = iftmp.2 != 0;
    D.5694 = (long int) D.5693;
    D.5695 = __builtin_expect (D.5694, 0);
    if (D.5695 != 0) goto <D.5696>; else goto <D.5697>;
    <D.5696>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 127, "next != INVALID_NEXT && next != FREE_NEXT");
    <D.5697>:
    D.5698 = next == tail;
    D.5699 = (long int) D.5698;
    D.5700 = __builtin_expect (D.5699, 0);
    if (D.5700 != 0) goto <D.5701>; else goto <D.5702>;
    <D.5701>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 128, "next != tail");
    <D.5702>:
    if (next == -2B) goto <D.5703>; else goto <D.5704>;
    <D.5703>:
    D.5705 = &tail->next;
    D.5706 = InterlockedCompareExchangePointer (D.5705, node, -2B);
    if (D.5706 == -2B) goto <D.5625>; else goto <D.5707>;
    <D.5707>:
    goto <D.5708>;
    <D.5704>:
    D.5709 = &q->tail;
    InterlockedCompareExchangePointer (D.5709, next, tail);
    <D.5708>:
    <D.5687>:
    mono_memory_write_barrier ();
    if (0 != 0) goto <D.5710>; else goto <D.5711>;
    <D.5710>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 147, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5711>:
    hp->hazard_pointers[0] = 0B;
  }
  goto <D.5626>;
  <D.5625>:
  D.5712 = &q->tail;
  InterlockedCompareExchangePointer (D.5712, node, tail);
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5713>; else goto <D.5714>;
  <D.5713>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 154, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5714>:
  hp->hazard_pointers[0] = 0B;
}


mono_memory_read_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.5715;
  long unsigned int comp.3;
  long unsigned int exch.4;
  long unsigned int D.5718;

  comp.3 = (long unsigned int) comp;
  exch.4 = (long unsigned int) exch;
  D.5718 = __sync_val_compare_and_swap_8 (dest, comp.3, exch.4);
  D.5715 = (void *) D.5718;
  return D.5715;
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_lock_free_queue_dequeue (struct MonoLockFreeQueue * q)
{
  struct MonoLockFreeQueueNode * volatile * D.5720;
  struct MonoLockFreeQueueNode * D.5721;
  int iftmp.5;
  _Bool D.5729;
  long int D.5730;
  long int D.5731;
  _Bool D.5734;
  long int D.5735;
  long int D.5736;
  int D.5745;
  int D.5748;
  struct MonoLockFreeQueueNode * D.5751;
  struct MonoLockFreeQueueNode * volatile * D.5752;
  _Bool D.5754;
  long int D.5755;
  long int D.5756;
  struct MonoLockFreeQueueNode * volatile * D.5759;
  void * D.5760;
  struct MonoLockFreeQueueNode * D.5766;
  _Bool D.5767;
  long int D.5768;
  long int D.5769;
  int D.5772;
  int D.5775;
  _Bool D.5776;
  long int D.5777;
  long int D.5778;
  int D.5781;
  struct MonoThreadHazardPointers * hp;
  struct MonoLockFreeQueueNode * head;
  void retry = <<< error >>>;

  hp = mono_hazard_pointer_get ();
  retry:
  <D.5658>:
  {
    struct MonoLockFreeQueueNode * tail;
    struct MonoLockFreeQueueNode * next;

    D.5720 = &q->head;
    head = get_hazardous_pointer (D.5720, hp, 0);
    tail = q->tail;
    mono_memory_read_barrier ();
    next = head->next;
    mono_memory_read_barrier ();
    D.5721 = q->head;
    if (D.5721 == head) goto <D.5722>; else goto <D.5723>;
    <D.5722>:
    if (next == -1B) goto <D.5725>; else goto <D.5728>;
    <D.5728>:
    if (next == -3B) goto <D.5725>; else goto <D.5726>;
    <D.5725>:
    iftmp.5 = 1;
    goto <D.5727>;
    <D.5726>:
    iftmp.5 = 0;
    <D.5727>:
    D.5729 = iftmp.5 != 0;
    D.5730 = (long int) D.5729;
    D.5731 = __builtin_expect (D.5730, 0);
    if (D.5731 != 0) goto <D.5732>; else goto <D.5733>;
    <D.5732>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 229, "next != INVALID_NEXT && next != FREE_NEXT");
    <D.5733>:
    D.5734 = next == head;
    D.5735 = (long int) D.5734;
    D.5736 = __builtin_expect (D.5735, 0);
    if (D.5736 != 0) goto <D.5737>; else goto <D.5738>;
    <D.5737>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 230, "next != head");
    <D.5738>:
    if (head == tail) goto <D.5739>; else goto <D.5740>;
    <D.5739>:
    if (next == -2B) goto <D.5741>; else goto <D.5742>;
    <D.5741>:
    if (0 != 0) goto <D.5743>; else goto <D.5744>;
    <D.5743>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 236, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5744>:
    hp->hazard_pointers[0] = 0B;
    D.5745 = is_dummy (q, head);
    if (D.5745 == 0) goto <D.5746>; else goto <D.5747>;
    <D.5746>:
    D.5748 = try_reenqueue_dummy (q);
    if (D.5748 != 0) goto <D.5749>; else goto <D.5750>;
    <D.5749>:
    // predicted unlikely by continue predictor.
    goto <D.5656>;
    <D.5750>:
    <D.5747>:
    D.5751 = 0B;
    return D.5751;
    <D.5742>:
    D.5752 = &q->tail;
    InterlockedCompareExchangePointer (D.5752, next, tail);
    goto <D.5753>;
    <D.5740>:
    D.5754 = next == -2B;
    D.5755 = (long int) D.5754;
    D.5756 = __builtin_expect (D.5755, 0);
    if (D.5756 != 0) goto <D.5757>; else goto <D.5758>;
    <D.5757>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 254, "next != END_MARKER");
    <D.5758>:
    D.5759 = &q->head;
    D.5760 = InterlockedCompareExchangePointer (D.5759, next, head);
    if (D.5760 == head) goto <D.5657>; else goto <D.5761>;
    <D.5761>:
    <D.5753>:
    <D.5723>:
    mono_memory_write_barrier ();
    if (0 != 0) goto <D.5762>; else goto <D.5763>;
    <D.5762>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 262, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5763>:
    hp->hazard_pointers[0] = 0B;
  }
  <D.5656>:
  goto <D.5658>;
  <D.5657>:
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5764>; else goto <D.5765>;
  <D.5764>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 270, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5765>:
  hp->hazard_pointers[0] = 0B;
  D.5766 = head->next;
  D.5767 = D.5766 == 0B;
  D.5768 = (long int) D.5767;
  D.5769 = __builtin_expect (D.5768, 0);
  if (D.5769 != 0) goto <D.5770>; else goto <D.5771>;
  <D.5770>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 272, "head->next");
  <D.5771>:
  head->next = -1B;
  D.5772 = is_dummy (q, head);
  if (D.5772 != 0) goto <D.5773>; else goto <D.5774>;
  <D.5773>:
  D.5775 = q->has_dummy;
  D.5776 = D.5775 == 0;
  D.5777 = (long int) D.5776;
  D.5778 = __builtin_expect (D.5777, 0);
  if (D.5778 != 0) goto <D.5779>; else goto <D.5780>;
  <D.5779>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 286, "q->has_dummy");
  <D.5780>:
  q->has_dummy = 0;
  mono_memory_write_barrier ();
  mono_thread_hazardous_free_or_queue (head, free_dummy, 0, 1);
  D.5781 = try_reenqueue_dummy (q);
  if (D.5781 != 0) goto retry; else goto <D.5782>;
  <D.5782>:
  D.5751 = 0B;
  return D.5751;
  <D.5774>:
  D.5751 = head;
  return D.5751;
}


free_dummy (void * _dummy)
{
  struct MonoLockFreeQueueNode * D.5784;
  int D.5785;
  _Bool D.5786;
  long int D.5787;
  long int D.5788;
  struct MonoLockFreeQueueDummy * dummy;

  dummy = _dummy;
  D.5784 = &dummy->node;
  mono_lock_free_queue_node_free (D.5784);
  D.5785 = dummy->in_use;
  D.5786 = D.5785 == 0;
  D.5787 = (long int) D.5786;
  D.5788 = __builtin_expect (D.5787, 0);
  if (D.5788 != 0) goto <D.5789>; else goto <D.5790>;
  <D.5789>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 162, "dummy->in_use");
  <D.5790>:
  mono_memory_write_barrier ();
  dummy->in_use = 0;
}


is_dummy (struct MonoLockFreeQueue * q, struct MonoLockFreeQueueNode * n)
{
  gboolean D.5791;
  int iftmp.6;
  struct MonoLockFreeQueueNode * D.5795;
  struct MonoLockFreeQueueNode * D.5797;

  D.5795 = &q->dummies[0].node;
  if (D.5795 <= n) goto <D.5796>; else goto <D.5793>;
  <D.5796>:
  D.5797 = &q->dummies[2].node;
  if (D.5797 > n) goto <D.5798>; else goto <D.5793>;
  <D.5798>:
  iftmp.6 = 1;
  goto <D.5794>;
  <D.5793>:
  iftmp.6 = 0;
  <D.5794>:
  D.5791 = iftmp.6;
  return D.5791;
}


try_reenqueue_dummy (struct MonoLockFreeQueue * q)
{
  int D.5800;
  gboolean D.5803;
  volatile gint32 * D.5806;
  int D.5807;
  struct MonoLockFreeQueueNode * D.5810;
  struct MonoLockFreeQueueDummy * dummy;

  D.5800 = q->has_dummy;
  if (D.5800 != 0) goto <D.5801>; else goto <D.5802>;
  <D.5801>:
  D.5803 = 0;
  return D.5803;
  <D.5802>:
  dummy = get_dummy (q);
  if (dummy == 0B) goto <D.5804>; else goto <D.5805>;
  <D.5804>:
  D.5803 = 0;
  return D.5803;
  <D.5805>:
  D.5806 = &q->has_dummy;
  D.5807 = InterlockedCompareExchange (D.5806, 1, 0);
  if (D.5807 != 0) goto <D.5808>; else goto <D.5809>;
  <D.5808>:
  dummy->in_use = 0;
  D.5803 = 0;
  return D.5803;
  <D.5809>:
  D.5810 = &dummy->node;
  mono_lock_free_queue_enqueue (q, D.5810);
  D.5803 = 1;
  return D.5803;
}


get_dummy (struct MonoLockFreeQueue * q)
{
  int D.5812;
  volatile gint32 * D.5815;
  int D.5816;
  struct MonoLockFreeQueueDummy * D.5819;
  int i;

  i = 0;
  goto <D.5638>;
  <D.5637>:
  {
    struct MonoLockFreeQueueDummy * dummy;

    dummy = &q->dummies[i];
    D.5812 = dummy->in_use;
    if (D.5812 != 0) goto <D.5813>; else goto <D.5814>;
    <D.5813>:
    // predicted unlikely by continue predictor.
    goto <D.5636>;
    <D.5814>:
    D.5815 = &dummy->in_use;
    D.5816 = InterlockedCompareExchange (D.5815, 1, 0);
    if (D.5816 == 0) goto <D.5817>; else goto <D.5818>;
    <D.5817>:
    D.5819 = dummy;
    return D.5819;
    <D.5818>:
  }
  <D.5636>:
  i = i + 1;
  <D.5638>:
  if (i <= 1) goto <D.5637>; else goto <D.5639>;
  <D.5639>:
  D.5819 = 0B;
  return D.5819;
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.5821;
  unsigned int comp.7;
  unsigned int exch.8;
  unsigned int D.5824;

  comp.7 = (unsigned int) comp;
  exch.8 = (unsigned int) exch;
  D.5824 = __sync_val_compare_and_swap_4 (dest, comp.7, exch.8);
  D.5821 = (gint32) D.5824;
  return D.5821;
}


