示例#1
0
/*!
 * Create new thread
 * \param start_func Starting function for new thread
 * \param param Parameter sent to starting function
 * \param exit_func Thread will call this function when it leaves 'start_func'
 * \param prio Thread priority
 * \param stack Address of thread stack (if not NULL)
 * \param stack_size Stack size
 * \param run Move thread descriptor to ready threads?
 * \param proc Process descriptor thread belongs to
 * \return Pointer to descriptor of created kernel thread
 */
kthread_t *k_create_thread ( void *start_func, void *param, void *exit_func,
			     int prio, void *stack, size_t stack_size, int run,
			     kprocess_t *proc )
{
	kthread_t *kthr;

	/* if stack is not defined */
	if ( proc && proc->stack_pool && ( !stack || !stack_size ) )
	{
		stack_size = proc->pi->thread_stack;
		stack = ffs_alloc ( proc->stack_pool, stack_size );
	}
	else if ( !stack || !stack_size )
	{
		if ( !stack_size )
			stack_size = DEFAULT_THREAD_STACK_SIZE;

		stack = kmalloc ( stack_size );
	}
	ASSERT ( stack && stack_size );

	kthr = kmalloc ( sizeof (kthread_t) ); /* thread descriptor */
	ASSERT ( kthr );

	/* initialize thread descriptor */
	kthr->id = k_new_unique_id ();

	kthr->state = THR_STATE_PASSIVE;

	if ( prio < 0 ) prio = 0;
	if ( prio >= PRIO_LEVELS ) prio = PRIO_LEVELS - 1;
	kthr->sched.prio = prio;

	arch_create_thread_context ( &kthr->context, start_func, param,
				     exit_func, stack, stack_size, proc );
	kthr->queue = NULL;
	kthr->exit_status = 0;
	k_threadq_init ( &kthr->join_queue );
	kthr->ref_cnt = 0;

	if ( run ) {
		move_to_ready ( kthr );
		kthr->ref_cnt = 1;
	}

	kthr->stack = stack;
	kthr->stack_size = stack_size;
	kthr->proc = proc;
	kthr->proc->thr_count++;
	kthr->private_storage = NULL;

#ifdef	MESSAGES
	k_thr_msg_init ( &kthr->msg );
#endif
	list_append ( &all_threads, kthr, &kthr->all );

	return kthr;
}
示例#2
0
/*! create/insert state for signal handler and similar */
void kthread_create_new_state ( kthread_t *kthread,
				void *start_func, void *param,
				void *stack, size_t stack_size,
				int save_old_state )
{
	ASSERT ( kthread );

	/* save old state if requested (put it at beginning of state list) */
	if ( save_old_state )
	{
		kthread_state_t *state = kmalloc ( sizeof (kthread_state_t) );
		*state = kthread->state;
		list_prepend ( &kthread->states, state, &state->list );
	}

	int stack_provided = FALSE;

	if ( !stack || !stack_size )
	{
		if ( !stack_size )
			stack_size = DEFAULT_THREAD_STACK_SIZE;

		stack = kmalloc ( stack_size );
	}
	ASSERT ( stack && stack_size );

	if ( stack_provided )
	{
		kthread->state.stack = NULL;
		kthread->state.stack_size = 0;
	}
	else {
		kthread->state.stack = stack;
		kthread->state.stack_size = stack_size;
	}

	arch_create_thread_context ( &kthread->state.context, start_func, param,
				     pi.exit, stack, stack_size );

	kthread->state.flags = 0;
	kthread->state.retval = 0;
	kthread->state.errno = 0;
	kthread->state.exit_status = NULL;
	kthread->state.pparam = NULL;

	list_init ( &kthread->state.cleanup );
}
uthread_t *create_uthread ( void (func) (void *), void *param )
{
	uthread_t *thread;

	thread = malloc ( sizeof (uthread_t) );
	thread->stack = malloc (DEFAULT_THREAD_STACK_SIZE);

	thread->id = next_id;

	arch_create_thread_context ( &thread->context, func, param,
		uthread_exit, thread->stack, DEFAULT_THREAD_STACK_SIZE );

	next_id++;
	list_append ( &ready, thread, &thread->list );

	return thread;
}
示例#4
0
文件: thread.c 项目: l30nard0/Benu
/*! create/insert state for signal handler and similar */
void kthread_create_new_state ( kthread_t *kthread,
				void *start_func, void *param,
				void *stack, size_t stack_size,
				int save_old_state )
{
	ASSERT ( kthread );
	kprocess_t *kproc = kthread_get_process ( kthread );
	ASSERT ( kproc );

	/* save old state if requested (put it at beginning of state list) */
	if ( save_old_state )
	{
		kthread_state_t *state = kmalloc ( sizeof (kthread_state_t) );
		*state = kthread->state;
		list_prepend ( &kthread->states, state, &state->list );
	}

	int stack_provided = FALSE;

	if ( stack && stack_size )
	{
		stack_provided = TRUE;
	}
	else if ( kproc->smap )
	{
		/* use process stack heap */
		stack_size = kproc->thread_stack_size;
		stack = kprocess_stack_alloc ( kproc );
	}
	else {
		/* use kernel heap */
		if ( !stack_size )
			stack_size = DEFAULT_THREAD_STACK_SIZE;

		stack = kmalloc ( stack_size );
	}
	ASSERT ( stack && stack_size );

	if ( stack_provided )
	{
		kthread->state.stack = NULL; /* don't free it on exit */
		kthread->state.stack_size = 0;
	}
	else {
		kthread->state.stack = stack;
		kthread->state.stack_size = stack_size;
	}

	/* reserve space for errno in user space */
	stack_size -= sizeof (int);
	kthread->state.errno = kthread->state.stack + stack_size;

	arch_create_thread_context ( &kthread->state.context, start_func, param,
				     kproc->proc->p.exit, stack, stack_size, kproc );

	*kthread->state.errno = 0;
	kthread->state.exit_status = NULL;
	kthread->state.pparam = NULL;

	list_init ( &kthread->state.cleanup );
}