HANDLE mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid) { pthread_attr_t attr; int res; pthread_t thread; StartInfo start_info; res = pthread_attr_init (&attr); g_assert (!res); if (stack_size == 0) { #if HAVE_VALGRIND_MEMCHECK_H if (RUNNING_ON_VALGRIND) stack_size = 1 << 20; else stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024; #else stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024; #endif } #ifdef PTHREAD_STACK_MIN if (stack_size < PTHREAD_STACK_MIN) stack_size = PTHREAD_STACK_MIN; #endif #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE res = pthread_attr_setstacksize (&attr, stack_size); g_assert (!res); #endif memset (&start_info, 0, sizeof (StartInfo)); start_info.start_routine = (void *(*)(void *)) start_routine; start_info.arg = arg; start_info.flags = creation_flags; MONO_SEM_INIT (&(start_info.registered), 0); /* Actually start the thread */ res = mono_gc_pthread_create (&thread, &attr, inner_start_thread, &start_info); if (res) { MONO_SEM_DESTROY (&(start_info.registered)); return NULL; } MONO_TRY_BLOCKING; /* Wait until the thread register itself in various places */ while (MONO_SEM_WAIT (&(start_info.registered)) != 0) { /*if (EINTR != errno) ABORT("sem_wait failed"); */ } MONO_FINISH_TRY_BLOCKING; MONO_SEM_DESTROY (&(start_info.registered)); if (out_tid) *out_tid = thread; return start_info.handle; }
gboolean mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *tid) { pthread_attr_t attr; pthread_t thread; gint res; gsize set_stack_size; res = pthread_attr_init (&attr); if (res != 0) g_error ("%s: pthread_attr_init failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); if (stack_size) set_stack_size = *stack_size; else set_stack_size = 0; #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE if (set_stack_size == 0) { #if HAVE_VALGRIND_MEMCHECK_H if (RUNNING_ON_VALGRIND) set_stack_size = 1 << 20; else set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024; #else set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024; #endif } #ifdef PTHREAD_STACK_MIN if (set_stack_size < PTHREAD_STACK_MIN) set_stack_size = PTHREAD_STACK_MIN; #endif res = pthread_attr_setstacksize (&attr, set_stack_size); if (res != 0) g_error ("%s: pthread_attr_setstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ /* Actually start the thread */ res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data); if (res) { res = pthread_attr_destroy (&attr); if (res != 0) g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); return FALSE; } if (tid) *tid = thread; if (stack_size) { res = pthread_attr_getstacksize (&attr, stack_size); if (res != 0) g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); } res = pthread_attr_destroy (&attr); if (res != 0) g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); return TRUE; }
int mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid) { pthread_attr_t attr; pthread_t thread; int policy; struct sched_param param; gint res; gsize set_stack_size; size_t min_size; res = pthread_attr_init (&attr); g_assert (!res); if (stack_size) set_stack_size = *stack_size; else set_stack_size = 0; #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE if (set_stack_size == 0) { #if HAVE_VALGRIND_MEMCHECK_H if (RUNNING_ON_VALGRIND) set_stack_size = 1 << 20; else set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024; #else set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024; #endif } #ifdef PTHREAD_STACK_MIN if (set_stack_size < PTHREAD_STACK_MIN) set_stack_size = PTHREAD_STACK_MIN; #endif res = pthread_attr_setstacksize (&attr, set_stack_size); g_assert (!res); #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ memset (¶m, 0, sizeof (param)); res = pthread_attr_getschedpolicy (&attr, &policy); if (res != 0) g_error ("%s: pthread_attr_getschedpolicy failed, error: \"%s\" (%d)", g_strerror (res), res); #ifdef _POSIX_PRIORITY_SCHEDULING int max, min; /* Necessary to get valid priority range */ min = sched_get_priority_min (policy); max = sched_get_priority_max (policy); if (max > 0 && min >= 0 && max > min) param.sched_priority = (max - min) / 2 + min; else #endif { switch (policy) { case SCHED_FIFO: case SCHED_RR: param.sched_priority = 50; break; #ifdef SCHED_BATCH case SCHED_BATCH: #endif case SCHED_OTHER: param.sched_priority = 0; break; default: g_error ("%s: unknown policy %d", __func__, policy); } } res = pthread_attr_setschedparam (&attr, ¶m); if (res != 0) g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res); if (stack_size) { res = pthread_attr_getstacksize (&attr, &min_size); if (res != 0) g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", g_strerror (res), res); else *stack_size = min_size; } /* Actually start the thread */ res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data); if (res) return -1; if (out_tid) *out_tid = thread; return 0; }