mono_threads_pthread_create (pthread_t * new_thread, const union pthread_attr_t * attr, void * (*<Tf4e>) (void *) start_routine, void * arg)
{
  int D.12259;
  union MonoSemType * D.12260;
  struct MonoThreadInfoCallbacks * D.12261;
  int (*<T1b8b>) (pthread_t *, const union pthread_attr_t *, void * (*<Tf4e>) (void *), void *) D.12262;
  int D.12265;
  struct ThreadStartInfo * start_info;
  int result;

  start_info = monoeg_malloc0 (28);
  if (start_info == 0B) goto <D.12257>; else goto <D.12258>;
  <D.12257>:
  D.12259 = 12;
  return D.12259;
  <D.12258>:
  D.12260 = &start_info->registered;
  sem_init (D.12260, 0, 0);
  start_info->arg = arg;
  start_info->start_routine = start_routine;
  D.12261 = mono_threads_get_callbacks ();
  D.12262 = D.12261->mono_gc_pthread_create;
  result = D.12262 (new_thread, attr, inner_start_thread, start_info);
  if (result == 0) goto <D.12263>; else goto <D.12264>;
  <D.12263>:
  goto <D.12190>;
  <D.12189>:
  <D.12190>:
  D.12260 = &start_info->registered;
  D.12265 = mono_sem_wait (D.12260, 0);
  if (D.12265 != 0) goto <D.12189>; else goto <D.12191>;
  <D.12191>:
  <D.12264>:
  D.12260 = &start_info->registered;
  sem_destroy (D.12260);
  monoeg_g_free (start_info);
  D.12259 = result;
  return D.12259;
}


inner_start_thread (void * arg)
{
  struct MonoThreadInfo * D.12267;
  union MonoSemType * D.12268;
  _Bool D.12269;
  long int D.12270;
  long int D.12271;
  void * result.0;
  struct MonoDomain * D.12275;
  _Bool D.12276;
  long int D.12277;
  long int D.12278;
  void * D.12281;
  struct ThreadStartInfo * start_info;
  void * t_arg;
  int post_result;
  void * (*<Tf4e>) (void *) start_func;
  void * result;

  try
    {
      start_info = arg;
      t_arg = start_info->arg;
      start_func = start_info->start_routine;
      D.12267 = mono_thread_info_attach (&result);
      D.12267->runtime_thread = 1;
      D.12268 = &start_info->registered;
      post_result = mono_sem_post (D.12268);
      D.12269 = post_result != 0;
      D.12270 = (long int) D.12269;
      D.12271 = __builtin_expect (D.12270, 0);
      if (D.12271 != 0) goto <D.12272>; else goto <D.12273>;
      <D.12272>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 47, "!post_result");
      <D.12273>:
      result.0 = start_func (t_arg);
      result = result.0;
      D.12275 = mono_domain_get ();
      D.12276 = D.12275 != 0B;
      D.12277 = (long int) D.12276;
      D.12278 = __builtin_expect (D.12277, 0);
      if (D.12278 != 0) goto <D.12279>; else goto <D.12280>;
      <D.12279>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-threads-posix.c", 50, "!mono_domain_get ()");
      <D.12280>:
      mono_thread_info_dettach ();
      D.12281 = result;
      return D.12281;
    }
  finally
    {
      result = {CLOBBER};
    }
}


mono_threads_init_platform ()
{
  int D.12284;
  int D.12287;

  D.12284 = mono_thread_info_new_interrupt_enabled ();
  if (D.12284 != 0) goto <D.12285>; else goto <D.12286>;
  <D.12285>:
  D.12287 = mono_thread_get_abort_signal ();
  mono_posix_add_signal_handler (D.12287, suspend_signal_handler);
  <D.12286>:
}


