mono_threads_pthread_create (pthread_t * new_thread, const union pthread_attr_t * attr, void * (*<Tfeb>) (void *) start_routine, void * arg)
{
  int D.12657;
  union MonoSemType * D.12658;
  struct MonoThreadInfoCallbacks * D.12659;
  int (*<T1c3a>) (pthread_t *, const union pthread_attr_t *, void * (*<Tfeb>) (void *), void *) D.12660;
  int D.12663;
  struct ThreadStartInfo * start_info;
  int result;

  start_info = monoeg_malloc0 (56);
  if (start_info == 0B) goto <D.12655>; else goto <D.12656>;
  <D.12655>:
  D.12657 = 12;
  return D.12657;
  <D.12656>:
  D.12658 = &start_info->registered;
  sem_init (D.12658, 0, 0);
  start_info->arg = arg;
  start_info->start_routine = start_routine;
  D.12659 = mono_threads_get_callbacks ();
  D.12660 = D.12659->mono_gc_pthread_create;
  result = D.12660 (new_thread, attr, inner_start_thread, start_info);
  if (result == 0) goto <D.12661>; else goto <D.12662>;
  <D.12661>:
  goto <D.12588>;
  <D.12587>:
  <D.12588>:
  D.12658 = &start_info->registered;
  D.12663 = mono_sem_wait (D.12658, 0);
  if (D.12663 != 0) goto <D.12587>; else goto <D.12589>;
  <D.12589>:
  <D.12662>:
  D.12658 = &start_info->registered;
  sem_destroy (D.12658);
  monoeg_g_free (start_info);
  D.12657 = result;
  return D.12657;
}


inner_start_thread (void * arg)
{
  struct MonoThreadInfo * D.12665;
  union MonoSemType * D.12666;
  _Bool D.12667;
  long int D.12668;
  long int D.12669;
  void * result.0;
  struct MonoDomain * D.12673;
  _Bool D.12674;
  long int D.12675;
  long int D.12676;
  void * D.12679;
  struct ThreadStartInfo * start_info;
  void * t_arg;
  int post_result;
  void * (*<Tfeb>) (void *) start_func;
  void * result;

  try
    {
      start_info = arg;
      t_arg = start_info->arg;
      start_func = start_info->start_routine;
      D.12665 = mono_thread_info_attach (&result);
      D.12665->runtime_thread = 1;
      D.12666 = &start_info->registered;
      post_result = mono_sem_post (D.12666);
      D.12667 = post_result != 0;
      D.12668 = (long int) D.12667;
      D.12669 = __builtin_expect (D.12668, 0);
      if (D.12669 != 0) goto <D.12670>; else goto <D.12671>;
      <D.12670>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 47, "!post_result");
      <D.12671>:
      result.0 = start_func (t_arg);
      result = result.0;
      D.12673 = mono_domain_get ();
      D.12674 = D.12673 != 0B;
      D.12675 = (long int) D.12674;
      D.12676 = __builtin_expect (D.12675, 0);
      if (D.12676 != 0) goto <D.12677>; else goto <D.12678>;
      <D.12677>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 50, "!mono_domain_get ()");
      <D.12678>:
      mono_thread_info_dettach ();
      D.12679 = result;
      return D.12679;
    }
  finally
    {
      result = {CLOBBER};
    }
}


mono_threads_init_platform ()
{
  int D.12682;
  int D.12685;

  D.12682 = mono_thread_info_new_interrupt_enabled ();
  if (D.12682 != 0) goto <D.12683>; else goto <D.12684>;
  <D.12683>:
  D.12685 = mono_thread_get_abort_signal ();
  mono_posix_add_signal_handler (D.12685, suspend_signal_handler);
  <D.12684>:
}


suspend_signal_handler (int _dummy, struct siginfo_t * info, void * context)
{
  int D.12686;
  struct MonoThreadInfoRuntimeCallbacks * D.12689;
  gboolean (*<T1c47>) (struct MonoThreadUnwindState *, void *) D.12690;
  struct MonoThreadUnwindState * D.12691;
  union MonoSemType * D.12692;
  union MonoSemType * D.12695;
  int D.12696;
  void (*<Tc2>) (void *) D.12697;
  struct MonoThreadInfoRuntimeCallbacks * D.12700;
  void (*<T1c41>) (struct MonoContext *, void (*<Tc2>) (void *), void *) D.12701;
  void * D.12702;
  union MonoSemType * D.12703;
  struct MonoThreadInfo * current;
  gboolean ret;

  current = mono_thread_info_current ();
  D.12686 = current->syscall_break_signal;
  if (D.12686 != 0) goto <D.12687>; else goto <D.12688>;
  <D.12687>:
  current->syscall_break_signal = 0;
  return;
  <D.12688>:
  D.12689 = mono_threads_get_runtime_callbacks ();
  D.12690 = D.12689->thread_state_init_from_sigctx;
  D.12691 = &current->suspend_state;
  ret = D.12690 (D.12691, context);
  current->suspend_can_continue = ret;
  D.12692 = &current->begin_suspend_semaphore;
  mono_sem_post (D.12692);
  if (ret == 0) goto <D.12693>; else goto <D.12694>;
  <D.12693>:
  return;
  <D.12694>:
  goto <D.12598>;
  <D.12597>:
  <D.12598>:
  D.12695 = &current->resume_semaphore;
  D.12696 = mono_sem_wait (D.12695, 0);
  if (D.12696 != 0) goto <D.12597>; else goto <D.12599>;
  <D.12599>:
  D.12697 = current->async_target;
  if (D.12697 != 0B) goto <D.12698>; else goto <D.12699>;
  <D.12698>:
  {
    struct MonoContext tmp;

    try
      {
        tmp = current->suspend_state.ctx;
        D.12700 = mono_threads_get_runtime_callbacks ();
        D.12701 = D.12700->setup_async_callback;
        D.12702 = current->user_data;
        D.12697 = current->async_target;
        D.12701 (&tmp, D.12697, D.12702);
        current->user_data = 0B;
        current->async_target = 0B;
        mono_monoctx_to_sigctx (&tmp, context);
      }
    finally
      {
        tmp = {CLOBBER};
      }
  }
  <D.12699>:
  D.12703 = &current->finish_resume_semaphore;
  mono_sem_post (D.12703);
}


