mono_monitor_init ()
{
  InitializeCriticalSection (&monitor_mutex);
}


mono_monitor_cleanup ()
{
  struct MonoThreadsSync * mon;

  mon = monitor_freelist;
  goto <D.20472>;
  <D.20471>:
  mon->wait_list = 4294967295B;
  mon = mon->data;
  <D.20472>:
  if (mon != 0B) goto <D.20471>; else goto <D.20473>;
  <D.20473>:
}


mono_monitor_init_tls ()
{
  long unsigned int tls_pthread_self.0;

  tls_pthread_self.0 = pthread_self ();
  tls_pthread_self = tls_pthread_self.0;
}


mono_locks_dump (gboolean include_untaken)
{
  int D.20736;
  void * D.20737;
  int D.20740;
  int D.20744;
  void * * D.20747;
  unsigned int D.20748;
  void * D.20751;
  unsigned int D.20752;
  void * D.20753;
  int D.20756;
  int i;
  int used;
  int on_freelist;
  int to_recycle;
  int total;
  int num_arrays;
  struct MonoThreadsSync * mon;
  struct MonitorArray * marray;

  used = 0;
  on_freelist = 0;
  to_recycle = 0;
  total = 0;
  num_arrays = 0;
  mon = monitor_freelist;
  goto <D.20496>;
  <D.20495>:
  on_freelist = on_freelist + 1;
  mon = mon->data;
  <D.20496>:
  if (mon != 0B) goto <D.20495>; else goto <D.20497>;
  <D.20497>:
  marray = monitor_allocated;
  goto <D.20503>;
  <D.20502>:
  D.20736 = marray->num_monitors;
  total = D.20736 + total;
  num_arrays = num_arrays + 1;
  i = 0;
  goto <D.20500>;
  <D.20499>:
  mon = &marray->monitors[i];
  D.20737 = mon->data;
  if (D.20737 == 0B) goto <D.20738>; else goto <D.20739>;
  <D.20738>:
  D.20736 = marray->num_monitors;
  D.20740 = D.20736 + -1;
  if (D.20740 > i) goto <D.20741>; else goto <D.20742>;
  <D.20741>:
  to_recycle = to_recycle + 1;
  <D.20742>:
  goto <D.20743>;
  <D.20739>:
  D.20737 = mon->data;
  D.20744 = monitor_is_on_freelist (D.20737);
  if (D.20744 == 0) goto <D.20745>; else goto <D.20746>;
  <D.20745>:
  {
    struct MonoObject * holder;

    D.20747 = &mon->data;
    holder = mono_gc_weak_link_get (D.20747);
    D.20748 = mon->owner;
    if (D.20748 != 0) goto <D.20749>; else goto <D.20750>;
    <D.20749>:
    D.20748 = mon->owner;
    D.20751 = (void *) D.20748;
    D.20752 = mon->nest;
    monoeg_g_print ("Lock %p in object %p held by thread %p, nest level: %d\n", mon, holder, D.20751, D.20752);
    D.20753 = mon->entry_sem;
    if (D.20753 != 0B) goto <D.20754>; else goto <D.20755>;
    <D.20754>:
    D.20753 = mon->entry_sem;
    D.20756 = mon->entry_count;
    monoeg_g_print ("\tWaiting on semaphore %p: %d\n", D.20753, D.20756);
    <D.20755>:
    goto <D.20757>;
    <D.20750>:
    if (include_untaken != 0) goto <D.20758>; else goto <D.20759>;
    <D.20758>:
    monoeg_g_print ("Lock %p in object %p untaken\n", mon, holder);
    <D.20759>:
    <D.20757>:
    used = used + 1;
  }
  <D.20746>:
  <D.20743>:
  i = i + 1;
  <D.20500>:
  D.20736 = marray->num_monitors;
  if (D.20736 > i) goto <D.20499>; else goto <D.20501>;
  <D.20501>:
  marray = marray->next;
  <D.20503>:
  if (marray != 0B) goto <D.20502>; else goto <D.20504>;
  <D.20504>:
  monoeg_g_print ("Total locks (in %d array(s)): %d, used: %d, on freelist: %d, to recycle: %d\n", num_arrays, total, used, on_freelist, to_recycle);
}


monitor_is_on_freelist (struct MonoThreadsSync * mon)
{
  struct MonoThreadsSync[0:] * D.20760;
  int D.20763;
  struct MonoThreadsSync * D.20764;
  int D.20767;
  struct MonitorArray * marray;

  marray = monitor_allocated;
  goto <D.20482>;
  <D.20481>:
  D.20760 = &marray->monitors;
  if (D.20760 <= mon) goto <D.20761>; else goto <D.20762>;
  <D.20761>:
  D.20763 = marray->num_monitors;
  D.20764 = &marray->monitors[D.20763];
  if (D.20764 > mon) goto <D.20765>; else goto <D.20766>;
  <D.20765>:
  D.20767 = 1;
  return D.20767;
  <D.20766>:
  <D.20762>:
  marray = marray->next;
  <D.20482>:
  if (marray != 0B) goto <D.20481>; else goto <D.20483>;
  <D.20483>:
  D.20767 = 0;
  return D.20767;
}


