__attribute__((visibility ("hidden")))
mono_lock_free_queue_init (struct MonoLockFreeQueue * q)
{
  struct MonoLockFreeQueueNode * volatile iftmp.0;
  _Bool D.5317;
  int D.5318;
  struct MonoLockFreeQueueNode * D.5319;
  struct MonoLockFreeQueueNode * D.5320;
  int i;

  i = 0;
  goto <D.5262>;
  <D.5261>:
  if (i == 0) goto <D.5314>; else goto <D.5315>;
  <D.5314>:
  iftmp.0 = -2B;
  goto <D.5316>;
  <D.5315>:
  iftmp.0 = -3B;
  <D.5316>:
  q->dummies[i].node.next = iftmp.0;
  D.5317 = i == 0;
  D.5318 = (int) D.5317;
  q->dummies[i].in_use = D.5318;
  i = i + 1;
  <D.5262>:
  if (i <= 1) goto <D.5261>; else goto <D.5263>;
  <D.5263>:
  D.5319 = &q->dummies[0].node;
  D.5320 = D.5319;
  q->tail = D.5320;
  q->head = D.5320;
  q->has_dummy = 1;
}


__attribute__((visibility ("hidden")))
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.5322>; else goto <D.5323>;
  <D.5322>:
  iftmp.1 = -1B;
  goto <D.5324>;
  <D.5323>:
  iftmp.1 = -3B;
  <D.5324>:
  node->next = iftmp.1;
}


__attribute__((visibility ("hidden")))
mono_lock_free_queue_node_free (struct MonoLockFreeQueueNode * node)
{
  struct MonoLockFreeQueueNode * D.5325;
  _Bool D.5326;
  long int D.5327;
  long int D.5328;

  D.5325 = node->next;
  D.5326 = D.5325 != -1B;
  D.5327 = (long int) D.5326;
  D.5328 = __builtin_expect (D.5327, 0);
  if (D.5328 != 0) goto <D.5329>; else goto <D.5330>;
  <D.5329>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 92, "node->next == INVALID_NEXT");
  <D.5330>:
  node->next = -3B;
}