mono_posix_add_signal_handler (int signo, void * handler)
{
  void (*<T1b09>) (int, struct siginfo_t *, void *) handler.1;
  _Bool D.12706;
  long int D.12707;
  long int D.12708;
  struct sigaction sa;
  struct sigaction previous_sa;
  int ret;

  try
    {
      handler.1 = (void (*<T1b09>) (int, struct siginfo_t *, void *)) handler;
      sa.__sigaction_handler.sa_sigaction = handler.1;
      sigemptyset (&sa.sa_mask);
      sa.sa_flags = 4;
      ret = sigaction (signo, &sa, &previous_sa);
      D.12706 = ret == -1;
      D.12707 = (long int) D.12706;
      D.12708 = __builtin_expect (D.12707, 0);
      if (D.12708 != 0) goto <D.12709>; else goto <D.12710>;
      <D.12709>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 139, "ret != -1");
      <D.12710>:
    }
  finally
    {
      sa = {CLOBBER};
      previous_sa = {CLOBBER};
    }
}


mono_threads_core_interrupt (struct MonoThreadInfo * info)
{

}


mono_threads_pthread_kill (struct MonoThreadInfo * info, int signum)
{
  int D.12711;
  long unsigned int D.12712;

  D.12712 = info->node.key;
  D.12711 = pthread_kill (D.12712, signum);
  return D.12711;
}


mono_threads_core_abort_syscall (struct MonoThreadInfo * info)
{
  int D.12714;

  info->syscall_break_signal = 1;
  D.12714 = mono_thread_get_abort_signal ();
  mono_threads_pthread_kill (info, D.12714);
}


mono_threads_core_needs_abort_syscall ()
{
  gboolean D.12715;

  D.12715 = 1;
  return D.12715;
}


mono_threads_core_suspend (struct MonoThreadInfo * info)
{
  int D.12717;
  union MonoSemType * D.12718;
  int D.12719;
  gboolean D.12720;

  D.12717 = mono_thread_get_abort_signal ();
  mono_threads_pthread_kill (info, D.12717);
  goto <D.12628>;
  <D.12627>:
  <D.12628>:
  D.12718 = &info->begin_suspend_semaphore;
  D.12719 = mono_sem_wait (D.12718, 0);
  if (D.12719 != 0) goto <D.12627>; else goto <D.12629>;
  <D.12629>:
  D.12720 = info->suspend_can_continue;
  return D.12720;
}


mono_threads_core_resume (struct MonoThreadInfo * info)
{
  union MonoSemType * D.12722;
  union MonoSemType * D.12723;
  int D.12724;
  gboolean D.12725;

  D.12722 = &info->resume_semaphore;
  mono_sem_post (D.12722);
  goto <D.12634>;
  <D.12633>:
  <D.12634>:
  D.12723 = &info->finish_resume_semaphore;
  D.12724 = mono_sem_wait (D.12723, 0);
  if (D.12724 != 0) goto <D.12633>; else goto <D.12635>;
  <D.12635>:
  D.12725 = 1;
  return D.12725;
}


mono_threads_platform_register (struct MonoThreadInfo * info)
{
  union MonoSemType * D.12727;

  D.12727 = &info->begin_suspend_semaphore;
  sem_init (D.12727, 0, 0);
}


mono_threads_platform_free (struct MonoThreadInfo * info)
{
  union MonoSemType * D.12728;

  D.12728 = &info->begin_suspend_semaphore;
  sem_destroy (D.12728);
}


mono_native_thread_id_get ()
{
  MonoNativeThreadId D.12729;

  D.12729 = pthread_self ();
  return D.12729;
}


mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2)
{
  gboolean D.12731;

  D.12731 = pthread_equal (id1, id2);
  return D.12731;
}


pthread_equal (pthread_t __thread1, pthread_t __thread2)
{
  int D.12733;
  _Bool D.12734;

  D.12734 = __thread1 == __thread2;
  D.12733 = (int) D.12734;
  return D.12733;
}


mono_native_thread_create (MonoNativeThreadId * tid, void * func, void * arg)
{
  gboolean D.12736;
  void * (*<Tfeb>) (void *) func.2;
  int D.12738;
  _Bool D.12739;

  func.2 = (void * (*<Tfeb>) (void *)) func;
  D.12738 = pthread_create (tid, 0B, func.2, arg);
  D.12739 = D.12738 == 0;
  D.12736 = (gboolean) D.12739;
  return D.12736;
}


