mono_lock_free_queue_init (struct MonoLockFreeQueue * q)
{
  struct MonoLockFreeQueueNode * volatile iftmp.0;
  _Bool D.5150;
  int D.5151;
  struct MonoLockFreeQueueNode * D.5152;
  struct MonoLockFreeQueueNode * D.5153;
  int i;

  i = 0;
  goto <D.5095>;
  <D.5094>:
  if (i == 0) goto <D.5147>; else goto <D.5148>;
  <D.5147>:
  iftmp.0 = -2B;
  goto <D.5149>;
  <D.5148>:
  iftmp.0 = -3B;
  <D.5149>:
  q->dummies[i].node.next = iftmp.0;
  D.5150 = i == 0;
  D.5151 = (int) D.5150;
  q->dummies[i].in_use = D.5151;
  i = i + 1;
  <D.5095>:
  if (i <= 1) goto <D.5094>; else goto <D.5096>;
  <D.5096>:
  D.5152 = &q->dummies[0].node;
  D.5153 = D.5152;
  q->tail = D.5153;
  q->head = D.5153;
  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.5155>; else goto <D.5156>;
  <D.5155>:
  iftmp.1 = -1B;
  goto <D.5157>;
  <D.5156>:
  iftmp.1 = -3B;
  <D.5157>:
  node->next = iftmp.1;
}


mono_lock_free_queue_node_free (struct MonoLockFreeQueueNode * node)
{
  struct MonoLockFreeQueueNode * D.5158;
  _Bool D.5159;
  long int D.5160;
  long int D.5161;

  D.5158 = node->next;
  D.5159 = D.5158 != -1B;
  D.5160 = (long int) D.5159;
  D.5161 = __builtin_expect (D.5160, 0);
  if (D.5161 != 0) goto <D.5162>; else goto <D.5163>;
  <D.5162>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 92, "node->next == INVALID_NEXT");
  <D.5163>:
  node->next = -3B;
}