mono_object_hash (struct MonoObject * obj)
{
  int D.20771;
  struct MonoThreadsSync * D.20772;
  unsigned int D.20773;
  unsigned int D.20774;
  unsigned int D.20777;
  unsigned int D.20778;
  unsigned int D.20781;
  struct MonoThreadsSync * D.20782;
  unsigned int obj.1;
  unsigned int D.20784;
  int hash.2;
  unsigned int D.20788;
  unsigned int D.20790;
  unsigned int D.20791;
  struct MonoThreadsSync * * D.20792;
  void * D.20793;
  union LockWord lw;
  unsigned int hash;

  try
    {
      if (obj == 0B) goto <D.20769>; else goto <D.20770>;
      <D.20769>:
      D.20771 = 0;
      return D.20771;
      <D.20770>:
      D.20772 = obj->synchronisation;
      lw.sync = D.20772;
      D.20773 = lw.lock_word;
      D.20774 = D.20773 & 1;
      if (D.20774 != 0) goto <D.20775>; else goto <D.20776>;
      <D.20775>:
      D.20773 = lw.lock_word;
      D.20777 = D.20773 >> 2;
      D.20771 = (int) D.20777;
      return D.20771;
      <D.20776>:
      D.20773 = lw.lock_word;
      D.20778 = D.20773 & 2;
      if (D.20778 != 0) goto <D.20779>; else goto <D.20780>;
      <D.20779>:
      D.20773 = lw.lock_word;
      D.20781 = D.20773 & 4294967292;
      lw.lock_word = D.20781;
      D.20782 = lw.sync;
      D.20771 = D.20782->hash_code;
      return D.20771;
      <D.20780>:
      obj.1 = (unsigned int) obj;
      D.20784 = obj.1 >> 3;
      hash = D.20784 * 2654435761;
      hash = hash & 1073741823;
      D.20782 = lw.sync;
      if (D.20782 != 0B) goto <D.20785>; else goto <D.20786>;
      <D.20785>:
      D.20782 = lw.sync;
      hash.2 = (int) hash;
      D.20782->hash_code = hash.2;
      D.20773 = lw.lock_word;
      D.20788 = D.20773 | 2;
      lw.lock_word = D.20788;
      D.20782 = lw.sync;
      obj->synchronisation = D.20782;
      goto <D.20789>;
      <D.20786>:
      D.20790 = hash << 2;
      D.20791 = D.20790 | 1;
      lw.lock_word = D.20791;
      D.20792 = &obj->synchronisation;
      D.20782 = lw.sync;
      D.20793 = InterlockedCompareExchangePointer (D.20792, D.20782, 0B);
      if (D.20793 == 0B) goto <D.20794>; else goto <D.20795>;
      <D.20794>:
      D.20771 = (int) hash;
      return D.20771;
      <D.20795>:
      D.20772 = obj->synchronisation;
      lw.sync = D.20772;
      D.20773 = lw.lock_word;
      D.20774 = D.20773 & 1;
      if (D.20774 != 0) goto <D.20796>; else goto <D.20797>;
      <D.20796>:
      D.20771 = (int) hash;
      return D.20771;
      <D.20797>:
      D.20773 = lw.lock_word;
      D.20781 = D.20773 & 4294967292;
      lw.lock_word = D.20781;
      D.20782 = lw.sync;
      hash.2 = (int) hash;
      D.20782->hash_code = hash.2;
      D.20773 = lw.lock_word;
      D.20788 = D.20773 | 2;
      lw.lock_word = D.20788;
      D.20782 = lw.sync;
      obj->synchronisation = D.20782;
      <D.20789>:
      D.20771 = (int) hash;
      return D.20771;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.20800;
  unsigned int comp.3;
  unsigned int exch.4;
  unsigned int D.20803;

  comp.3 = (unsigned int) comp;
  exch.4 = (unsigned int) exch;
  D.20803 = __sync_val_compare_and_swap_4 (dest, comp.3, exch.4);
  D.20800 = (void *) D.20803;
  return D.20800;
}


mono_monitor_enter (struct MonoObject * obj)
{
  mono_bool D.20805;
  int D.20806;
  _Bool D.20807;

  D.20806 = mono_monitor_try_enter_internal (obj, 4294967295, 0);
  D.20807 = D.20806 == 1;
  D.20805 = (mono_bool) D.20807;
  return D.20805;
}


mono_monitor_try_enter_internal (struct MonoObject * obj, guint32 ms, gboolean allow_interruption)
{
  _Bool D.20809;
  long int D.20810;
  long int D.20811;
  struct MonoException * D.20814;
  gint32 D.20815;
  _Bool D.20816;
  long int D.20817;
  long int D.20818;
  _Bool D.20823;
  long int D.20824;
  long int D.20825;
  struct MonoThreadsSync * * D.20828;
  void * D.20829;
  void * * D.20832;
  _Bool D.20835;
  long int D.20836;
  long int D.20837;
  struct MonoThreadsSync * D.20840;
  unsigned int D.20841;
  unsigned int D.20842;
  unsigned int D.20845;
  int D.20846;
  unsigned int D.20847;
  struct MonoThreadsSync * D.20848;
  void * D.20849;
  _Bool D.20854;
  long int D.20855;
  long int D.20856;
  _Bool D.20861;
  long int D.20862;
  long int D.20863;
  unsigned int D.20866;
  _Bool D.20871;
  long int D.20872;
  long int D.20873;
  unsigned int D.20876;
  _Bool D.20880;
  long int D.20881;
  long int D.20882;
  unsigned int D.20886;
  unsigned int D.20887;
  _Bool D.20892;
  long int D.20893;
  long int D.20894;
  unsigned int D.20897;
  int D.20898;
  unsigned int D.20899;
  struct MonoThreadsSync * D.20900;
  void * D.20901;
  _Bool D.20906;
  long int D.20907;
  long int D.20908;
  _Bool D.20913;
  long int D.20914;
  long int D.20915;
  unsigned int D.20918;
  unsigned int D.20919;
  unsigned int D.20920;
  _Bool D.20921;
  long int D.20922;
  long int D.20923;
  gsize * D.20926;
  void * id.5;
  void * D.20928;
  _Bool D.20929;
  long int D.20930;
  long int D.20931;
  unsigned int D.20933;
  _Bool D.20934;
  long int D.20935;
  long int D.20936;
  unsigned int D.20941;
  struct MonoPerfCounters * mono_perfcounters.6;
  unsigned int D.20943;
  unsigned int D.20944;
  void * D.20949;
  _Bool D.20950;
  long int D.20951;
  long int D.20952;
  void * D.20959;
  _Bool D.20962;
  long int D.20963;
  long int D.20964;
  void * * D.20967;
  void * D.20968;
  volatile gint32 * D.20977;
  unsigned int D.20978;
  unsigned int D.20979;
  unsigned int D.20980;
  unsigned int D.20981;
  volatile gint32 * D.20982;
  unsigned int D.20983;
  unsigned int D.20988;
  _Bool D.20995;
  _Bool D.20996;
  _Bool D.20997;
  struct MonoInternalThread * D.21005;
  int D.21006;
  struct MonoThreadsSync * mon;
  gsize id;
  void * sem;
  guint32 then;
  guint32 now;
  guint32 delta;
  guint32 waitms;
  guint32 ret;
  struct MonoInternalThread * thread;
  void retry = <<< error >>>;
  void retry_contended = <<< error >>>;

  id = tls_pthread_self;
  then = 0;
  D.20809 = obj == 0B;
  D.20810 = (long int) D.20809;
  D.20811 = __builtin_expect (D.20810, 0);
  if (D.20811 != 0) goto <D.20812>; else goto <D.20813>;
  <D.20812>:
  D.20814 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.20814);
  D.20815 = 0;
  return D.20815;
  <D.20813>:
  retry:
  mon = obj->synchronisation;
  D.20816 = mon == 0B;
  D.20817 = (long int) D.20816;
  D.20818 = __builtin_expect (D.20817, 0);
  if (D.20818 != 0) goto <D.20819>; else goto <D.20820>;
  <D.20819>:
  {
    int ret;

    ret = pthread_mutex_lock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.20821>; else goto <D.20822>;
    <D.20821>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20822>:
    D.20823 = ret != 0;
    D.20824 = (long int) D.20823;
    D.20825 = __builtin_expect (D.20824, 0);
    if (D.20825 != 0) goto <D.20826>; else goto <D.20827>;
    <D.20826>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 439, "ret == 0");
    <D.20827>:
  }
  mon = mon_new (id);
  D.20828 = &obj->synchronisation;
  D.20829 = InterlockedCompareExchangePointer (D.20828, mon, 0B);
  if (D.20829 == 0B) goto <D.20830>; else goto <D.20831>;
  <D.20830>:
  D.20832 = &mon->data;
  mono_gc_weak_link_add (D.20832, obj, 0);
  {
    int ret;

    ret = pthread_mutex_unlock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.20833>; else goto <D.20834>;
    <D.20833>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20834>:
    D.20835 = ret != 0;
    D.20836 = (long int) D.20835;
    D.20837 = __builtin_expect (D.20836, 0);
    if (D.20837 != 0) goto <D.20838>; else goto <D.20839>;
    <D.20838>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 443, "ret == 0");
    <D.20839>:
  }
  D.20815 = 1;
  return D.20815;
  <D.20831>:
  {
    union LockWord lw;

    try
      {
        D.20840 = obj->synchronisation;
        lw.sync = D.20840;
        D.20841 = lw.lock_word;
        D.20842 = D.20841 & 1;
        if (D.20842 != 0) goto <D.20843>; else goto <D.20844>;
        <D.20843>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          D.20841 = lw.lock_word;
          D.20845 = D.20841 >> 2;
          D.20846 = (int) D.20845;
          mon->hash_code = D.20846;
          lw.sync = mon;
          D.20841 = lw.lock_word;
          D.20847 = D.20841 | 2;
          lw.lock_word = D.20847;
          D.20828 = &obj->synchronisation;
          D.20848 = lw.sync;
          D.20849 = InterlockedCompareExchangePointer (D.20828, D.20848, oldlw);
          if (D.20849 == oldlw) goto <D.20850>; else goto <D.20851>;
          <D.20850>:
          D.20832 = &mon->data;
          mono_gc_weak_link_add (D.20832, obj, 0);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.20852>; else goto <D.20853>;
            <D.20852>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.20853>:
            D.20854 = ret != 0;
            D.20855 = (long int) D.20854;
            D.20856 = __builtin_expect (D.20855, 0);
            if (D.20856 != 0) goto <D.20857>; else goto <D.20858>;
            <D.20857>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 458, "ret == 0");
            <D.20858>:
          }
          D.20815 = 1;
          return D.20815;
          <D.20851>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.20859>; else goto <D.20860>;
            <D.20859>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.20860>:
            D.20861 = ret != 0;
            D.20862 = (long int) D.20861;
            D.20863 = __builtin_expect (D.20862, 0);
            if (D.20863 != 0) goto <D.20864>; else goto <D.20865>;
            <D.20864>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 463, "ret == 0");
            <D.20865>:
          }
          goto retry;
        }
        <D.20844>:
        D.20841 = lw.lock_word;
        D.20866 = D.20841 & 2;
        if (D.20866 != 0) goto <D.20867>; else goto <D.20868>;
        <D.20867>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.20869>; else goto <D.20870>;
          <D.20869>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.20870>:
          D.20871 = ret != 0;
          D.20872 = (long int) D.20871;
          D.20873 = __builtin_expect (D.20872, 0);
          if (D.20873 != 0) goto <D.20874>; else goto <D.20875>;
          <D.20874>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 468, "ret == 0");
          <D.20875>:
        }
        D.20841 = lw.lock_word;
        D.20876 = D.20841 & 4294967292;
        lw.lock_word = D.20876;
        mon = lw.sync;
        goto <D.20877>;
        <D.20868>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          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", "monitor.c", 474, "ret == 0");
          <D.20884>:
        }
        mon = obj->synchronisation;
        <D.20877>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  goto <D.20885>;
  <D.20820>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.20886 = lw.lock_word;
        D.20887 = D.20886 & 1;
        if (D.20887 != 0) goto <D.20888>; else goto <D.20889>;
        <D.20888>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          {
            int ret;

            ret = pthread_mutex_lock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.20890>; else goto <D.20891>;
            <D.20890>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
            <D.20891>:
            D.20892 = ret != 0;
            D.20893 = (long int) D.20892;
            D.20894 = __builtin_expect (D.20893, 0);
            if (D.20894 != 0) goto <D.20895>; else goto <D.20896>;
            <D.20895>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 489, "ret == 0");
            <D.20896>:
          }
          mon = mon_new (id);
          D.20886 = lw.lock_word;
          D.20897 = D.20886 >> 2;
          D.20898 = (int) D.20897;
          mon->hash_code = D.20898;
          lw.sync = mon;
          D.20886 = lw.lock_word;
          D.20899 = D.20886 | 2;
          lw.lock_word = D.20899;
          D.20828 = &obj->synchronisation;
          D.20900 = lw.sync;
          D.20901 = InterlockedCompareExchangePointer (D.20828, D.20900, oldlw);
          if (D.20901 == oldlw) goto <D.20902>; else goto <D.20903>;
          <D.20902>:
          D.20832 = &mon->data;
          mono_gc_weak_link_add (D.20832, obj, 1);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.20904>; else goto <D.20905>;
            <D.20904>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.20905>:
            D.20906 = ret != 0;
            D.20907 = (long int) D.20906;
            D.20908 = __builtin_expect (D.20907, 0);
            if (D.20908 != 0) goto <D.20909>; else goto <D.20910>;
            <D.20909>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 497, "ret == 0");
            <D.20910>:
          }
          D.20815 = 1;
          return D.20815;
          <D.20903>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.20911>; else goto <D.20912>;
            <D.20911>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.20912>:
            D.20913 = ret != 0;
            D.20914 = (long int) D.20913;
            D.20915 = __builtin_expect (D.20914, 0);
            if (D.20915 != 0) goto <D.20916>; else goto <D.20917>;
            <D.20916>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 502, "ret == 0");
            <D.20917>:
          }
          goto retry;
        }
        <D.20889>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  <D.20885>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.20918 = lw.lock_word;
        D.20919 = D.20918 & 4294967292;
        lw.lock_word = D.20919;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.20920 = mon->owner;
  D.20921 = D.20920 == 0;
  D.20922 = (long int) D.20921;
  D.20923 = __builtin_expect (D.20922, 1);
  if (D.20923 != 0) goto <D.20924>; else goto <D.20925>;
  <D.20924>:
  D.20926 = &mon->owner;
  id.5 = (void *) id;
  D.20928 = InterlockedCompareExchangePointer (D.20926, id.5, 0B);
  D.20929 = D.20928 == 0B;
  D.20930 = (long int) D.20929;
  D.20931 = __builtin_expect (D.20930, 1);
  if (D.20931 != 0) goto <D.20932>; else goto retry;
  <D.20932>:
  D.20933 = mon->nest;
  D.20934 = D.20933 != 1;
  D.20935 = (long int) D.20934;
  D.20936 = __builtin_expect (D.20935, 0);
  if (D.20936 != 0) goto <D.20937>; else goto <D.20938>;
  <D.20937>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 530, "mon->nest == 1");
  <D.20938>:
  D.20815 = 1;
  return D.20815;
  <D.20925>:
  D.20920 = mon->owner;
  if (D.20920 == id) goto <D.20939>; else goto <D.20940>;
  <D.20939>:
  D.20933 = mon->nest;
  D.20941 = D.20933 + 1;
  mon->nest = D.20941;
  D.20815 = 1;
  return D.20815;
  <D.20940>:
  mono_perfcounters.6 = mono_perfcounters;
  D.20943 = mono_perfcounters.6->thread_contentions;
  D.20944 = D.20943 + 1;
  mono_perfcounters.6->thread_contentions = D.20944;
  if (ms == 0) goto <D.20945>; else goto <D.20946>;
  <D.20945>:
  D.20815 = 0;
  return D.20815;
  <D.20946>:
  mono_profiler_monitor_event (obj, 1);
  retry_contended:
  D.20920 = mon->owner;
  D.20921 = D.20920 == 0;
  D.20922 = (long int) D.20921;
  D.20923 = __builtin_expect (D.20922, 1);
  if (D.20923 != 0) goto <D.20947>; else goto <D.20948>;
  <D.20947>:
  D.20926 = &mon->owner;
  id.5 = (void *) id;
  D.20949 = InterlockedCompareExchangePointer (D.20926, id.5, 0B);
  D.20950 = D.20949 == 0B;
  D.20951 = (long int) D.20950;
  D.20952 = __builtin_expect (D.20951, 1);
  if (D.20952 != 0) goto <D.20953>; else goto <D.20954>;
  <D.20953>:
  D.20933 = mon->nest;
  D.20934 = D.20933 != 1;
  D.20935 = (long int) D.20934;
  D.20936 = __builtin_expect (D.20935, 0);
  if (D.20936 != 0) goto <D.20955>; else goto <D.20956>;
  <D.20955>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 574, "mon->nest == 1");
  <D.20956>:
  mono_profiler_monitor_event (obj, 2);
  D.20815 = 1;
  return D.20815;
  <D.20954>:
  <D.20948>:
  D.20920 = mon->owner;
  if (D.20920 == id) goto <D.20957>; else goto <D.20958>;
  <D.20957>:
  D.20933 = mon->nest;
  D.20941 = D.20933 + 1;
  mon->nest = D.20941;
  mono_profiler_monitor_event (obj, 2);
  D.20815 = 1;
  return D.20815;
  <D.20958>:
  D.20959 = mon->entry_sem;
  if (D.20959 == 0B) goto <D.20960>; else goto <D.20961>;
  <D.20960>:
  sem = CreateSemaphore (0B, 0, 2147483647, 0B);
  D.20962 = sem == 0B;
  D.20963 = (long int) D.20962;
  D.20964 = __builtin_expect (D.20963, 0);
  if (D.20964 != 0) goto <D.20965>; else goto <D.20966>;
  <D.20965>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 593, "sem != NULL");
  <D.20966>:
  D.20967 = &mon->entry_sem;
  D.20968 = InterlockedCompareExchangePointer (D.20967, sem, 0B);
  if (D.20968 != 0B) goto <D.20969>; else goto <D.20970>;
  <D.20969>:
  CloseHandle (sem);
  <D.20970>:
  <D.20961>:
  if (ms != 4294967295) goto <D.20971>; else goto <D.20972>;
  <D.20971>:
  then = mono_msec_ticks ();
  if (ms <= 99) goto <D.20973>; else goto <D.20974>;
  <D.20973>:
  waitms = ms;
  goto <D.20975>;
  <D.20974>:
  waitms = 100;
  <D.20975>:
  goto <D.20976>;
  <D.20972>:
  waitms = 100;
  <D.20976>:
  D.20977 = &mon->entry_count;
  InterlockedIncrement (D.20977);
  mono_perfcounters.6 = mono_perfcounters;
  D.20978 = mono_perfcounters.6->thread_queue_len;
  D.20979 = D.20978 + 1;
  mono_perfcounters.6->thread_queue_len = D.20979;
  mono_perfcounters.6 = mono_perfcounters;
  D.20980 = mono_perfcounters.6->thread_queue_max;
  D.20981 = D.20980 + 1;
  mono_perfcounters.6->thread_queue_max = D.20981;
  thread = mono_thread_internal_current ();
  mono_thread_set_state (thread, 32);
  D.20959 = mon->entry_sem;
  ret = WaitForSingleObjectEx (D.20959, waitms, 1);
  mono_thread_clr_state (thread, 32);
  D.20982 = &mon->entry_count;
  InterlockedDecrement (D.20982);
  mono_perfcounters.6 = mono_perfcounters;
  D.20978 = mono_perfcounters.6->thread_queue_len;
  D.20983 = D.20978 + 4294967295;
  mono_perfcounters.6->thread_queue_len = D.20983;
  if (ms != 4294967295) goto <D.20984>; else goto <D.20985>;
  <D.20984>:
  now = mono_msec_ticks ();
  if (now < then) goto <D.20986>; else goto <D.20987>;
  <D.20986>:
  D.20988 = now - then;
  now = D.20988 - 1;
  then = 0;
  <D.20987>:
  delta = now - then;
  if (delta >= ms) goto <D.20989>; else goto <D.20990>;
  <D.20989>:
  ms = 0;
  goto <D.20991>;
  <D.20990>:
  ms = ms - delta;
  <D.20991>:
  if (ret == 258) goto <D.20992>; else goto <D.20994>;
  <D.20994>:
  D.20995 = ret == 192;
  D.20996 = allow_interruption == 0;
  D.20997 = D.20995 & D.20996;
  if (D.20997 != 0) goto <D.20992>; else goto <D.20993>;
  <D.20992>:
  if (ms != 0) goto retry_contended; else goto <D.20998>;
  <D.20998>:
  <D.20993>:
  goto <D.20999>;
  <D.20985>:
  if (ret == 258) goto <D.21000>; else goto <D.21002>;
  <D.21002>:
  D.20995 = ret == 192;
  D.20996 = allow_interruption == 0;
  D.20997 = D.20995 & D.20996;
  if (D.20997 != 0) goto <D.21000>; else goto <D.21001>;
  <D.21000>:
  if (ret == 192) goto <D.21003>; else goto <D.21004>;
  <D.21003>:
  D.21005 = mono_thread_internal_current ();
  D.21006 = mono_thread_test_state (D.21005, 3);
  if (D.21006 != 0) goto <D.21007>; else goto <D.21008>;
  <D.21007>:
  mono_profiler_monitor_event (obj, 3);
  D.20815 = -1;
  return D.20815;
  <D.21008>:
  <D.21004>:
  goto retry_contended;
  <D.21001>:
  <D.20999>:
  if (ret == 0) goto retry_contended; else goto <D.21009>;
  <D.21009>:
  mono_profiler_monitor_event (obj, 3);
  if (ret == 192) goto <D.21010>; else goto <D.21011>;
  <D.21010>:
  D.20815 = -1;
  return D.20815;
  <D.21011>:
  D.20815 = 0;
  return D.20815;
}


