mono_threads_pthread_create (pthread_t * new_thread, const union pthread_attr_t * attr, void * (*<T19d6>) (void *) start_routine, void * arg)
{
  int D.14844;
  union MonoSemType * D.14845;
  struct MonoThreadInfoCallbacks * D.14846;
  int (*<T25fc>) (pthread_t *, const union pthread_attr_t *, void * (*<T19d6>) (void *), void *) D.14847;
  int D.14850;
  struct ThreadStartInfo * start_info;
  int result;

  start_info = monoeg_malloc0 (28);
  if (start_info == 0B) goto <D.14842>; else goto <D.14843>;
  <D.14842>:
  D.14844 = 12;
  return D.14844;
  <D.14843>:
  D.14845 = &start_info->registered;
  sem_init (D.14845, 0, 0);
  start_info->arg = arg;
  start_info->start_routine = start_routine;
  D.14846 = mono_threads_get_callbacks ();
  D.14847 = D.14846->mono_gc_pthread_create;
  result = D.14847 (new_thread, attr, inner_start_thread, start_info);
  if (result == 0) goto <D.14848>; else goto <D.14849>;
  <D.14848>:
  goto <D.14773>;
  <D.14772>:
  <D.14773>:
  D.14845 = &start_info->registered;
  D.14850 = mono_sem_wait (D.14845, 0);
  if (D.14850 != 0) goto <D.14772>; else goto <D.14774>;
  <D.14774>:
  <D.14849>:
  D.14845 = &start_info->registered;
  sem_destroy (D.14845);
  monoeg_g_free (start_info);
  D.14844 = result;
  return D.14844;
}


inner_start_thread (void * arg)
{
  struct MonoThreadInfo * D.14852;
  union MonoSemType * D.14853;
  _Bool D.14854;
  long int D.14855;
  long int D.14856;
  void * result.0;
  struct MonoDomain * D.14860;
  _Bool D.14861;
  long int D.14862;
  long int D.14863;
  void * D.14866;
  struct ThreadStartInfo * start_info;
  void * t_arg;
  int post_result;
  void * (*<T19d6>) (void *) start_func;
  void * result;

  try
    {
      start_info = arg;
      t_arg = start_info->arg;
      start_func = start_info->start_routine;
      D.14852 = mono_thread_info_attach (&result);
      D.14852->runtime_thread = 1;
      D.14853 = &start_info->registered;
      post_result = mono_sem_post (D.14853);
      D.14854 = post_result != 0;
      D.14855 = (long int) D.14854;
      D.14856 = __builtin_expect (D.14855, 0);
      if (D.14856 != 0) goto <D.14857>; else goto <D.14858>;
      <D.14857>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 47, "!post_result");
      <D.14858>:
      result.0 = start_func (t_arg);
      result = result.0;
      D.14860 = mono_domain_get ();
      D.14861 = D.14860 != 0B;
      D.14862 = (long int) D.14861;
      D.14863 = __builtin_expect (D.14862, 0);
      if (D.14863 != 0) goto <D.14864>; else goto <D.14865>;
      <D.14864>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 50, "!mono_domain_get ()");
      <D.14865>:
      mono_thread_info_dettach ();
      D.14866 = result;
      return D.14866;
    }
  finally
    {
      result = {CLOBBER};
    }
}


mono_threads_init_platform ()
{
  int D.14869;
  int D.14872;

  D.14869 = mono_thread_info_new_interrupt_enabled ();
  if (D.14869 != 0) goto <D.14870>; else goto <D.14871>;
  <D.14870>:
  D.14872 = mono_thread_get_abort_signal ();
  mono_posix_add_signal_handler (D.14872, suspend_signal_handler);
  <D.14871>:
}