mono_lock_free_queue_enqueue (struct MonoLockFreeQueue * q, struct MonoLockFreeQueueNode * node)
{
  struct MonoLockFreeQueueNode * D.5164;
  _Bool D.5165;
  long int D.5166;
  long int D.5167;
  struct MonoLockFreeQueueNode * volatile * D.5170;
  struct MonoLockFreeQueueNode * D.5171;
  _Bool D.5174;
  _Bool D.5175;
  _Bool D.5176;
  int D.5177;
  _Bool D.5178;
  long int D.5179;
  long int D.5180;
  _Bool D.5183;
  long int D.5184;
  long int D.5185;
  struct MonoLockFreeQueueNode * volatile * D.5190;
  void * D.5191;
  struct MonoLockFreeQueueNode * volatile * D.5194;
  struct MonoLockFreeQueueNode * volatile * D.5197;
  struct MonoThreadHazardPointers * hp;
  struct MonoLockFreeQueueNode * tail;

  hp = mono_hazard_pointer_get ();
  D.5164 = node->next;
  D.5165 = D.5164 != -3B;
  D.5166 = (long int) D.5165;
  D.5167 = __builtin_expect (D.5166, 0);
  if (D.5167 != 0) goto <D.5168>; else goto <D.5169>;
  <D.5168>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 111, "node->next == FREE_NEXT");
  <D.5169>:
  node->next = -2B;
  <D.5112>:
  {
    struct MonoLockFreeQueueNode * next;

    D.5170 = &q->tail;
    tail = get_hazardous_pointer (D.5170, hp, 0);
    mono_memory_read_barrier ();
    next = tail->next;
    mono_memory_read_barrier ();
    D.5171 = q->tail;
    if (D.5171 == tail) goto <D.5172>; else goto <D.5173>;
    <D.5172>:
    D.5174 = next == -1B;
    D.5175 = next == -3B;
    D.5176 = D.5174 | D.5175;
    D.5177 = (int) D.5176;
    D.5178 = D.5177 != 0;
    D.5179 = (long int) D.5178;
    D.5180 = __builtin_expect (D.5179, 0);
    if (D.5180 != 0) goto <D.5181>; else goto <D.5182>;
    <D.5181>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 127, "next != INVALID_NEXT && next != FREE_NEXT");
    <D.5182>:
    D.5183 = next == tail;
    D.5184 = (long int) D.5183;
    D.5185 = __builtin_expect (D.5184, 0);
    if (D.5185 != 0) goto <D.5186>; else goto <D.5187>;
    <D.5186>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 128, "next != tail");
    <D.5187>:
    if (next == -2B) goto <D.5188>; else goto <D.5189>;
    <D.5188>:
    D.5190 = &tail->next;
    D.5191 = InterlockedCompareExchangePointer (D.5190, node, -2B);
    if (D.5191 == -2B) goto <D.5111>; else goto <D.5192>;
    <D.5192>:
    goto <D.5193>;
    <D.5189>:
    D.5194 = &q->tail;
    InterlockedCompareExchangePointer (D.5194, next, tail);
    <D.5193>:
    <D.5173>:
    mono_memory_write_barrier ();
    if (0 != 0) goto <D.5195>; else goto <D.5196>;
    <D.5195>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 147, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5196>:
    hp->hazard_pointers[0] = 0B;
  }
  goto <D.5112>;
  <D.5111>:
  D.5197 = &q->tail;
  InterlockedCompareExchangePointer (D.5197, node, tail);
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5198>; else goto <D.5199>;
  <D.5198>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 154, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5199>:
  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.5200;
  long unsigned int exch.2;
  long unsigned int comp.3;
  long unsigned int D.5203;

  exch.2 = (long unsigned int) exch;
  comp.3 = (long unsigned int) comp;
  D.5203 = __sync_val_compare_and_swap_8 (dest, comp.3, exch.2);
  D.5200 = (void *) D.5203;
  return D.5200;
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_lock_free_queue_dequeue (struct MonoLockFreeQueue * q)
{
  struct MonoLockFreeQueueNode * volatile * D.5205;
  struct MonoLockFreeQueueNode * D.5206;
  _Bool D.5209;
  _Bool D.5210;
  _Bool D.5211;
  int D.5212;
  _Bool D.5213;
  long int D.5214;
  long int D.5215;
  _Bool D.5218;
  long int D.5219;
  long int D.5220;
  int D.5229;
  int D.5232;
  struct MonoLockFreeQueueNode * D.5235;
  struct MonoLockFreeQueueNode * volatile * D.5236;
  _Bool D.5238;
  long int D.5239;
  long int D.5240;
  struct MonoLockFreeQueueNode * volatile * D.5243;
  void * D.5244;
  struct MonoLockFreeQueueNode * D.5250;
  _Bool D.5251;
  long int D.5252;
  long int D.5253;
  int D.5256;
  int D.5259;
  _Bool D.5260;
  long int D.5261;
  long int D.5262;
  int D.5265;
  struct MonoThreadHazardPointers * hp;
  struct MonoLockFreeQueueNode * head;
  void retry = <<< error >>>;

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

    D.5205 = &q->head;
    head = get_hazardous_pointer (D.5205, hp, 0);
    tail = q->tail;
    mono_memory_read_barrier ();
    next = head->next;
    mono_memory_read_barrier ();
    D.5206 = q->head;
    if (D.5206 == head) goto <D.5207>; else goto <D.5208>;
    <D.5207>:
    D.5209 = next == -1B;
    D.5210 = next == -3B;
    D.5211 = D.5209 | D.5210;
    D.5212 = (int) D.5211;
    D.5213 = D.5212 != 0;
    D.5214 = (long int) D.5213;
    D.5215 = __builtin_expect (D.5214, 0);
    if (D.5215 != 0) goto <D.5216>; else goto <D.5217>;
    <D.5216>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 229, "next != INVALID_NEXT && next != FREE_NEXT");
    <D.5217>:
    D.5218 = next == head;
    D.5219 = (long int) D.5218;
    D.5220 = __builtin_expect (D.5219, 0);
    if (D.5220 != 0) goto <D.5221>; else goto <D.5222>;
    <D.5221>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 230, "next != head");
    <D.5222>:
    if (head == tail) goto <D.5223>; else goto <D.5224>;
    <D.5223>:
    if (next == -2B) goto <D.5225>; else goto <D.5226>;
    <D.5225>:
    if (0 != 0) goto <D.5227>; else goto <D.5228>;
    <D.5227>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 236, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5228>:
    hp->hazard_pointers[0] = 0B;
    D.5229 = is_dummy (q, head);
    if (D.5229 == 0) goto <D.5230>; else goto <D.5231>;
    <D.5230>:
    D.5232 = try_reenqueue_dummy (q);
    if (D.5232 != 0) goto <D.5233>; else goto <D.5234>;
    <D.5233>:
    // predicted unlikely by continue predictor.
    goto <D.5142>;
    <D.5234>:
    <D.5231>:
    D.5235 = 0B;
    return D.5235;
    <D.5226>:
    D.5236 = &q->tail;
    InterlockedCompareExchangePointer (D.5236, next, tail);
    goto <D.5237>;
    <D.5224>:
    D.5238 = next == -2B;
    D.5239 = (long int) D.5238;
    D.5240 = __builtin_expect (D.5239, 0);
    if (D.5240 != 0) goto <D.5241>; else goto <D.5242>;
    <D.5241>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 254, "next != END_MARKER");
    <D.5242>:
    D.5243 = &q->head;
    D.5244 = InterlockedCompareExchangePointer (D.5243, next, head);
    if (D.5244 == head) goto <D.5143>; else goto <D.5245>;
    <D.5245>:
    <D.5237>:
    <D.5208>:
    mono_memory_write_barrier ();
    if (0 != 0) goto <D.5246>; else goto <D.5247>;
    <D.5246>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 262, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5247>:
    hp->hazard_pointers[0] = 0B;
  }
  <D.5142>:
  goto <D.5144>;
  <D.5143>:
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5248>; else goto <D.5249>;
  <D.5248>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 270, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5249>:
  hp->hazard_pointers[0] = 0B;
  D.5250 = head->next;
  D.5251 = D.5250 == 0B;
  D.5252 = (long int) D.5251;
  D.5253 = __builtin_expect (D.5252, 0);
  if (D.5253 != 0) goto <D.5254>; else goto <D.5255>;
  <D.5254>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 272, "head->next");
  <D.5255>:
  head->next = -1B;
  D.5256 = is_dummy (q, head);
  if (D.5256 != 0) goto <D.5257>; else goto <D.5258>;
  <D.5257>:
  D.5259 = q->has_dummy;
  D.5260 = D.5259 == 0;
  D.5261 = (long int) D.5260;
  D.5262 = __builtin_expect (D.5261, 0);
  if (D.5262 != 0) goto <D.5263>; else goto <D.5264>;
  <D.5263>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 286, "q->has_dummy");
  <D.5264>:
  q->has_dummy = 0;
  mono_memory_write_barrier ();
  mono_thread_hazardous_free_or_queue (head, free_dummy, 0, 1);
  D.5265 = try_reenqueue_dummy (q);
  if (D.5265 != 0) goto retry; else goto <D.5266>;
  <D.5266>:
  D.5235 = 0B;
  return D.5235;
  <D.5258>:
  D.5235 = head;
  return D.5235;
}