mon_new (gsize id)
{
  struct MonoThreadsSync * monitor_freelist.7;
  void * D.21022;
  struct GSList * D.21025;
  void * D.21028;
  struct GSList * D.21029;
  void * * D.21030;
  int D.21031;
  int array_size.8;
  unsigned int array_size.9;
  unsigned int D.21037;
  unsigned int D.21038;
  int array_size.10;
  int D.21040;
  struct MonoThreadsSync * D.21041;
  int D.21042;
  struct MonoThreadsSync * monitor_freelist.11;
  struct MonitorArray * monitor_allocated.12;
  struct MonitorArray * D.21048;
  void * monitor_freelist.13;
  struct MonoPerfCounters * mono_perfcounters.14;
  unsigned int D.21051;
  unsigned int D.21052;
  struct MonoThreadsSync * D.21053;
  struct MonoThreadsSync * new;

  monitor_freelist.7 = monitor_freelist;
  if (monitor_freelist.7 == 0B) goto <D.21020>; else goto <D.21021>;
  <D.21020>:
  {
    struct MonitorArray * marray;
    int i;

    new = 0B;
    marray = monitor_allocated;
    goto <D.20522>;
    <D.20521>:
    i = 0;
    goto <D.20518>;
    <D.20517>:
    D.21022 = marray->monitors[i].data;
    if (D.21022 == 0B) goto <D.21023>; else goto <D.21024>;
    <D.21023>:
    new = &marray->monitors[i];
    D.21025 = new->wait_list;
    if (D.21025 != 0B) goto <D.21026>; else goto <D.21027>;
    <D.21026>:
    goto <D.20515>;
    <D.20514>:
    D.21025 = new->wait_list;
    D.21028 = D.21025->data;
    CloseHandle (D.21028);
    D.21025 = new->wait_list;
    D.21025 = new->wait_list;
    D.21028 = D.21025->data;
    D.21029 = monoeg_g_slist_remove (D.21025, D.21028);
    new->wait_list = D.21029;
    <D.20515>:
    D.21025 = new->wait_list;
    if (D.21025 != 0B) goto <D.20514>; else goto <D.20516>;
    <D.20516>:
    <D.21027>:
    D.21030 = &new->data;
    mono_gc_weak_link_remove (D.21030, 0);
    monitor_freelist.7 = monitor_freelist;
    new->data = monitor_freelist.7;
    monitor_freelist = new;
    <D.21024>:
    i = i + 1;
    <D.20518>:
    D.21031 = marray->num_monitors;
    if (D.21031 > i) goto <D.20517>; else goto <D.20519>;
    <D.20519>:
    if (new != 0B) goto <D.20520>; else goto <D.21032>;
    <D.21032>:
    marray = marray->next;
    <D.20522>:
    if (marray != 0B) goto <D.20521>; else goto <D.20520>;
    <D.20520>:
    monitor_freelist.7 = monitor_freelist;
    if (monitor_freelist.7 == 0B) goto <D.21033>; else goto <D.21034>;
    <D.21033>:
    {
      struct MonitorArray * last;

      array_size.8 = array_size;
      array_size.9 = (unsigned int) array_size.8;
      D.21037 = array_size.9 * 28;
      D.21038 = D.21037 + 16;
      marray = monoeg_malloc0 (D.21038);
      array_size.8 = array_size;
      marray->num_monitors = array_size.8;
      array_size.8 = array_size;
      array_size.10 = array_size.8 * 2;
      array_size = array_size.10;
      i = 0;
      goto <D.20525>;
      <D.20524>:
      D.21040 = i + 1;
      D.21041 = &marray->monitors[D.21040];
      marray->monitors[i].data = D.21041;
      i = i + 1;
      <D.20525>:
      D.21031 = marray->num_monitors;
      D.21042 = D.21031 + -1;
      if (D.21042 > i) goto <D.20524>; else goto <D.20526>;
      <D.20526>:
      marray->monitors[i].data = 0B;
      monitor_freelist.11 = &marray->monitors[0];
      monitor_freelist = monitor_freelist.11;
      monitor_allocated.12 = monitor_allocated;
      if (monitor_allocated.12 == 0B) goto <D.21045>; else goto <D.21046>;
      <D.21045>:
      monitor_allocated = marray;
      goto <D.21047>;
      <D.21046>:
      last = monitor_allocated;
      goto <D.20528>;
      <D.20527>:
      last = last->next;
      <D.20528>:
      D.21048 = last->next;
      if (D.21048 != 0B) goto <D.20527>; else goto <D.20529>;
      <D.20529>:
      last->next = marray;
      <D.21047>:
    }
    <D.21034>:
  }
  <D.21021>:
  new = monitor_freelist;
  monitor_freelist.13 = new->data;
  monitor_freelist = monitor_freelist.13;
  new->owner = id;
  new->nest = 1;
  new->data = 0B;
  mono_perfcounters.14 = mono_perfcounters;
  D.21051 = mono_perfcounters.14->gc_sync_blocks;
  D.21052 = D.21051 + 1;
  mono_perfcounters.14->gc_sync_blocks = D.21052;
  D.21053 = new;
  return D.21053;
}