suspend_signal_handler (int _dummy, struct siginfo_t * info, void * context)
{
  int D.12288;
  struct MonoThreadInfoRuntimeCallbacks * D.12291;
  gboolean (*<T1b98>) (struct MonoThreadUnwindState *, void *) D.12292;
  struct MonoThreadUnwindState * D.12293;
  union MonoSemType * D.12294;
  union MonoSemType * D.12297;
  int D.12298;
  void (*<Tc3>) (void *) D.12299;
  union MonoSemType * D.12302;
  struct MonoThreadInfo * current;
  gboolean ret;

  current = mono_thread_info_current ();
  D.12288 = current->syscall_break_signal;
  if (D.12288 != 0) goto <D.12289>; else goto <D.12290>;
  <D.12289>:
  current->syscall_break_signal = 0;
  return;
  <D.12290>:
  D.12291 = mono_threads_get_runtime_callbacks ();
  D.12292 = D.12291->thread_state_init_from_sigctx;
  D.12293 = &current->suspend_state;
  ret = D.12292 (D.12293, context);
  current->suspend_can_continue = ret;
  D.12294 = &current->begin_suspend_semaphore;
  mono_sem_post (D.12294);
  if (ret == 0) goto <D.12295>; else goto <D.12296>;
  <D.12295>:
  return;
  <D.12296>:
  goto <D.12200>;
  <D.12199>:
  <D.12200>:
  D.12297 = &current->resume_semaphore;
  D.12298 = mono_sem_wait (D.12297, 0);
  if (D.12298 != 0) goto <D.12199>; else goto <D.12201>;
  <D.12201>:
  D.12299 = current->async_target;
  if (D.12299 != 0B) goto <D.12300>; else goto <D.12301>;
  <D.12300>:
  monoeg_g_log (0B, 4, "The new interruption machinery requires a working mono-context");
  <D.12202>:
  goto <D.12202>;
  <D.12301>:
  D.12302 = &current->finish_resume_semaphore;
  mono_sem_post (D.12302);
}


mono_posix_add_signal_handler (int signo, void * handler)
{
  void (*<T1a75>) (int, struct siginfo_t *, void *) handler.1;
  _Bool D.12305;
  long int D.12306;
  long int D.12307;
  struct sigaction sa;
  struct sigaction previous_sa;
  int ret;

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


mono_threads_core_interrupt (struct MonoThreadInfo * info)
{

}


mono_threads_pthread_kill (struct MonoThreadInfo * info, int signum)
{
  int D.12310;
  unsigned int D.12311;

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


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

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


mono_threads_core_needs_abort_syscall ()
{
  gboolean D.12314;

  D.12314 = 1;
  return D.12314;
}


mono_threads_core_suspend (struct MonoThreadInfo * info)
{
  int D.12316;
  union MonoSemType * D.12317;
  int D.12318;
  gboolean D.12319;

  D.12316 = mono_thread_get_abort_signal ();
  mono_threads_pthread_kill (info, D.12316);
  goto <D.12230>;
  <D.12229>:
  <D.12230>:
  D.12317 = &info->begin_suspend_semaphore;
  D.12318 = mono_sem_wait (D.12317, 0);
  if (D.12318 != 0) goto <D.12229>; else goto <D.12231>;
  <D.12231>:
  D.12319 = info->suspend_can_continue;
  return D.12319;
}


mono_threads_core_resume (struct MonoThreadInfo * info)
{
  union MonoSemType * D.12321;
  union MonoSemType * D.12322;
  int D.12323;
  gboolean D.12324;

  D.12321 = &info->resume_semaphore;
  mono_sem_post (D.12321);
  goto <D.12236>;
  <D.12235>:
  <D.12236>:
  D.12322 = &info->finish_resume_semaphore;
  D.12323 = mono_sem_wait (D.12322, 0);
  if (D.12323 != 0) goto <D.12235>; else goto <D.12237>;
  <D.12237>:
  D.12324 = 1;
  return D.12324;
}


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

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


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

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


mono_native_thread_id_get ()
{
  MonoNativeThreadId D.12328;

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


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

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


pthread_equal (pthread_t __thread1, pthread_t __thread2)
{
  int D.12332;
  _Bool D.12333;

  D.12333 = __thread1 == __thread2;
  D.12332 = (int) D.12333;
  return D.12332;
}


mono_native_thread_create (MonoNativeThreadId * tid, void * func, void * arg)
{
  gboolean D.12335;
  void * (*<Tf4e>) (void *) func.2;
  int D.12337;
  _Bool D.12338;

  func.2 = (void * (*<Tf4e>) (void *)) func;
  D.12337 = pthread_create (tid, 0B, func.2, arg);
  D.12338 = D.12337 == 0;
  D.12335 = (gboolean) D.12338;
  return D.12335;
}