__attribute__((visibility ("hidden")))
mono_lock_free_queue_enqueue (struct MonoLockFreeQueue * q, struct MonoLockFreeQueueNode * node)
{
  struct MonoLockFreeQueueNode * D.5331;
  _Bool D.5332;
  long int D.5333;
  long int D.5334;
  struct MonoLockFreeQueueNode * volatile * D.5337;
  struct MonoLockFreeQueueNode * D.5338;
  int iftmp.2;
  _Bool D.5346;
  long int D.5347;
  long int D.5348;
  _Bool D.5351;
  long int D.5352;
  long int D.5353;
  struct MonoLockFreeQueueNode * volatile * D.5358;
  void * D.5359;
  struct MonoLockFreeQueueNode * volatile * D.5362;
  struct MonoLockFreeQueueNode * volatile * D.5365;
  struct MonoThreadHazardPointers * hp;
  struct MonoLockFreeQueueNode * tail;

  hp = mono_hazard_pointer_get ();
  D.5331 = node->next;
  D.5332 = D.5331 != -3B;
  D.5333 = (long int) D.5332;
  D.5334 = __builtin_expect (D.5333, 0);
  if (D.5334 != 0) goto <D.5335>; else goto <D.5336>;
  <D.5335>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 111, "node->next == FREE_NEXT");
  <D.5336>:
  node->next = -2B;
  <D.5279>:
  {
    struct MonoLockFreeQueueNode * next;

    D.5337 = &q->tail;
    tail = get_hazardous_pointer (D.5337, hp, 0);
    mono_memory_read_barrier ();
    next = tail->next;
    mono_memory_read_barrier ();
    D.5338 = q->tail;
    if (D.5338 == tail) goto <D.5339>; else goto <D.5340>;
    <D.5339>:
    if (next == -1B) goto <D.5342>; else goto <D.5345>;
    <D.5345>:
    if (next == -3B) goto <D.5342>; else goto <D.5343>;
    <D.5342>:
    iftmp.2 = 1;
    goto <D.5344>;
    <D.5343>:
    iftmp.2 = 0;
    <D.5344>:
    D.5346 = iftmp.2 != 0;
    D.5347 = (long int) D.5346;
    D.5348 = __builtin_expect (D.5347, 0);
    if (D.5348 != 0) goto <D.5349>; else goto <D.5350>;
    <D.5349>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 127, "next != INVALID_NEXT && next != FREE_NEXT");
    <D.5350>:
    D.5351 = next == tail;
    D.5352 = (long int) D.5351;
    D.5353 = __builtin_expect (D.5352, 0);
    if (D.5353 != 0) goto <D.5354>; else goto <D.5355>;
    <D.5354>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 128, "next != tail");
    <D.5355>:
    if (next == -2B) goto <D.5356>; else goto <D.5357>;
    <D.5356>:
    D.5358 = &tail->next;
    D.5359 = InterlockedCompareExchangePointer (D.5358, node, -2B);
    if (D.5359 == -2B) goto <D.5278>; else goto <D.5360>;
    <D.5360>:
    goto <D.5361>;
    <D.5357>:
    D.5362 = &q->tail;
    InterlockedCompareExchangePointer (D.5362, next, tail);
    <D.5361>:
    <D.5340>:
    mono_memory_write_barrier ();
    if (0 != 0) goto <D.5363>; else goto <D.5364>;
    <D.5363>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 147, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5364>:
    hp->hazard_pointers[0] = 0B;
  }
  goto <D.5279>;
  <D.5278>:
  D.5365 = &q->tail;
  InterlockedCompareExchangePointer (D.5365, node, tail);
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5366>; else goto <D.5367>;
  <D.5366>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 154, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5367>:
  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.5368;
  long unsigned int comp.3;
  long unsigned int exch.4;
  long unsigned int D.5371;

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


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