mon_finalize (struct MonoThreadsSync * mon)
{
  void * D.21055;
  struct GSList * D.21058;
  _Bool D.21059;
  long int D.21060;
  long int D.21061;
  struct MonoThreadsSync * monitor_freelist.15;
  struct MonoPerfCounters * mono_perfcounters.16;
  unsigned int D.21066;
  unsigned int D.21067;

  D.21055 = mon->entry_sem;
  if (D.21055 != 0B) goto <D.21056>; else goto <D.21057>;
  <D.21056>:
  D.21055 = mon->entry_sem;
  CloseHandle (D.21055);
  mon->entry_sem = 0B;
  <D.21057>:
  D.21058 = mon->wait_list;
  D.21059 = D.21058 != 0B;
  D.21060 = (long int) D.21059;
  D.21061 = __builtin_expect (D.21060, 0);
  if (D.21061 != 0) goto <D.21062>; else goto <D.21063>;
  <D.21062>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 239, "mon->wait_list == NULL");
  <D.21063>:
  mon->entry_count = 0;
  monitor_freelist.15 = monitor_freelist;
  mon->data = monitor_freelist.15;
  monitor_freelist = mon;
  mono_perfcounters.16 = mono_perfcounters;
  D.21066 = mono_perfcounters.16->gc_sync_blocks;
  D.21067 = D.21066 + 4294967295;
  mono_perfcounters.16->gc_sync_blocks = D.21067;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.21068;
  unsigned int D.21069;

  D.21069 = __sync_add_and_fetch_4 (val, 1);
  D.21068 = (gint32) D.21069;
  return D.21068;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.21071;
  unsigned int D.21072;

  D.21072 = __sync_sub_and_fetch_4 (val, 1);
  D.21071 = (gint32) D.21072;
  return D.21071;
}


mono_monitor_try_enter (struct MonoObject * obj, guint32 ms)
{
  mono_bool D.21074;
  int D.21075;
  _Bool D.21076;

  D.21075 = mono_monitor_try_enter_internal (obj, ms, 0);
  D.21076 = D.21075 == 1;
  D.21074 = (mono_bool) D.21076;
  return D.21074;
}


mono_monitor_exit (struct MonoObject * obj)
{
  _Bool D.21078;
  long int D.21079;
  long int D.21080;
  struct MonoException * D.21083;
  unsigned int D.21084;
  unsigned int D.21085;
  unsigned int D.21088;
  _Bool D.21089;
  long int D.21090;
  long int D.21091;
  unsigned int D.21094;
  unsigned int tls_pthread_self.17;
  _Bool D.21096;
  long int D.21097;
  long int D.21098;
  unsigned int D.21101;
  int D.21104;
  void * D.21107;
  struct MonoThreadsSync * mon;
  guint32 nest;

  D.21078 = obj == 0B;
  D.21079 = (long int) D.21078;
  D.21080 = __builtin_expect (D.21079, 0);
  if (D.21080 != 0) goto <D.21081>; else goto <D.21082>;
  <D.21081>:
  D.21083 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.21083);
  return;
  <D.21082>:
  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.21084 = lw.lock_word;
        D.21085 = D.21084 & 1;
        if (D.21085 != 0) goto <D.21086>; else goto <D.21087>;
        <D.21086>:
        return;
        <D.21087>:
        D.21084 = lw.lock_word;
        D.21088 = D.21084 & 4294967292;
        lw.lock_word = D.21088;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.21089 = mon == 0B;
  D.21090 = (long int) D.21089;
  D.21091 = __builtin_expect (D.21090, 0);
  if (D.21091 != 0) goto <D.21092>; else goto <D.21093>;
  <D.21092>:
  return;
  <D.21093>:
  D.21094 = mon->owner;
  tls_pthread_self.17 = tls_pthread_self;
  D.21096 = D.21094 != tls_pthread_self.17;
  D.21097 = (long int) D.21096;
  D.21098 = __builtin_expect (D.21097, 0);
  if (D.21098 != 0) goto <D.21099>; else goto <D.21100>;
  <D.21099>:
  return;
  <D.21100>:
  D.21101 = mon->nest;
  nest = D.21101 + 4294967295;
  if (nest == 0) goto <D.21102>; else goto <D.21103>;
  <D.21102>:
  mon->owner = 0;
  D.21104 = mon->entry_count;
  if (D.21104 > 0) goto <D.21105>; else goto <D.21106>;
  <D.21105>:
  D.21107 = mon->entry_sem;
  ReleaseSemaphore (D.21107, 1, 0B);
  <D.21106>:
  goto <D.21108>;
  <D.21103>:
  mon->nest = nest;
  <D.21108>:
}


