コード例 #1
0
ファイル: uinit.c プロジェクト: fhector/helenOS-0.5-Hector
/** Thread used to bring up userspace thread.
 *
 * @param arg Pointer to structure containing userspace entry and stack
 *     addresses.
 */
void uinit(void *arg)
{
	/*
	 * So far, we don't have a use for joining userspace threads so we
	 * immediately detach each uinit thread. If joining of userspace threads
	 * is required, some userspace API based on the kernel mechanism will
	 * have to be implemented. Moreover, garbage collecting of threads that
	 * didn't detach themselves and nobody else joined them will have to be
	 * deployed for the event of forceful task termination.
	 */
	thread_detach(THREAD);
	
#ifdef CONFIG_UDEBUG
	udebug_stoppable_end();
#endif
	
	uspace_arg_t *uarg = (uspace_arg_t *) arg;
	uspace_arg_t local_uarg;
	
	local_uarg.uspace_entry = uarg->uspace_entry;
	local_uarg.uspace_stack = uarg->uspace_stack;
	local_uarg.uspace_stack_size = uarg->uspace_stack_size;
	local_uarg.uspace_uarg = uarg->uspace_uarg;
	local_uarg.uspace_thread_function = NULL;
	local_uarg.uspace_thread_arg = NULL;
	
	free(uarg);
	
	userspace(&local_uarg);
}
コード例 #2
0
ファイル: process_kern.c プロジェクト: kzlin129/tt-gpl
void new_thread_handler(int sig)
{
	int (*fn)(void *), n;
	void *arg;

	fn = current->thread.request.u.thread.proc;
	arg = current->thread.request.u.thread.arg;
	change_sig(SIGUSR1, 1);
	thread_wait(&current->thread.mode.skas.switch_buf, 
		    current->thread.mode.skas.fork_buf);

	if(current->thread.prev_sched != NULL)
		schedule_tail(current->thread.prev_sched);
	current->thread.prev_sched = NULL;

	/* The return value is 1 if the kernel thread execs a process,
	 * 0 if it just exits
	 */
	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
	if(n == 1){
		/* Handle any immediate reschedules or signals */
		interrupt_end();
		userspace(&current->thread.regs.regs);
	}
	else do_exit(0);
}
コード例 #3
0
ファイル: proc.c プロジェクト: Aresthu/ucore_plus
/**
 * The hook called before 'do_execve' successfully return.
 *     What we need to do here are:
 *       1. create a new host container if the process doesn't have one yet;
 *       2. create the stack for syscall stub;
 *       3. unmap umUcore kernel area in the child and erasing the info in the page table;
 *       4. copy arguments to the user stack of the child, and free the kernel's copy;
 *       5. call 'userspace'.
 *     If everything is done, the current thread becomes a monitor thread forever.
 * @param argc the number of arguments
 * @param kargv the copy of the arguments in the kernel
 */
int do_execve_arch_hook(int argc, char **kargv)
{
	if (current->arch.host == NULL) {
		current->arch.host = kmalloc(sizeof(struct host_container));
		if (current->arch.host == NULL)
			return -1;
	}

	void *stub_stack = boot_alloc_page();
	if (stub_stack == NULL)
		goto free_host;
	int ret = start_userspace(stub_stack);
	if (ret <= 0)
		goto free_stub_stack;

	current->arch.host->stub_stack = stub_stack;
	current->arch.host->host_pid = ret;
	current->arch.host->nr_threads = 1;

	/* unmap kernel area */
	if (host_munmap(current, (void *)KERNBASE, KERNTOP - KERNBASE) < 0)
		panic("unmap kernel area failed\n");

	/* erase kernel maps in the page table */
	int valid_size = KERNBASE / PTSIZE * sizeof(pte_t);
	memset((void *)((int)(current->mm->pgdir) + valid_size),
	       0, PGSIZE - valid_size);

	/* Copy arguments */
	current->arch.regs.is_user = 1;
	uintptr_t stacktop = USTACKTOP - argc * PGSIZE;
	char **uargv = (char **)(stacktop - argc * sizeof(char *));
	int i, addr;
	for (i = 0; i < argc; i++) {
		addr = stacktop + i * PGSIZE;
		assert(copy_to_user
		       (current->mm, uargv + i, &addr, sizeof(int)));
		assert(copy_to_user
		       (current->mm, (void *)addr, kargv[i],
			strlen(kargv[i]) + 1));
	}
	stacktop = (uintptr_t) uargv - sizeof(int);
	copy_to_user(current->mm, (void *)stacktop, &argc, sizeof(int));

	/* The copy of the args in the kernel will never be used again and we will not return,
	 *     so free them here.
	 */
	while (argc > 0) {
		kfree(kargv[--argc]);
	}
	userspace(&(current->arch.regs));
	/* should never comes here */

free_stub_stack:
	free_page(kva2page(stub_stack));
free_host:
	kfree(current->arch.host);
	current->arch.host = NULL;
	return -1;
}
コード例 #4
0
void fork_handler(int sig)
{
        change_sig(SIGUSR1, 1);
 	thread_wait(&current->thread.mode.skas.switch_buf, 
		    current->thread.mode.skas.fork_buf);
  	
	force_flush_all();
	if(current->thread.prev_sched == NULL)
		panic("blech");

	schedule_tail(current->thread.prev_sched);
	current->thread.prev_sched = NULL;

	userspace(&current->thread.regs.regs);
}
コード例 #5
0
ファイル: process_kern.c プロジェクト: kzlin129/tt-gpl
void fork_handler(int sig)
{
        change_sig(SIGUSR1, 1);
 	thread_wait(&current->thread.mode.skas.switch_buf, 
		    current->thread.mode.skas.fork_buf);
  	
	force_flush_all();
	if(current->thread.prev_sched == NULL)
		panic("blech");

	schedule_tail(current->thread.prev_sched);
	current->thread.prev_sched = NULL;

	/* Handle any immediate reschedules or signals */
	interrupt_end();
	userspace(&current->thread.regs.regs);
}
コード例 #6
0
ファイル: process.c プロジェクト: 3sOx/asuswrt-merlin
/* Called magically, see new_thread_handler above */
void fork_handler(void)
{
	force_flush_all();
	if(current->thread.prev_sched == NULL)
		panic("blech");

	schedule_tail(current->thread.prev_sched);

	/* XXX: if interrupt_end() calls schedule, this call to
	 * arch_switch_to_skas isn't needed. We could want to apply this to
	 * improve performance. -bb */
	arch_switch_to_skas(current->thread.prev_sched, current);

	current->thread.prev_sched = NULL;

/* Handle any immediate reschedules or signals */
	interrupt_end();

	userspace(&current->thread.regs.regs);
}