free_dummy (void * _dummy)
{
  struct MonoLockFreeQueueNode * D.5268;
  int D.5269;
  _Bool D.5270;
  long int D.5271;
  long int D.5272;
  struct MonoLockFreeQueueDummy * dummy;

  dummy = _dummy;
  D.5268 = &dummy->node;
  mono_lock_free_queue_node_free (D.5268);
  D.5269 = dummy->in_use;
  D.5270 = D.5269 == 0;
  D.5271 = (long int) D.5270;
  D.5272 = __builtin_expect (D.5271, 0);
  if (D.5272 != 0) goto <D.5273>; else goto <D.5274>;
  <D.5273>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 162, "dummy->in_use");
  <D.5274>:
  mono_memory_write_barrier ();
  dummy->in_use = 0;
}


is_dummy (struct MonoLockFreeQueue * q, struct MonoLockFreeQueueNode * n)
{
  gboolean D.5275;
  int iftmp.4;
  struct MonoLockFreeQueueNode * D.5279;
  struct MonoLockFreeQueueNode * D.5281;

  D.5279 = &q->dummies[0].node;
  if (D.5279 <= n) goto <D.5280>; else goto <D.5277>;
  <D.5280>:
  D.5281 = &q->dummies[2].node;
  if (D.5281 > n) goto <D.5282>; else goto <D.5277>;
  <D.5282>:
  iftmp.4 = 1;
  goto <D.5278>;
  <D.5277>:
  iftmp.4 = 0;
  <D.5278>:
  D.5275 = iftmp.4;
  return D.5275;
}