mono_monitor_get_object_monitor_weak_link (struct MonoObject * object)
{
  struct MonoThreadsSync * D.21112;
  unsigned int D.21113;
  unsigned int D.21114;
  unsigned int D.21117;
  unsigned int D.21119;
  void * D.21124;
  void * * D.21127;
  union LockWord lw;
  struct MonoThreadsSync * sync;

  try
    {
      sync = 0B;
      D.21112 = object->synchronisation;
      lw.sync = D.21112;
      D.21113 = lw.lock_word;
      D.21114 = D.21113 & 2;
      if (D.21114 != 0) goto <D.21115>; else goto <D.21116>;
      <D.21115>:
      D.21113 = lw.lock_word;
      D.21117 = D.21113 & 4294967292;
      lw.lock_word = D.21117;
      sync = lw.sync;
      goto <D.21118>;
      <D.21116>:
      D.21113 = lw.lock_word;
      D.21119 = D.21113 & 1;
      if (D.21119 == 0) goto <D.21120>; else goto <D.21121>;
      <D.21120>:
      sync = lw.sync;
      <D.21121>:
      <D.21118>:
      if (sync != 0B) goto <D.21122>; else goto <D.21123>;
      <D.21122>:
      D.21124 = sync->data;
      if (D.21124 != 0B) goto <D.21125>; else goto <D.21126>;
      <D.21125>:
      D.21127 = &sync->data;
      return D.21127;
      <D.21126>:
      <D.21123>:
      D.21127 = 0B;
      return D.21127;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


mono_monitor_is_il_fastpath_wrapper (struct MonoMethod * method)
{
  struct MonoMethod * D.21130;
  gboolean D.21133;
  int i;

  i = 0;
  goto <D.20607>;
  <D.20606>:
  D.21130 = monitor_il_fastpaths[i];
  if (D.21130 == method) goto <D.21131>; else goto <D.21132>;
  <D.21131>:
  D.21133 = 1;
  return D.21133;
  <D.21132>:
  i = i + 1;
  <D.20607>:
  if (i <= 2) goto <D.20606>; else goto <D.20608>;
  <D.20608>:
  D.21133 = 0;
  return D.21133;
}


mono_monitor_get_fast_path (struct MonoMethod * enter_or_exit)
{
  int D.20664;
  int iftmp.18;
  int D.20663;
  const char[6] * D.21138;
  unsigned char D.21139;
  int D.21140;
  unsigned char D.21141;
  int D.21142;
  _Bool D.21143;
  _Bool D.21144;
  _Bool D.21145;
  const unsigned char * D.21148;
  unsigned char D.21149;
  int D.21150;
  const unsigned char * D.21151;
  unsigned char D.21152;
  int D.21153;
  _Bool D.21154;
  _Bool D.21155;
  const unsigned char * D.21158;
  unsigned char D.21159;
  int D.21160;
  const unsigned char * D.21161;
  unsigned char D.21162;
  int D.21163;
  _Bool D.21164;
  _Bool D.21165;
  const unsigned char * D.21168;
  unsigned char D.21169;
  int D.21170;
  const unsigned char * D.21171;
  unsigned char D.21172;
  int D.21173;
  const char * D.21175;
  struct MonoMethod * D.21178;
  int D.20673;
  int iftmp.19;
  int D.20672;
  const char[5] * D.21182;
  unsigned char D.21183;
  int D.21184;
  unsigned char D.21185;
  int D.21186;
  _Bool D.21187;
  _Bool D.21188;
  _Bool D.21189;
  const unsigned char * D.21192;
  unsigned char D.21193;
  int D.21194;
  const unsigned char * D.21195;
  unsigned char D.21196;
  int D.21197;
  _Bool D.21198;
  _Bool D.21199;
  const unsigned char * D.21202;
  unsigned char D.21203;
  int D.21204;
  const unsigned char * D.21205;
  unsigned char D.21206;
  int D.21207;
  _Bool D.21208;
  _Bool D.21209;
  const unsigned char * D.21212;
  unsigned char D.21213;
  int D.21214;
  const unsigned char * D.21215;
  unsigned char D.21216;
  int D.21217;

  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 5;
    if (__s2_len <= 3) goto <D.21136>; else goto <D.21137>;
    <D.21136>:
    {
      const unsigned char * __s2;
      int __result;

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

    __s2_len = 4;
    if (__s2_len <= 3) goto <D.21180>; else goto <D.21181>;
    <D.21180>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = enter_or_exit->name;
      D.21182 = "Exit";
      D.21183 = MEM[(const unsigned char *)D.21182];
      D.21184 = (int) D.21183;
      D.21185 = *__s2;
      D.21186 = (int) D.21185;
      __result = D.21184 - D.21186;
      {
        D.21187 = __s2_len != 0;
        D.21188 = __result == 0;
        D.21189 = D.21187 & D.21188;
        if (D.21189 != 0) goto <D.21190>; else goto <D.21191>;
        <D.21190>:
        D.21192 = &MEM[(void *)"Exit" + 1B];
        D.21193 = *D.21192;
        D.21194 = (int) D.21193;
        D.21195 = __s2 + 1;
        D.21196 = *D.21195;
        D.21197 = (int) D.21196;
        __result = D.21194 - D.21197;
        D.21198 = __s2_len > 1;
        D.21188 = __result == 0;
        D.21199 = D.21198 & D.21188;
        if (D.21199 != 0) goto <D.21200>; else goto <D.21201>;
        <D.21200>:
        D.21202 = &MEM[(void *)"Exit" + 2B];
        D.21203 = *D.21202;
        D.21204 = (int) D.21203;
        D.21205 = __s2 + 2;
        D.21206 = *D.21205;
        D.21207 = (int) D.21206;
        __result = D.21204 - D.21207;
        D.21208 = __s2_len > 2;
        D.21188 = __result == 0;
        D.21209 = D.21208 & D.21188;
        if (D.21209 != 0) goto <D.21210>; else goto <D.21211>;
        <D.21210>:
        D.21212 = &MEM[(void *)"Exit" + 3B];
        D.21213 = *D.21212;
        D.21214 = (int) D.21213;
        D.21215 = __s2 + 3;
        D.21216 = *D.21215;
        D.21217 = (int) D.21216;
        __result = D.21214 - D.21217;
        <D.21211>:
        <D.21201>:
        <D.21191>:
      }
      D.20672 = __result;
    }
    iftmp.19 = -D.20672;
    goto <D.21218>;
    <D.21181>:
    D.21175 = enter_or_exit->name;
    iftmp.19 = __builtin_strcmp (D.21175, "Exit");
    <D.21218>:
    D.20673 = iftmp.19;
  }
  if (D.20673 == 0) goto <D.21219>; else goto <D.21220>;
  <D.21219>:
  D.21178 = mono_monitor_get_fast_exit_method (enter_or_exit);
  return D.21178;
  <D.21220>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "monitor.c", 1227);
  D.21178 = 0B;
  return D.21178;
}


