Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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 (&param, 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, &param);
	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;
}