struct proc* proctable_get_process(pid_t pid) { if (pid < MIN_PID || pid > MAX_PID) { return NULL; } return procarray_get(procTable, pid); }
void sys__exit(int exitcode) { // array init exitcode = _MKWAIT_EXIT(exitcode); // add to exitcode array struct exitc *c = find_exitc(curproc->p_pid); if(c) { c->exitcode = exitcode; } // remove from procarray. unsigned num = procarray_num(procarr); for (unsigned i = 0 ; i < num ; i++) { if ((procarray_get(procarr, i)) == curproc) { procarray_remove(procarr,i); break; } } // pid_list[curproc->p_pid] = false; cv_broadcast(curproc->p_cv,curproc->p_lk); //proc_remthread(curthread); thread_exit(); // curthread->t_proc = NULL; //what is this??? you removed it at the bottom and then added it here? // code below is removed. Since the process is destroyed, there is no "curthread" now. // We cannot access to it. // curthread->t_proc = NULL; }
void proctable_exit_process(struct proc *proc_exited, int exitcode) { // DEBUG(DB_EXEC, "Exiting PID: %d from proctable\n", getPID(proc_exited)); KASSERT(proc_exited != NULL); KASSERT(proc_exited->p_pid > 0); // set the process state to exited setState(proc_exited, PROC_EXITED); // encode the exit code as per the docs. setExitcode(proc_exited, _MKWAIT_EXIT(exitcode)); // Next we need to evaluate some cases: // If proc_exited has living children, they should now have a NULL parent. // If proc_exited has dead children, they should now be destroyed. int exitedPID = getPID(proc_exited); // Find the children of proc_exited. for (int i = MIN_PID; i < pidLimit; i++) { struct proc* cur = procarray_get(procTable, i); if (cur != NULL && getPPID(cur) == exitedPID) { // Check state of child int state = getState(cur); // A running child has its parent set to NULL if (state == PROC_RUNNING) { setPPID(cur, PROC_NO_PID); } // An exited child can now be completely removed. else if (state == PROC_EXITED) { proctable_remove_process(cur); } } } // If proc_exited has no parent, it can be removed if (getPPID(proc_exited) == PROC_NO_PID) { proctable_remove_process(proc_exited); } // Otherwise if proc_exited has a parent // then proc_exited must wake its potentially waiting parent else { cv_signal(proc_exited->wait_cv, procTableLock); } }
int proctable_add_process(struct proc *proc_created, struct proc *proc_parent) { KASSERT(procTableLock != NULL); KASSERT(proc_created != NULL); // Grow the proctable as more processes come in. // Subtract 1 for zero-indexing. if (procCount == pidLimit - 1) { if (pidLimit < MAX_PID) { pidLimit = pidLimit * 2; procarray_setsize(procTable, pidLimit); } else { return -1; } } // Assign a PID to the new process for (int i = MIN_PID; i < pidLimit; i++) { if (procarray_get(procTable, i) == NULL) { setPID(proc_created, i); procarray_set(procTable, i, proc_created); break; } } // Check to see if a PID was available if (getPID(proc_created) == PROC_NO_PID) { return -1; } DEBUG(DB_EXEC, "New process in table: %d\n", getPID(proc_created)); // Increase the count of processes in the procTable procCount++; // Assign the process' parent PID if (proc_parent == NULL) { setPPID(proc_created, PROC_NO_PID); } else { setPPID(proc_created, getPID(proc_parent)); } // Finally, set the state of the proces to running setState(proc_created, PROC_RUNNING); return 0; }