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; }
/*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; }