__attribute__((visibility ("hidden")))
mono_lock_free_queue_dequeue (struct MonoLockFreeQueue * q)
{
  struct MonoLockFreeQueueNode * volatile * D.5373;
  struct MonoLockFreeQueueNode * D.5374;
  int iftmp.5;
  _Bool D.5382;
  long int D.5383;
  long int D.5384;
  _Bool D.5387;
  long int D.5388;
  long int D.5389;
  int D.5398;
  int D.5401;
  struct MonoLockFreeQueueNode * D.5404;
  struct MonoLockFreeQueueNode * volatile * D.5405;
  _Bool D.5407;
  long int D.5408;
  long int D.5409;
  struct MonoLockFreeQueueNode * volatile * D.5412;
  void * D.5413;
  struct MonoLockFreeQueueNode * D.5419;
  _Bool D.5420;
  long int D.5421;
  long int D.5422;
  int D.5425;
  int D.5428;
  _Bool D.5429;
  long int D.5430;
  long int D.5431;
  int D.5434;
  struct MonoThreadHazardPointers * hp;
  struct MonoLockFreeQueueNode * head;
  void retry = <<< error >>>;

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

    D.5373 = &q->head;
    head = get_hazardous_pointer (D.5373, hp, 0);
    tail = q->tail;
    mono_memory_read_barrier ();
    next = head->next;
    mono_memory_read_barrier ();
    D.5374 = q->head;
    if (D.5374 == head) goto <D.5375>; else goto <D.5376>;
    <D.5375>:
    if (next == -1B) goto <D.5378>; else goto <D.5381>;
    <D.5381>:
    if (next == -3B) goto <D.5378>; else goto <D.5379>;
    <D.5378>:
    iftmp.5 = 1;
    goto <D.5380>;
    <D.5379>:
    iftmp.5 = 0;
    <D.5380>:
    D.5382 = iftmp.5 != 0;
    D.5383 = (long int) D.5382;
    D.5384 = __builtin_expect (D.5383, 0);
    if (D.5384 != 0) goto <D.5385>; else goto <D.5386>;
    <D.5385>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 229, "next != INVALID_NEXT && next != FREE_NEXT");
    <D.5386>:
    D.5387 = next == head;
    D.5388 = (long int) D.5387;
    D.5389 = __builtin_expect (D.5388, 0);
    if (D.5389 != 0) goto <D.5390>; else goto <D.5391>;
    <D.5390>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 230, "next != head");
    <D.5391>:
    if (head == tail) goto <D.5392>; else goto <D.5393>;
    <D.5392>:
    if (next == -2B) goto <D.5394>; else goto <D.5395>;
    <D.5394>:
    if (0 != 0) goto <D.5396>; else goto <D.5397>;
    <D.5396>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 236, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5397>:
    hp->hazard_pointers[0] = 0B;
    D.5398 = is_dummy (q, head);
    if (D.5398 == 0) goto <D.5399>; else goto <D.5400>;
    <D.5399>:
    D.5401 = try_reenqueue_dummy (q);
    if (D.5401 != 0) goto <D.5402>; else goto <D.5403>;
    <D.5402>:
    // predicted unlikely by continue predictor.
    goto <D.5309>;
    <D.5403>:
    <D.5400>:
    D.5404 = 0B;
    return D.5404;
    <D.5395>:
    D.5405 = &q->tail;
    InterlockedCompareExchangePointer (D.5405, next, tail);
    goto <D.5406>;
    <D.5393>:
    D.5407 = next == -2B;
    D.5408 = (long int) D.5407;
    D.5409 = __builtin_expect (D.5408, 0);
    if (D.5409 != 0) goto <D.5410>; else goto <D.5411>;
    <D.5410>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 254, "next != END_MARKER");
    <D.5411>:
    D.5412 = &q->head;
    D.5413 = InterlockedCompareExchangePointer (D.5412, next, head);
    if (D.5413 == head) goto <D.5310>; else goto <D.5414>;
    <D.5414>:
    <D.5406>:
    <D.5376>:
    mono_memory_write_barrier ();
    if (0 != 0) goto <D.5415>; else goto <D.5416>;
    <D.5415>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 262, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
    <D.5416>:
    hp->hazard_pointers[0] = 0B;
  }
  <D.5309>:
  goto <D.5311>;
  <D.5310>:
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5417>; else goto <D.5418>;
  <D.5417>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 270, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5418>:
  hp->hazard_pointers[0] = 0B;
  D.5419 = head->next;
  D.5420 = D.5419 == 0B;
  D.5421 = (long int) D.5420;
  D.5422 = __builtin_expect (D.5421, 0);
  if (D.5422 != 0) goto <D.5423>; else goto <D.5424>;
  <D.5423>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 272, "head->next");
  <D.5424>:
  head->next = -1B;
  D.5425 = is_dummy (q, head);
  if (D.5425 != 0) goto <D.5426>; else goto <D.5427>;
  <D.5426>:
  D.5428 = q->has_dummy;
  D.5429 = D.5428 == 0;
  D.5430 = (long int) D.5429;
  D.5431 = __builtin_expect (D.5430, 0);
  if (D.5431 != 0) goto <D.5432>; else goto <D.5433>;
  <D.5432>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 286, "q->has_dummy");
  <D.5433>:
  q->has_dummy = 0;
  mono_memory_write_barrier ();
  mono_thread_hazardous_free_or_queue (head, free_dummy, 0, 1);
  D.5434 = try_reenqueue_dummy (q);
  if (D.5434 != 0) goto retry; else goto <D.5435>;
  <D.5435>:
  D.5404 = 0B;
  return D.5404;
  <D.5427>:
  D.5404 = head;
  return D.5404;
}


