mono_threads_pthread_create (pthread_t * new_thread, const union pthread_attr_t * attr, void * (*<T1020>) (void *) start_routine, void * arg)
{
  int D.13187;
  union MonoSemType * D.13188;
  struct MonoThreadInfoCallbacks * D.13189;
  int (*<T1cc2>) (pthread_t *, const union pthread_attr_t *, void * (*<T1020>) (void *), void *) D.13190;
  int D.13193;
  struct ThreadStartInfo * start_info;
  int result;

  start_info = monoeg_malloc0 (56);
  if (start_info == 0B) goto <D.13185>; else goto <D.13186>;
  <D.13185>:
  D.13187 = 12;
  return D.13187;
  <D.13186>:
  D.13188 = &start_info->registered;
  sem_init (D.13188, 0, 0);
  start_info->arg = arg;
  start_info->start_routine = start_routine;
  D.13189 = mono_threads_get_callbacks ();
  D.13190 = D.13189->mono_gc_pthread_create;
  result = D.13190 (new_thread, attr, inner_start_thread, start_info);
  if (result == 0) goto <D.13191>; else goto <D.13192>;
  <D.13191>:
  goto <D.13118>;
  <D.13117>:
  <D.13118>:
  D.13188 = &start_info->registered;
  D.13193 = mono_sem_wait (D.13188, 0);
  if (D.13193 != 0) goto <D.13117>; else goto <D.13119>;
  <D.13119>:
  <D.13192>:
  D.13188 = &start_info->registered;
  sem_destroy (D.13188);
  monoeg_g_free (start_info);
  D.13187 = result;
  return D.13187;
}


inner_start_thread (void * arg)
{
  struct MonoThreadInfo * D.13195;
  union MonoSemType * D.13196;
  _Bool D.13197;
  long int D.13198;
  long int D.13199;
  void * result.0;
  struct MonoDomain * D.13203;
  _Bool D.13204;
  long int D.13205;
  long int D.13206;
  void * D.13209;
  struct ThreadStartInfo * start_info;
  void * t_arg;
  int post_result;
  void * (*<T1020>) (void *) start_func;
  void * result;

  try
    {
      start_info = arg;
      t_arg = start_info->arg;
      start_func = start_info->start_routine;
      D.13195 = mono_thread_info_attach (&result);
      D.13195->runtime_thread = 1;
      D.13196 = &start_info->registered;
      post_result = mono_sem_post (D.13196);
      D.13197 = post_result != 0;
      D.13198 = (long int) D.13197;
      D.13199 = __builtin_expect (D.13198, 0);
      if (D.13199 != 0) goto <D.13200>; else goto <D.13201>;
      <D.13200>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 47, "!post_result");
      <D.13201>:
      result.0 = start_func (t_arg);
      result = result.0;
      D.13203 = mono_domain_get ();
      D.13204 = D.13203 != 0B;
      D.13205 = (long int) D.13204;
      D.13206 = __builtin_expect (D.13205, 0);
      if (D.13206 != 0) goto <D.13207>; else goto <D.13208>;
      <D.13207>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 50, "!mono_domain_get ()");
      <D.13208>:
      mono_thread_info_dettach ();
      D.13209 = result;
      return D.13209;
    }
  finally
    {
      result = {CLOBBER};
    }
}


mono_threads_init_platform ()
{
  int D.13212;
  int D.13215;

  D.13212 = mono_thread_info_new_interrupt_enabled ();
  if (D.13212 != 0) goto <D.13213>; else goto <D.13214>;
  <D.13213>:
  D.13215 = mono_thread_get_abort_signal ();
  mono_posix_add_signal_handler (D.13215, suspend_signal_handler);
  <D.13214>:
}


