Beispiel #1
0
int
thread_create(thread_id_t *tid, const char *name, 
		void (*entry)(uint32_t), uint32_t arg) {
    struct thread_context *tc = malloc(sizeof(struct thread_context));
    if (!tc)
	return -E_NO_MEM;

    memset(tc, 0, sizeof(struct thread_context));
    
    thread_set_name(tc, name);
    tc->tc_tid = alloc_tid();

    tc->tc_stack_bottom = malloc(stack_size);
    if (!tc->tc_stack_bottom) {
	free(tc);
	return -E_NO_MEM;
    }

    void *stacktop = tc->tc_stack_bottom + stack_size;
    // Terminate stack unwinding
    stacktop = stacktop - 4;
    memset(stacktop, 0, 4);
    
    memset(&tc->tc_jb, 0, sizeof(tc->tc_jb));
    tc->tc_jb.jb_esp = (uint32_t)stacktop;
    tc->tc_jb.jb_eip = (uint32_t)&thread_entry;
    tc->tc_entry = entry;
    tc->tc_arg = arg;

    threadq_push(&thread_queue, tc);

    if (tid)
	*tid = tc->tc_tid;
    return 0;
}
Beispiel #2
0
/*Acutal function for spawning a new task*/
struct tsk * spawn_task(char *taskname, struct attr attr, void *(*tsk_wrapper) (void *), void *arg)
{
	struct tsk  *new_task;

	new_task = (struct tsk *) tm_calloc (1, sizeof (struct tsk ));

	if (!new_task) {
		return NULL;
	}

	memset (new_task, 0, sizeof(struct tsk));

	INIT_LIST_HEAD (&new_task->hd);

	INIT_LIST_HEAD (&new_task->sig_hd);

	INIT_LIST_HEAD (&new_task->lock_hd);

	INIT_LIST_HEAD (&new_task->sync_hd);

	new_task->tid = alloc_tid ();

	new_task->needsched = TRUE;

	new_task->prio = attr.prio;

	new_task->stksize = attr.stksze;

	new_task->tslice = DEFAULT_TIME_SLICE;

	new_task->stk = tm_malloc (new_task->stksize);

	if (!new_task->stk) {
		free(new_task);
		return NULL;
        }

	strncpy (new_task->taskname, (char *)taskname, MAX_TASK_NAME);

	if (!nsetjmp (new_task->regs) && tsk_wrapper) {
		/*
		   The jmp_buf is assumed to contain the following, in order:
		   %ebx
		   %esp
		   %ebp
		   %esi
		   %edi
		   <return address>
		   */
		memcpy(&new_task->stk[new_task->stksize - 4], &arg, 
		       sizeof(unsigned int));
		memcpy(&new_task->stk[new_task->stksize - 8],&tsk_wrapper,
		       sizeof(unsigned int));
		new_task->regs->__jmpbuf[1] = (unsigned int)
				&new_task->stk[new_task->stksize - (3*sizeof(int))];
		new_task->regs->__jmpbuf[5] = (unsigned int)clone_thread;

		task_count++;

		wakeup_new_task (new_task);
	}

	return new_task;
}