static void __vsep_func( void * const ptr) { tid_t myid, nthreads; arg_t * arg; ctrl_t * ctrl; graph_t * graph; pid_t * where; pid_t ** dwhere; arg = ptr; ctrl = arg->ctrl; graph = arg->graph; where = arg->where; dwhere = arg->dwhere; myid = dlthread_get_id(ctrl->comm); nthreads = dlthread_get_nthreads(ctrl->comm); dlthread_barrier(ctrl->comm); if (nthreads > 1) { par_partition_pre(ctrl,graph); } dwhere[myid] = pid_alloc(graph->mynvtxs[myid]); par_partition_vertexseparator(ctrl,graph,dwhere); if (where) { __unify_where(dwhere,graph,where); } if (ctrl->verbosity >= MTMETIS_VERBOSITY_LOW) { dlthread_barrier(ctrl->comm); if (myid == 0) { partition_print_info(ctrl,graph,(pid_t const **)dwhere); } dlthread_barrier(ctrl->comm); } dl_free(dwhere[myid]); }
void main() { kputs("--DEBUG-- Hello world from kernel!\n"); unsigned long i; kernelsp[0]=(unsigned long)kernel_stack[1]; for(i=1;i<MSIM_CPU_NUM;i++) { send(MSIM_MASTER_ID, 0, 0); kernelsp[i]=(unsigned long)kernel_stack[i+1]; send(i, 1, (uint32_t)cpu_stack[i+1]); send(i, 0, (uint32_t)slave_main); } cur_pid=pid_alloc(); write_c0_entryhi(cur_pid); sc_num=SYS_EXEC; sc_args[0]="init"; sc_pid=cur_pid; for(;;) { write_c0_compare(0); switch(sc_num) { case SYS_PUTS: kputs(sc_args[0]); sc_ret=0; break; case SYS_FORK: sc_ret=kfork(); break; case SYS_EXEC: sc_ret=kexec(sc_args[0]); break; case SYS_GETS: sc_ret=kgets(sc_args[0], sc_args[1]); break; } pcb[sc_pid].gpr[ORD_V0]=sc_ret; cur_pid=sc_pid; next_process; sc_num=SYS_NONE; __to_user(); } }
/* * Create a new thread based on an existing one. * The new thread has name NAME, and starts executing in function FUNC. * DATA1 and DATA2 are passed to FUNC. */ int thread_fork(const char *name, void *data1, unsigned long data2, void (*func)(void *, unsigned long), pid_t *ret) { struct thread *newguy; int s, result; /* Allocate a thread */ newguy = thread_create(name); if (newguy==NULL) { return ENOMEM; } /* ASST1: Allocate a pid */ result = pid_alloc(&newguy->t_pid); if (result != 0) { kfree(newguy->t_name); kfree(newguy); return result; } /* Allocate a stack */ newguy->t_stack = kmalloc(STACK_SIZE); if (newguy->t_stack==NULL) { pid_unalloc(newguy->t_pid); /* ASST1: cleanup pid on fail */ kfree(newguy->t_name); kfree(newguy); return ENOMEM; } /* stick a magic number on the bottom end of the stack */ newguy->t_stack[0] = 0xae; newguy->t_stack[1] = 0x11; newguy->t_stack[2] = 0xda; newguy->t_stack[3] = 0x33; /* Inherit the current directory */ if (curthread->t_cwd != NULL) { VOP_INCREF(curthread->t_cwd); newguy->t_cwd = curthread->t_cwd; } /* ASST1: copy address space if there is one */ if (curthread->t_vmspace != NULL) { result = as_copy(curthread->t_vmspace, &newguy->t_vmspace); if (result) { pid_unalloc(newguy->t_pid); kfree(newguy->t_name); kfree(newguy->t_stack); kfree(newguy); return ENOMEM; } } /* Set up the pcb (this arranges for func to be called) */ md_initpcb(&newguy->t_pcb, newguy->t_stack, data1, data2, func); /* Interrupts off for atomicity */ s = splhigh(); /* * Make sure our data structures have enough space, so we won't * run out later at an inconvenient time. */ result = array_preallocate(sleepers, numthreads+1); if (result) { goto fail; } result = array_preallocate(zombies, numthreads+1); if (result) { goto fail; } /* Do the same for the scheduler. */ result = scheduler_preallocate(numthreads+1); if (result) { goto fail; } /* Make the new thread runnable */ result = make_runnable(newguy); if (result != 0) { goto fail; } /* * Increment the thread counter. This must be done atomically * with the preallocate calls; otherwise the count can be * temporarily too low, which would obviate its reason for * existence. */ numthreads++; /* Done with stuff that needs to be atomic */ splx(s); /* * Return new thread structure if it's wanted. Note that * using the thread structure from the parent thread should be * done only with caution, because in general the child thread * might exit at any time. */ if (ret != NULL) { *ret = newguy->t_pid; /* ASST1 return pid, not thread struct */ } else { /* Not returning the pid... better detach the new thread */ result = thread_detach(newguy->t_pid); assert(result == 0); /* can't fail. */ } return 0; fail: splx(s); /* ASST1: cleanup pid and vmspace on fail */ pid_unalloc(newguy->t_pid); if (newguy->t_vmspace) { as_destroy(newguy->t_vmspace); } if (newguy->t_cwd != NULL) { VOP_DECREF(newguy->t_cwd); } kfree(newguy->t_stack); kfree(newguy->t_name); kfree(newguy); return result; }