suspend_signal_handler (int _dummy, struct siginfo_t * info, void * context)
{
  int D.13216;
  struct MonoThreadInfoRuntimeCallbacks * D.13219;
  gboolean (*<T1ccf>) (struct MonoThreadUnwindState *, void *) D.13220;
  struct MonoThreadUnwindState * D.13221;
  union MonoSemType * D.13222;
  union MonoSemType * D.13225;
  int D.13226;
  void (*<Tbf>) (void *) D.13227;
  union MonoSemType * D.13230;
  struct MonoThreadInfo * current;
  gboolean ret;

  current = mono_thread_info_current ();
  D.13216 = current->syscall_break_signal;
  if (D.13216 != 0) goto <D.13217>; else goto <D.13218>;
  <D.13217>:
  current->syscall_break_signal = 0;
  return;
  <D.13218>:
  D.13219 = mono_threads_get_runtime_callbacks ();
  D.13220 = D.13219->thread_state_init_from_sigctx;
  D.13221 = &current->suspend_state;
  ret = D.13220 (D.13221, context);
  current->suspend_can_continue = ret;
  D.13222 = &current->begin_suspend_semaphore;
  mono_sem_post (D.13222);
  if (ret == 0) goto <D.13223>; else goto <D.13224>;
  <D.13223>:
  return;
  <D.13224>:
  goto <D.13128>;
  <D.13127>:
  <D.13128>:
  D.13225 = &current->resume_semaphore;
  D.13226 = mono_sem_wait (D.13225, 0);
  if (D.13226 != 0) goto <D.13127>; else goto <D.13129>;
  <D.13129>:
  D.13227 = current->async_target;
  if (D.13227 != 0B) goto <D.13228>; else goto <D.13229>;
  <D.13228>:
  monoeg_g_log (0B, 4, "The new interruption machinery requires a working mono-context");
  <D.13130>:
  goto <D.13130>;
  <D.13229>:
  D.13230 = &current->finish_resume_semaphore;
  mono_sem_post (D.13230);
}


mono_posix_add_signal_handler (int signo, void * handler)
{
  void (*<T1b3d>) (int, struct siginfo_t *, void *) handler.1;
  _Bool D.13233;
  long int D.13234;
  long int D.13235;
  struct sigaction sa;
  struct sigaction previous_sa;
  int ret;

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


mono_threads_core_interrupt (struct MonoThreadInfo * info)
{

}


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

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


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

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


mono_threads_core_needs_abort_syscall ()
{
  gboolean D.13242;

  D.13242 = 1;
  return D.13242;
}


mono_threads_core_suspend (struct MonoThreadInfo * info)
{
  int D.13244;
  union MonoSemType * D.13245;
  int D.13246;
  gboolean D.13247;

  D.13244 = mono_thread_get_abort_signal ();
  mono_threads_pthread_kill (info, D.13244);
  goto <D.13158>;
  <D.13157>:
  <D.13158>:
  D.13245 = &info->begin_suspend_semaphore;
  D.13246 = mono_sem_wait (D.13245, 0);
  if (D.13246 != 0) goto <D.13157>; else goto <D.13159>;
  <D.13159>:
  D.13247 = info->suspend_can_continue;
  return D.13247;
}


mono_threads_core_resume (struct MonoThreadInfo * info)
{
  union MonoSemType * D.13249;
  union MonoSemType * D.13250;
  int D.13251;
  gboolean D.13252;

  D.13249 = &info->resume_semaphore;
  mono_sem_post (D.13249);
  goto <D.13164>;
  <D.13163>:
  <D.13164>:
  D.13250 = &info->finish_resume_semaphore;
  D.13251 = mono_sem_wait (D.13250, 0);
  if (D.13251 != 0) goto <D.13163>; else goto <D.13165>;
  <D.13165>:
  D.13252 = 1;
  return D.13252;
}


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

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


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

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


mono_native_thread_id_get ()
{
  MonoNativeThreadId D.13256;

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


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

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


pthread_equal (pthread_t __thread1, pthread_t __thread2)
{
  int D.13260;
  _Bool D.13261;

  D.13261 = __thread1 == __thread2;
  D.13260 = (int) D.13261;
  return D.13260;
}


mono_native_thread_create (MonoNativeThreadId * tid, void * func, void * arg)
{
  gboolean D.13263;
  void * (*<T1020>) (void *) func.2;
  int D.13265;
  _Bool D.13266;

  func.2 = (void * (*<T1020>) (void *)) func;
  D.13265 = pthread_create (tid, 0B, func.2, arg);
  D.13266 = D.13265 == 0;
  D.13263 = (gboolean) D.13266;
  return D.13263;
}