mono_monitor_get_fast_enter_method (struct MonoMethod * monitor_enter_method)
{
  struct MonoMethodSignature * D.21222;
  short unsigned int D.21223;
  _Bool D.21224;
  _Bool D.21225;
  _Bool D.21226;
  long int D.21227;
  long int D.21228;
  struct MonoMethod * D.21233;
  struct MonoMethod * D.21234;
  struct MonoMethod * compare_exchange_method.20;
  struct MonoImage * D.21240;
  struct MonoMethod * compare_exchange_method.21;
  struct MonoClass * D.21244;
  const char * iftmp.22;
  struct MonoMethod * D.21249;
  struct MonoClass * D.21250;
  struct MonoType * D.21251;
  int * iftmp.23;
  unsigned int tid_loc.24;
  unsigned int syncp_loc.25;
  unsigned int owner_loc.26;
  unsigned int D.21259;
  unsigned int D.21260;
  unsigned int tid_branch.27;
  unsigned int D.21264;
  int thin_hash_branch.28;
  unsigned int thin_hash_branch.29;
  int obj_null_branch.30;
  unsigned int obj_null_branch.31;
  int syncp_null_branch.32;
  unsigned int syncp_null_branch.33;
  unsigned int has_owner_branch.34;
  unsigned int other_owner_branch.35;
  int true_locktaken_branch.36;
  unsigned int true_locktaken_branch.37;
  struct MonoMethodSignature * D.21283;
  struct MonoMethod * D.21284;
  WrapperSubtype iftmp.38;
  struct MonoMethodBuilder * mb;
  struct MonoMethod * res;
  static struct MonoMethod * compare_exchange_method;
  int obj_null_branch;
  int true_locktaken_branch;
  int syncp_null_branch;
  int has_owner_branch;
  int other_owner_branch;
  int tid_branch;
  int thin_hash_branch;
  int tid_loc;
  int syncp_loc;
  int owner_loc;
  int thread_tls_offset;
  gboolean is_v4;
  int fast_path_idx;
  struct WrapperInfo * info;

  try
    {
      true_locktaken_branch = 0;
      D.21222 = mono_method_signature (monitor_enter_method);
      D.21223 = D.21222->param_count;
      D.21224 = D.21223 == 2;
      is_v4 = (gboolean) D.21224;
      D.21225 = is_v4 != 0;
      fast_path_idx = (int) D.21225;
      D.21226 = is_v4 == 0;
      D.21227 = (long int) D.21226;
      D.21228 = __builtin_expect (D.21227, 0);
      if (D.21228 != 0) goto <D.21229>; else goto <D.21230>;
      <D.21229>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 898, "is_v4");
      <D.21230>:
      thread_tls_offset = mono_thread_get_tls_offset ();
      if (thread_tls_offset == -1) goto <D.21231>; else goto <D.21232>;
      <D.21231>:
      D.21233 = 0B;
      return D.21233;
      <D.21232>:
      D.21234 = monitor_il_fastpaths[fast_path_idx];
      if (D.21234 != 0B) goto <D.21235>; else goto <D.21236>;
      <D.21235>:
      D.21233 = monitor_il_fastpaths[fast_path_idx];
      return D.21233;
      <D.21236>:
      compare_exchange_method.20 = compare_exchange_method;
      if (compare_exchange_method.20 == 0B) goto <D.21238>; else goto <D.21239>;
      <D.21238>:
      {
        struct MonoMethodDesc * desc;
        struct MonoClass * class;

        desc = mono_method_desc_new ("Interlocked:CompareExchange(intptr&,intptr,intptr)", 0);
        D.21240 = mono_defaults.corlib;
        class = mono_class_from_name (D.21240, "System.Threading", "Interlocked");
        compare_exchange_method.21 = mono_method_desc_search_in_class (desc, class);
        compare_exchange_method = compare_exchange_method.21;
        mono_method_desc_free (desc);
        compare_exchange_method.20 = compare_exchange_method;
        if (compare_exchange_method.20 == 0B) goto <D.21242>; else goto <D.21243>;
        <D.21242>:
        D.21233 = 0B;
        return D.21233;
        <D.21243>:
      }
      <D.21239>:
      D.21244 = mono_defaults.monitor_class;
      if (is_v4 != 0) goto <D.21246>; else goto <D.21247>;
      <D.21246>:
      iftmp.22 = "FastMonitorEnterV4";
      goto <D.21248>;
      <D.21247>:
      iftmp.22 = "FastMonitorEnter";
      <D.21248>:
      mb = mono_mb_new (D.21244, iftmp.22, 25);
      D.21249 = mb->method;
      D.21249->slot = -1;
      D.21249 = mb->method;
      D.21249->flags = 182;
      D.21250 = mono_defaults.int_class;
      D.21251 = &D.21250->byval_arg;
      tid_loc = mono_mb_add_local (mb, D.21251);
      D.21250 = mono_defaults.int_class;
      D.21251 = &D.21250->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.21251);
      D.21250 = mono_defaults.int_class;
      D.21251 = &D.21250->byval_arg;
      owner_loc = mono_mb_add_local (mb, D.21251);
      if (is_v4 != 0) goto <D.21253>; else goto <D.21254>;
      <D.21253>:
      iftmp.23 = &true_locktaken_branch;
      goto <D.21255>;
      <D.21254>:
      iftmp.23 = 0B;
      <D.21255>:
      emit_obj_syncp_check (mb, syncp_loc, &obj_null_branch, iftmp.23, &syncp_null_branch, &thin_hash_branch, 0);
      mono_mb_emit_byte (mb, 240);
      mono_mb_emit_byte (mb, 13);
      mono_mb_emit_i4 (mb, 0);
      mono_mb_emit_icon (mb, 40);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      tid_loc.24 = (unsigned int) tid_loc;
      mono_mb_emit_stloc (mb, tid_loc.24);
      syncp_loc.25 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.25);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      owner_loc.26 = (unsigned int) owner_loc;
      mono_mb_emit_stloc (mb, owner_loc.26);
      owner_loc.26 = (unsigned int) owner_loc;
      mono_mb_emit_ldloc (mb, owner_loc.26);
      D.21259 = mono_mb_emit_short_branch (mb, 45);
      tid_branch = (int) D.21259;
      syncp_loc.25 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.25);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      tid_loc.24 = (unsigned int) tid_loc;
      mono_mb_emit_ldloc (mb, tid_loc.24);
      mono_mb_emit_byte (mb, 22);
      compare_exchange_method.20 = compare_exchange_method;
      mono_mb_emit_managed_call (mb, compare_exchange_method.20, 0B);
      D.21260 = mono_mb_emit_short_branch (mb, 45);
      has_owner_branch = (int) D.21260;
      if (is_v4 != 0) goto <D.21261>; else goto <D.21262>;
      <D.21261>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.21262>:
      mono_mb_emit_byte (mb, 42);
      tid_branch.27 = (unsigned int) tid_branch;
      mono_mb_patch_short_branch (mb, tid_branch.27);
      owner_loc.26 = (unsigned int) owner_loc;
      mono_mb_emit_ldloc (mb, owner_loc.26);
      tid_loc.24 = (unsigned int) tid_loc;
      mono_mb_emit_ldloc (mb, tid_loc.24);
      D.21264 = mono_mb_emit_short_branch (mb, 51);
      other_owner_branch = (int) D.21264;
      syncp_loc.25 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.25);
      mono_mb_emit_icon (mb, 4);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 37);
      mono_mb_emit_byte (mb, 74);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 84);
      if (is_v4 != 0) goto <D.21265>; else goto <D.21266>;
      <D.21265>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.21266>:
      mono_mb_emit_byte (mb, 42);
      thin_hash_branch.28 = thin_hash_branch;
      if (thin_hash_branch.28 != 0) goto <D.21268>; else goto <D.21269>;
      <D.21268>:
      thin_hash_branch.28 = thin_hash_branch;
      thin_hash_branch.29 = (unsigned int) thin_hash_branch.28;
      mono_mb_patch_short_branch (mb, thin_hash_branch.29);
      <D.21269>:
      obj_null_branch.30 = obj_null_branch;
      obj_null_branch.31 = (unsigned int) obj_null_branch.30;
      mono_mb_patch_short_branch (mb, obj_null_branch.31);
      syncp_null_branch.32 = syncp_null_branch;
      syncp_null_branch.33 = (unsigned int) syncp_null_branch.32;
      mono_mb_patch_short_branch (mb, syncp_null_branch.33);
      has_owner_branch.34 = (unsigned int) has_owner_branch;
      mono_mb_patch_short_branch (mb, has_owner_branch.34);
      other_owner_branch.35 = (unsigned int) other_owner_branch;
      mono_mb_patch_short_branch (mb, other_owner_branch.35);
      true_locktaken_branch.36 = true_locktaken_branch;
      if (true_locktaken_branch.36 != 0) goto <D.21278>; else goto <D.21279>;
      <D.21278>:
      true_locktaken_branch.36 = true_locktaken_branch;
      true_locktaken_branch.37 = (unsigned int) true_locktaken_branch.36;
      mono_mb_patch_short_branch (mb, true_locktaken_branch.37);
      <D.21279>:
      mono_mb_emit_byte (mb, 2);
      if (is_v4 != 0) goto <D.21281>; else goto <D.21282>;
      <D.21281>:
      mono_mb_emit_byte (mb, 3);
      <D.21282>:
      mono_mb_emit_managed_call (mb, monitor_enter_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.21283 = mono_signature_no_pinvoke (monitor_enter_method);
      D.21284 = mono_mb_create_method (mb, D.21283, 5);
      res = register_fastpath (D.21284, fast_path_idx);
      D.21240 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.21240, 12);
      if (is_v4 != 0) goto <D.21286>; else goto <D.21287>;
      <D.21286>:
      iftmp.38 = 5;
      goto <D.21288>;
      <D.21287>:
      iftmp.38 = 4;
      <D.21288>:
      info->subtype = iftmp.38;
      mono_marshal_set_wrapper_info (res, info);
      mono_mb_free (mb);
      D.21233 = res;
      return D.21233;
    }
  finally
    {
      obj_null_branch = {CLOBBER};
      true_locktaken_branch = {CLOBBER};
      syncp_null_branch = {CLOBBER};
      thin_hash_branch = {CLOBBER};
    }
}