suspend_signal_handler (int _dummy, struct siginfo_t * info, void * context)
{
  int D.14873;
  struct MonoThreadInfoRuntimeCallbacks * D.14876;
  gboolean (*<T2609>) (struct MonoThreadUnwindState *, void *) D.14877;
  struct MonoThreadUnwindState * D.14878;
  union MonoSemType * D.14879;
  union MonoSemType * D.14882;
  int D.14883;
  void (*<Tc1>) (void *) D.14884;
  union MonoSemType * D.14887;
  struct MonoThreadInfo * current;
  gboolean ret;

  current = mono_thread_info_current ();
  D.14873 = current->syscall_break_signal;
  if (D.14873 != 0) goto <D.14874>; else goto <D.14875>;
  <D.14874>:
  current->syscall_break_signal = 0;
  return;
  <D.14875>:
  D.14876 = mono_threads_get_runtime_callbacks ();
  D.14877 = D.14876->thread_state_init_from_sigctx;
  D.14878 = &current->suspend_state;
  ret = D.14877 (D.14878, context);
  current->suspend_can_continue = ret;
  D.14879 = &current->begin_suspend_semaphore;
  mono_sem_post (D.14879);
  if (ret == 0) goto <D.14880>; else goto <D.14881>;
  <D.14880>:
  return;
  <D.14881>:
  goto <D.14783>;
  <D.14782>:
  <D.14783>:
  D.14882 = &current->resume_semaphore;
  D.14883 = mono_sem_wait (D.14882, 0);
  if (D.14883 != 0) goto <D.14782>; else goto <D.14784>;
  <D.14784>:
  D.14884 = current->async_target;
  if (D.14884 != 0B) goto <D.14885>; else goto <D.14886>;
  <D.14885>:
  monoeg_g_log (0B, 4, "The new interruption machinery requires a working mono-context");
  <D.14785>:
  goto <D.14785>;
  <D.14886>:
  D.14887 = &current->finish_resume_semaphore;
  mono_sem_post (D.14887);
}


mono_posix_add_signal_handler (int signo, void * handler)
{
  void (*<T24fc>) (int, struct siginfo_t *, void *) handler.1;
  _Bool D.14890;
  long int D.14891;
  long int D.14892;
  struct sigaction sa;
  struct sigaction previous_sa;
  int ret;

  try
    {
      handler.1 = (void (*<T24fc>) (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.14890 = ret == -1;
      D.14891 = (long int) D.14890;
      D.14892 = __builtin_expect (D.14891, 0);
      if (D.14892 != 0) goto <D.14893>; else goto <D.14894>;
      <D.14893>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 139, "ret != -1");
      <D.14894>:
    }
  finally
    {
      sa = {CLOBBER};
      previous_sa = {CLOBBER};
    }
}


mono_threads_core_interrupt (struct MonoThreadInfo * info)
{

}


mono_threads_pthread_kill (struct MonoThreadInfo * info, int signum)
{
  int D.14895;
  unsigned int D.14896;

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


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

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


mono_threads_core_needs_abort_syscall ()
{
  gboolean D.14899;

  D.14899 = 1;
  return D.14899;
}


mono_threads_core_suspend (struct MonoThreadInfo * info)
{
  int D.14901;
  union MonoSemType * D.14902;
  int D.14903;
  gboolean D.14904;

  D.14901 = mono_thread_get_abort_signal ();
  mono_threads_pthread_kill (info, D.14901);
  goto <D.14813>;
  <D.14812>:
  <D.14813>:
  D.14902 = &info->begin_suspend_semaphore;
  D.14903 = mono_sem_wait (D.14902, 0);
  if (D.14903 != 0) goto <D.14812>; else goto <D.14814>;
  <D.14814>:
  D.14904 = info->suspend_can_continue;
  return D.14904;
}


mono_threads_core_resume (struct MonoThreadInfo * info)
{
  union MonoSemType * D.14906;
  union MonoSemType * D.14907;
  int D.14908;
  gboolean D.14909;

  D.14906 = &info->resume_semaphore;
  mono_sem_post (D.14906);
  goto <D.14819>;
  <D.14818>:
  <D.14819>:
  D.14907 = &info->finish_resume_semaphore;
  D.14908 = mono_sem_wait (D.14907, 0);
  if (D.14908 != 0) goto <D.14818>; else goto <D.14820>;
  <D.14820>:
  D.14909 = 1;
  return D.14909;
}


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

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


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

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


mono_native_thread_id_get ()
{
  MonoNativeThreadId D.14913;

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


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

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


pthread_equal (pthread_t __thread1, pthread_t __thread2)
{
  int D.14917;
  _Bool D.14918;

  D.14918 = __thread1 == __thread2;
  D.14917 = (int) D.14918;
  return D.14917;
}


mono_native_thread_create (MonoNativeThreadId * tid, void * func, void * arg)
{
  gboolean D.14920;
  void * (*<T19d6>) (void *) func.2;
  int D.14922;
  _Bool D.14923;

  func.2 = (void * (*<T19d6>) (void *)) func;
  D.14922 = pthread_create (tid, 0B, func.2, arg);
  D.14923 = D.14922 == 0;
  D.14920 = (gboolean) D.14923;
  return D.14920;
}