free_dummy (void * _dummy)
{
  struct MonoLockFreeQueueNode * D.5437;
  int D.5438;
  _Bool D.5439;
  long int D.5440;
  long int D.5441;
  struct MonoLockFreeQueueDummy * dummy;

  dummy = _dummy;
  D.5437 = &dummy->node;
  mono_lock_free_queue_node_free (D.5437);
  D.5438 = dummy->in_use;
  D.5439 = D.5438 == 0;
  D.5440 = (long int) D.5439;
  D.5441 = __builtin_expect (D.5440, 0);
  if (D.5441 != 0) goto <D.5442>; else goto <D.5443>;
  <D.5442>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-queue.c", 162, "dummy->in_use");
  <D.5443>:
  mono_memory_write_barrier ();
  dummy->in_use = 0;
}


is_dummy (struct MonoLockFreeQueue * q, struct MonoLockFreeQueueNode * n)
{
  gboolean D.5444;
  int iftmp.6;
  struct MonoLockFreeQueueNode * D.5448;
  struct MonoLockFreeQueueNode * D.5450;

  D.5448 = &q->dummies[0].node;
  if (D.5448 <= n) goto <D.5449>; else goto <D.5446>;
  <D.5449>:
  D.5450 = &q->dummies[2].node;
  if (D.5450 > n) goto <D.5451>; else goto <D.5446>;
  <D.5451>:
  iftmp.6 = 1;
  goto <D.5447>;
  <D.5446>:
  iftmp.6 = 0;
  <D.5447>:
  D.5444 = iftmp.6;
  return D.5444;
}


try_reenqueue_dummy (struct MonoLockFreeQueue * q)
{
  int D.5453;
  gboolean D.5456;
  volatile gint32 * D.5459;
  int D.5460;
  struct MonoLockFreeQueueNode * D.5463;
  struct MonoLockFreeQueueDummy * dummy;

  D.5453 = q->has_dummy;
  if (D.5453 != 0) goto <D.5454>; else goto <D.5455>;
  <D.5454>:
  D.5456 = 0;
  return D.5456;
  <D.5455>:
  dummy = get_dummy (q);
  if (dummy == 0B) goto <D.5457>; else goto <D.5458>;
  <D.5457>:
  D.5456 = 0;
  return D.5456;
  <D.5458>:
  D.5459 = &q->has_dummy;
  D.5460 = InterlockedCompareExchange (D.5459, 1, 0);
  if (D.5460 != 0) goto <D.5461>; else goto <D.5462>;
  <D.5461>:
  dummy->in_use = 0;
  D.5456 = 0;
  return D.5456;
  <D.5462>:
  D.5463 = &dummy->node;
  mono_lock_free_queue_enqueue (q, D.5463);
  D.5456 = 1;
  return D.5456;
}


get_dummy (struct MonoLockFreeQueue * q)
{
  int D.5465;
  volatile gint32 * D.5468;
  int D.5469;
  struct MonoLockFreeQueueDummy * D.5472;
  int i;

  i = 0;
  goto <D.5291>;
  <D.5290>:
  {
    struct MonoLockFreeQueueDummy * dummy;

    dummy = &q->dummies[i];
    D.5465 = dummy->in_use;
    if (D.5465 != 0) goto <D.5466>; else goto <D.5467>;
    <D.5466>:
    // predicted unlikely by continue predictor.
    goto <D.5289>;
    <D.5467>:
    D.5468 = &dummy->in_use;
    D.5469 = InterlockedCompareExchange (D.5468, 1, 0);
    if (D.5469 == 0) goto <D.5470>; else goto <D.5471>;
    <D.5470>:
    D.5472 = dummy;
    return D.5472;
    <D.5471>:
  }
  <D.5289>:
  i = i + 1;
  <D.5291>:
  if (i <= 1) goto <D.5290>; else goto <D.5292>;
  <D.5292>:
  D.5472 = 0B;
  return D.5472;
}


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

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


