// func is a pointer to a procedure the thread will run. // arg is the argument to be passed to that procedure. void thread_create(thread_t *thread, void (*func)(int), int arg) { // Allocate TCB and stack TCB *tcb = new TCB(); thread->tcb = tcb; tcb->stack_size = INITIAL_STACK_SIZE; tcb->stack = new Stack(INITIAL_STACK_SIZE); // Initialize registers so that when thread is resumed, it will start running at // stub. The stack starts at the top of the allocated region and grows down. tcb->sp = tcb->stack + INITIAL_STACK_SIZE; tcb->pc = stub; // Create a stack frame by pushing stub's arguments and start address // onto the stack: func, arg *(tcb->sp) = arg; tcb->sp--; *(tcb->sp) = func; tcb->sp--; // Create another stack frame so that thread_switch works correctly. // This routine is explained later in the chapter. thread_dummySwitchFrame(tcb); tcb->state = #\readyThreadState#; readyList.add(tcb); // Put tcb on ready list } void stub(void (*func)(int), int arg) { (*func)(arg); // Execute the function func() thread_exit(0); // If func() does not call exit, call it here. }