emit_obj_syncp_check (struct MonoMethodBuilder * mb, int syncp_loc, int * obj_null_branch, int * true_locktaken_branch, int * syncp_true_false_branch, int * thin_hash_branch, gboolean branch_on_true)
{
  unsigned int D.21291;
  int D.21292;
  unsigned int D.21295;
  int D.21296;
  unsigned int syncp_loc.39;
  int D.21298;
  unsigned int D.21301;
  int D.21302;
  guint8 iftmp.40;
  unsigned int D.21308;
  int D.21309;

  mono_mb_emit_byte (mb, 2);
  D.21291 = mono_mb_emit_short_branch (mb, 44);
  D.21292 = (int) D.21291;
  *obj_null_branch = D.21292;
  if (true_locktaken_branch != 0B) goto <D.21293>; else goto <D.21294>;
  <D.21293>:
  mono_mb_emit_byte (mb, 3);
  mono_mb_emit_byte (mb, 70);
  D.21295 = mono_mb_emit_short_branch (mb, 45);
  D.21296 = (int) D.21295;
  *true_locktaken_branch = D.21296;
  <D.21294>:
  mono_mb_emit_byte (mb, 2);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_icon (mb, 4);
  mono_mb_emit_byte (mb, 88);
  mono_mb_emit_byte (mb, 77);
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_stloc (mb, syncp_loc.39);
  D.21298 = mono_gc_is_moving ();
  if (D.21298 != 0) goto <D.21299>; else goto <D.21300>;
  <D.21299>:
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.39);
  mono_mb_emit_icon (mb, 1);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_byte (mb, 95);
  D.21301 = mono_mb_emit_short_branch (mb, 45);
  D.21302 = (int) D.21301;
  *thin_hash_branch = D.21302;
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.39);
  mono_mb_emit_icon (mb, -4);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_byte (mb, 95);
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_stloc (mb, syncp_loc.39);
  goto <D.21303>;
  <D.21300>:
  *thin_hash_branch = 0;
  <D.21303>:
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.39);
  if (branch_on_true != 0) goto <D.21305>; else goto <D.21306>;
  <D.21305>:
  iftmp.40 = 45;
  goto <D.21307>;
  <D.21306>:
  iftmp.40 = 44;
  <D.21307>:
  D.21308 = mono_mb_emit_short_branch (mb, iftmp.40);
  D.21309 = (int) D.21308;
  *syncp_true_false_branch = D.21309;
}


register_fastpath (struct MonoMethod * method, int idx)
{
  struct MonoMethod * D.21310;

  mono_memory_barrier ();
  monitor_il_fastpaths[idx] = method;
  D.21310 = method;
  return D.21310;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_monitor_get_fast_exit_method (struct MonoMethod * monitor_exit_method)
{
  struct MonoMethod * D.21314;
  struct MonoMethod * D.21315;
  struct MonoClass * D.21318;
  struct MonoMethod * D.21319;
  struct MonoClass * D.21320;
  struct MonoType * D.21321;
  int has_syncp_branch.41;
  unsigned int has_syncp_branch.42;
  unsigned int syncp_loc.43;
  unsigned int D.21325;
  unsigned int owned_branch.44;
  unsigned int D.21327;
  unsigned int D.21328;
  unsigned int nested_branch.45;
  int thin_hash_branch.46;
  unsigned int thin_hash_branch.47;
  int obj_null_branch.48;
  unsigned int obj_null_branch.49;
  unsigned int has_waiting_branch.50;
  struct MonoMethodSignature * D.21337;
  struct MonoMethod * D.21338;
  struct MonoImage * D.21339;
  struct MonoMethodBuilder * mb;
  struct MonoMethod * res;
  int obj_null_branch;
  int has_waiting_branch;
  int has_syncp_branch;
  int owned_branch;
  int nested_branch;
  int thin_hash_branch;
  int thread_tls_offset;
  int syncp_loc;
  struct WrapperInfo * info;

  try
    {
      thread_tls_offset = mono_thread_get_tls_offset ();
      if (thread_tls_offset == -1) goto <D.21312>; else goto <D.21313>;
      <D.21312>:
      D.21314 = 0B;
      return D.21314;
      <D.21313>:
      D.21315 = monitor_il_fastpaths[2];
      if (D.21315 != 0B) goto <D.21316>; else goto <D.21317>;
      <D.21316>:
      D.21314 = monitor_il_fastpaths[2];
      return D.21314;
      <D.21317>:
      D.21318 = mono_defaults.monitor_class;
      mb = mono_mb_new (D.21318, "FastMonitorExit", 25);
      D.21319 = mb->method;
      D.21319->slot = -1;
      D.21319 = mb->method;
      D.21319->flags = 182;
      D.21320 = mono_defaults.int_class;
      D.21321 = &D.21320->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.21321);
      emit_obj_syncp_check (mb, syncp_loc, &obj_null_branch, 0B, &has_syncp_branch, &thin_hash_branch, 1);
      mono_mb_emit_byte (mb, 42);
      has_syncp_branch.41 = has_syncp_branch;
      has_syncp_branch.42 = (unsigned int) has_syncp_branch.41;
      mono_mb_patch_short_branch (mb, has_syncp_branch.42);
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      mono_mb_emit_byte (mb, 240);
      mono_mb_emit_byte (mb, 13);
      mono_mb_emit_i4 (mb, 0);
      mono_mb_emit_icon (mb, 40);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      D.21325 = mono_mb_emit_short_branch (mb, 46);
      owned_branch = (int) D.21325;
      mono_mb_emit_byte (mb, 42);
      owned_branch.44 = (unsigned int) owned_branch;
      mono_mb_patch_short_branch (mb, owned_branch.44);
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      mono_mb_emit_icon (mb, 4);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 37);
      mono_mb_emit_byte (mb, 74);
      mono_mb_emit_byte (mb, 37);
      mono_mb_emit_byte (mb, 23);
      D.21327 = mono_mb_emit_short_branch (mb, 53);
      nested_branch = (int) D.21327;
      mono_mb_emit_byte (mb, 38);
      mono_mb_emit_byte (mb, 38);
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      mono_mb_emit_icon (mb, 12);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 74);
      D.21328 = mono_mb_emit_short_branch (mb, 45);
      has_waiting_branch = (int) D.21328;
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 20);
      mono_mb_emit_byte (mb, 223);
      mono_mb_emit_byte (mb, 42);
      nested_branch.45 = (unsigned int) nested_branch;
      mono_mb_patch_short_branch (mb, nested_branch.45);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 89);
      mono_mb_emit_byte (mb, 84);
      mono_mb_emit_byte (mb, 42);
      thin_hash_branch.46 = thin_hash_branch;
      if (thin_hash_branch.46 != 0) goto <D.21331>; else goto <D.21332>;
      <D.21331>:
      thin_hash_branch.46 = thin_hash_branch;
      thin_hash_branch.47 = (unsigned int) thin_hash_branch.46;
      mono_mb_patch_short_branch (mb, thin_hash_branch.47);
      <D.21332>:
      obj_null_branch.48 = obj_null_branch;
      obj_null_branch.49 = (unsigned int) obj_null_branch.48;
      mono_mb_patch_short_branch (mb, obj_null_branch.49);
      has_waiting_branch.50 = (unsigned int) has_waiting_branch;
      mono_mb_patch_short_branch (mb, has_waiting_branch.50);
      mono_mb_emit_byte (mb, 2);
      mono_mb_emit_managed_call (mb, monitor_exit_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.21337 = mono_signature_no_pinvoke (monitor_exit_method);
      D.21338 = mono_mb_create_method (mb, D.21337, 5);
      res = register_fastpath (D.21338, 2);
      mono_mb_free (mb);
      D.21339 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.21339, 12);
      info->subtype = 6;
      mono_marshal_set_wrapper_info (res, info);
      D.21314 = res;
      return D.21314;
    }
  finally
    {
      obj_null_branch = {CLOBBER};
      has_syncp_branch = {CLOBBER};
      thin_hash_branch = {CLOBBER};
    }
}


mono_monitor_threads_sync_members_offset (int * owner_offset, int * nest_offset, int * entry_count_offset)
{
  struct MonoThreadsSync ts;

  try
    {
      *owner_offset = 4;
      *nest_offset = 1028;
      *entry_count_offset = 3076;
    }
  finally
    {
      ts = {CLOBBER};
    }
}


ves_icall_System_Threading_Monitor_Monitor_try_enter (struct MonoObject * obj, guint32 ms)
{
  gboolean D.21344;
  _Bool D.21345;
  gint32 res;

  <D.20685>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.21342>; else goto <D.21343>;
  <D.21342>:
  mono_thread_interruption_checkpoint ();
  <D.21343>:
  if (res == -1) goto <D.20685>; else goto <D.20686>;
  <D.20686>:
  D.21345 = res == 1;
  D.21344 = (gboolean) D.21345;
  return D.21344;
}


ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (struct MonoObject * obj, guint32 ms, char * lockTaken)
{
  _Bool D.21349;
  char D.21350;
  gint32 res;

  <D.20693>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.21347>; else goto <D.21348>;
  <D.21347>:
  mono_thread_interruption_checkpoint ();
  <D.21348>:
  if (res == -1) goto <D.20693>; else goto <D.20694>;
  <D.20694>:
  D.21349 = res == 1;
  D.21350 = (char) D.21349;
  *lockTaken = D.21350;
}