try_reenqueue_dummy (struct MonoLockFreeQueue * q)
{
  int D.5284;
  gboolean D.5287;
  volatile gint32 * D.5290;
  int D.5291;
  struct MonoLockFreeQueueNode * D.5294;
  struct MonoLockFreeQueueDummy * dummy;

  D.5284 = q->has_dummy;
  if (D.5284 != 0) goto <D.5285>; else goto <D.5286>;
  <D.5285>:
  D.5287 = 0;
  return D.5287;
  <D.5286>:
  dummy = get_dummy (q);
  if (dummy == 0B) goto <D.5288>; else goto <D.5289>;
  <D.5288>:
  D.5287 = 0;
  return D.5287;
  <D.5289>:
  D.5290 = &q->has_dummy;
  D.5291 = InterlockedCompareExchange (D.5290, 1, 0);
  if (D.5291 != 0) goto <D.5292>; else goto <D.5293>;
  <D.5292>:
  dummy->in_use = 0;
  D.5287 = 0;
  return D.5287;
  <D.5293>:
  D.5294 = &dummy->node;
  mono_lock_free_queue_enqueue (q, D.5294);
  D.5287 = 1;
  return D.5287;
}


get_dummy (struct MonoLockFreeQueue * q)
{
  int D.5296;
  volatile gint32 * D.5299;
  int D.5300;
  struct MonoLockFreeQueueDummy * D.5303;
  int i;

  i = 0;
  goto <D.5124>;
  <D.5123>:
  {
    struct MonoLockFreeQueueDummy * dummy;

    dummy = &q->dummies[i];
    D.5296 = dummy->in_use;
    if (D.5296 != 0) goto <D.5297>; else goto <D.5298>;
    <D.5297>:
    // predicted unlikely by continue predictor.
    goto <D.5122>;
    <D.5298>:
    D.5299 = &dummy->in_use;
    D.5300 = InterlockedCompareExchange (D.5299, 1, 0);
    if (D.5300 == 0) goto <D.5301>; else goto <D.5302>;
    <D.5301>:
    D.5303 = dummy;
    return D.5303;
    <D.5302>:
  }
  <D.5122>:
  i = i + 1;
  <D.5124>:
  if (i <= 1) goto <D.5123>; else goto <D.5125>;
  <D.5125>:
  D.5303 = 0B;
  return D.5303;
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.5305;
  unsigned int exch.5;
  unsigned int comp.6;
  unsigned int D.5308;

  exch.5 = (unsigned int) exch;
  comp.6 = (unsigned int) comp;
  D.5308 = __sync_val_compare_and_swap_4 (dest, comp.6, exch.5);
  D.5305 = (gint32) D.5308;
  return D.5305;
}