ves_icall_System_Threading_Monitor_Monitor_test_owner (struct MonoObject * obj)
{
  unsigned int D.21351;
  unsigned int D.21352;
  gboolean D.21355;
  unsigned int D.21356;
  unsigned int D.21359;
  unsigned int tls_pthread_self.51;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.21351 = lw.lock_word;
        D.21352 = D.21351 & 1;
        if (D.21352 != 0) goto <D.21353>; else goto <D.21354>;
        <D.21353>:
        D.21355 = 0;
        return D.21355;
        <D.21354>:
        D.21351 = lw.lock_word;
        D.21356 = D.21351 & 4294967292;
        lw.lock_word = D.21356;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.21357>; else goto <D.21358>;
  <D.21357>:
  D.21355 = 0;
  return D.21355;
  <D.21358>:
  D.21359 = mon->owner;
  tls_pthread_self.51 = tls_pthread_self;
  if (D.21359 == tls_pthread_self.51) goto <D.21361>; else goto <D.21362>;
  <D.21361>:
  D.21355 = 1;
  return D.21355;
  <D.21362>:
  D.21355 = 0;
  return D.21355;
}


ves_icall_System_Threading_Monitor_Monitor_test_synchronised (struct MonoObject * obj)
{
  unsigned int D.21366;
  unsigned int D.21367;
  gboolean D.21370;
  unsigned int D.21371;
  unsigned int D.21374;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.21366 = lw.lock_word;
        D.21367 = D.21366 & 1;
        if (D.21367 != 0) goto <D.21368>; else goto <D.21369>;
        <D.21368>:
        D.21370 = 0;
        return D.21370;
        <D.21369>:
        D.21366 = lw.lock_word;
        D.21371 = D.21366 & 4294967292;
        lw.lock_word = D.21371;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.21372>; else goto <D.21373>;
  <D.21372>:
  D.21370 = 0;
  return D.21370;
  <D.21373>:
  D.21374 = mon->owner;
  if (D.21374 != 0) goto <D.21375>; else goto <D.21376>;
  <D.21375>:
  D.21370 = 1;
  return D.21370;
  <D.21376>:
  D.21370 = 0;
  return D.21370;
}


ves_icall_System_Threading_Monitor_Monitor_pulse (struct MonoObject * obj)
{
  unsigned int D.21380;
  unsigned int D.21381;
  struct MonoException * D.21384;
  unsigned int D.21385;
  struct MonoException * D.21388;
  unsigned int D.21389;
  unsigned int tls_pthread_self.52;
  struct MonoException * D.21393;
  struct GSList * D.21394;
  void * D.21397;
  struct GSList * D.21398;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.21380 = lw.lock_word;
        D.21381 = D.21380 & 1;
        if (D.21381 != 0) goto <D.21382>; else goto <D.21383>;
        <D.21382>:
        D.21384 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.21384);
        return;
        <D.21383>:
        D.21380 = lw.lock_word;
        D.21385 = D.21380 & 4294967292;
        lw.lock_word = D.21385;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.21386>; else goto <D.21387>;
  <D.21386>:
  D.21388 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.21388);
  return;
  <D.21387>:
  D.21389 = mon->owner;
  tls_pthread_self.52 = tls_pthread_self;
  if (D.21389 != tls_pthread_self.52) goto <D.21391>; else goto <D.21392>;
  <D.21391>:
  D.21393 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.21393);
  return;
  <D.21392>:
  D.21394 = mon->wait_list;
  if (D.21394 != 0B) goto <D.21395>; else goto <D.21396>;
  <D.21395>:
  D.21394 = mon->wait_list;
  D.21397 = D.21394->data;
  SetEvent (D.21397);
  D.21394 = mon->wait_list;
  D.21394 = mon->wait_list;
  D.21397 = D.21394->data;
  D.21398 = monoeg_g_slist_remove (D.21394, D.21397);
  mon->wait_list = D.21398;
  <D.21396>:
}


ves_icall_System_Threading_Monitor_Monitor_pulse_all (struct MonoObject * obj)
{
  unsigned int D.21402;
  unsigned int D.21403;
  struct MonoException * D.21406;
  unsigned int D.21407;
  struct MonoException * D.21410;
  unsigned int D.21411;
  unsigned int tls_pthread_self.53;
  struct MonoException * D.21415;
  struct GSList * D.21416;
  void * D.21417;
  struct GSList * D.21418;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.21402 = lw.lock_word;
        D.21403 = D.21402 & 1;
        if (D.21403 != 0) goto <D.21404>; else goto <D.21405>;
        <D.21404>:
        D.21406 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.21406);
        return;
        <D.21405>:
        D.21402 = lw.lock_word;
        D.21407 = D.21402 & 4294967292;
        lw.lock_word = D.21407;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.21408>; else goto <D.21409>;
  <D.21408>:
  D.21410 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.21410);
  return;
  <D.21409>:
  D.21411 = mon->owner;
  tls_pthread_self.53 = tls_pthread_self;
  if (D.21411 != tls_pthread_self.53) goto <D.21413>; else goto <D.21414>;
  <D.21413>:
  D.21415 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.21415);
  return;
  <D.21414>:
  goto <D.20716>;
  <D.20715>:
  D.21416 = mon->wait_list;
  D.21417 = D.21416->data;
  SetEvent (D.21417);
  D.21416 = mon->wait_list;
  D.21416 = mon->wait_list;
  D.21417 = D.21416->data;
  D.21418 = monoeg_g_slist_remove (D.21416, D.21417);
  mon->wait_list = D.21418;
  <D.20716>:
  D.21416 = mon->wait_list;
  if (D.21416 != 0B) goto <D.20715>; else goto <D.20717>;
  <D.20717>:
}


ves_icall_System_Threading_Monitor_Monitor_wait (struct MonoObject * obj, guint32 ms)
{
  unsigned int D.21422;
  unsigned int D.21423;
  struct MonoException * D.21426;
  gboolean D.21427;
  unsigned int D.21428;
  struct MonoException * D.21431;
  unsigned int D.21432;
  unsigned int tls_pthread_self.54;
  struct MonoException * D.21436;
  struct MonoException * D.21439;
  struct GSList * D.21440;
  struct GSList * D.21441;
  int D.21442;
  struct MonoException * D.21449;
  struct GSList * D.21455;
  struct MonoThreadsSync * mon;
  void * event;
  guint32 nest;
  guint32 ret;
  gboolean success;
  gint32 regain;
  struct MonoInternalThread * thread;

  success = 0;
  thread = mono_thread_internal_current ();
  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.21422 = lw.lock_word;
        D.21423 = D.21422 & 1;
        if (D.21423 != 0) goto <D.21424>; else goto <D.21425>;
        <D.21424>:
        D.21426 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.21426);
        D.21427 = 0;
        return D.21427;
        <D.21425>:
        D.21422 = lw.lock_word;
        D.21428 = D.21422 & 4294967292;
        lw.lock_word = D.21428;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.21429>; else goto <D.21430>;
  <D.21429>:
  D.21431 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.21431);
  D.21427 = 0;
  return D.21427;
  <D.21430>:
  D.21432 = mon->owner;
  tls_pthread_self.54 = tls_pthread_self;
  if (D.21432 != tls_pthread_self.54) goto <D.21434>; else goto <D.21435>;
  <D.21434>:
  D.21436 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.21436);
  D.21427 = 0;
  return D.21427;
  <D.21435>:
  mono_thread_current_check_pending_interrupt ();
  event = CreateEvent (0B, 0, 0, 0B);
  if (event == 0B) goto <D.21437>; else goto <D.21438>;
  <D.21437>:
  D.21439 = mono_get_exception_synchronization_lock ("Failed to set up wait event");
  mono_raise_exception (D.21439);
  D.21427 = 0;
  return D.21427;
  <D.21438>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.21440 = mon->wait_list;
  D.21441 = monoeg_g_slist_append (D.21440, event);
  mon->wait_list = D.21441;
  nest = mon->nest;
  mon->nest = 1;
  mono_monitor_exit (obj);
  ret = WaitForSingleObjectEx (event, ms, 1);
  mono_thread_clr_state (thread, 32);
  D.21442 = mono_thread_interruption_requested ();
  if (D.21442 != 0) goto <D.21443>; else goto <D.21444>;
  <D.21443>:
  D.21427 = 0;
  return D.21427;
  <D.21444>:
  <D.20730>:
  regain = mono_monitor_try_enter_internal (obj, 4294967295, 1);
  if (regain == -1) goto <D.21445>; else goto <D.21446>;
  <D.21445>:
  mono_thread_interruption_checkpoint ();
  <D.21446>:
  if (regain == -1) goto <D.20730>; else goto <D.20731>;
  <D.20731>:
  if (regain == 0) goto <D.21447>; else goto <D.21448>;
  <D.21447>:
  CloseHandle (event);
  D.21449 = mono_get_exception_synchronization_lock ("Failed to regain lock");
  mono_raise_exception (D.21449);
  D.21427 = 0;
  return D.21427;
  <D.21448>:
  mon->nest = nest;
  if (ret == 258) goto <D.21450>; else goto <D.21451>;
  <D.21450>:
  ret = WaitForSingleObjectEx (event, 0, 0);
  <D.21451>:
  if (ret == 0) goto <D.21452>; else goto <D.21453>;
  <D.21452>:
  success = 1;
  goto <D.21454>;
  <D.21453>:
  D.21440 = mon->wait_list;
  D.21455 = monoeg_g_slist_remove (D.21440, event);
  mon->wait_list = D.21455;
  <D.21454>:
  CloseHandle (event);
  D.21427 = success;
  return D.21427;
}


