/* * Destroy a proc structure. * * Note: nothing currently calls this. Your wait/exit code will * probably want to do so. */ void proc_destroy(struct proc *proc) { /* * You probably want to destroy and null out much of the * process (particularly the address space) at exit time if * your wait/exit design calls for the process structure to * hang around beyond process exit. Some wait/exit designs * do, some don't. */ KASSERT(proc != NULL); KASSERT(proc != kproc); /* * We don't take p_lock in here because we must have the only * reference to this structure. (Otherwise it would be * incorrect to destroy it.) */ /* VFS fields */ if (proc->p_cwd) { VOP_DECREF(proc->p_cwd); proc->p_cwd = NULL; } /* VM fields */ if (proc->p_addrspace) { /* * In case p is the currently running process (which * it might be in some circumstances, or if this code * gets moved into exit as suggested above), clear * p_addrspace before calling as_destroy. Otherwise if * as_destroy sleeps (which is quite possible) when we * come back we'll be calling as_activate on a * half-destroyed address space. This tends to be * messily fatal. */ struct addrspace *as; as_deactivate(); as = curproc_setas(NULL); as_destroy(as); } threadarray_cleanup(&proc->p_threads); spinlock_cleanup(&proc->p_lock); kfree(proc->p_name); kfree(proc); }
/* * Destroy a proc structure. */ void proc_destroy(struct proc *proc) { /* * note: some parts of the process structure, such as the address space, * are destroyed in sys_exit, before we get here * * note: depending on where this function is called from, curproc may not * be defined because the calling thread may have already detached itself * from the process. */ KASSERT(proc != NULL); KASSERT(proc != kproc); #if OPT_A2 lock_destroy(proc->opencloselock); if(proc->filetable != NULL) { for(int i = 127; i >= 0; i--) { if(array_get(proc->filetable, i) != NULL) { //kprintf("%d \n", i); cleanupfile(array_get(proc->filetable, i)); } array_remove(proc->filetable, i); } array_destroy(proc->filetable); } #endif /* * We don't take p_lock in here because we must have the only * reference to this structure. (Otherwise it would be * incorrect to destroy it.) */ /* VFS fields */ if (proc->p_cwd) { VOP_DECREF(proc->p_cwd); proc->p_cwd = NULL; } #ifndef UW // in the UW version, space destruction occurs in sys_exit, not here if (proc->p_addrspace) { /* * In case p is the currently running process (which * it might be in some circumstances, or if this code * gets moved into exit as suggested above), clear * p_addrspace before calling as_destroy. Otherwise if * as_destroy sleeps (which is quite possible) when we * come back we'll be calling as_activate on a * half-destroyed address space. This tends to be * messily fatal. */ struct addrspace *as; as_deactivate(); as = curproc_setas(NULL); as_destroy(as); } #endif // UW #ifdef UW if (proc->console) { vfs_close(proc->console); } #endif // UW threadarray_cleanup(&proc->p_threads); spinlock_cleanup(&proc->p_lock); kfree(proc->p_name); kfree(proc); #ifdef UW /* decrement the process count */ /* note: kproc is not included in the process count, but proc_destroy is never called on kproc (see KASSERT above), so we're OK to decrement the proc_count unconditionally here */ P(proc_count_mutex); KASSERT(proc_count > 0); proc_count--; /* signal the kernel menu thread if the process count has reached zero */ if (proc_count == 0) { V(no_proc_sem); } V(proc_count_mutex); #endif // UW }
/* * Destroy a proc structure. * * Note: nothing currently calls this. Your wait/exit code will * probably want to do so. */ void proc_destroy(struct proc *proc) { /* * You probably want to destroy and null out much of the * process (particularly the address space) at exit time if * your wait/exit design calls for the process structure to * hang around beyond process exit. Some wait/exit designs * do, some don't. */ KASSERT(proc != NULL); KASSERT(proc != kproc); /* * We don't take p_lock in here because we must have the only * reference to this structure. (Otherwise it would be * incorrect to destroy it.) */ /* VFS fields */ if (proc->p_cwd) { VOP_DECREF(proc->p_cwd); proc->p_cwd = NULL; } if (proc->p_filetable) { filetable_destroy(proc->p_filetable); proc->p_filetable = NULL; } /* VM fields */ if (proc->p_addrspace) { /* * If p is the current process, remove it safely from * p_addrspace before destroying it. This makes sure * we don't try to activate the address space while * it's being destroyed. * * Also explicitly deactivate, because setting the * address space to NULL won't necessarily do that. * * (When the address space is NULL, it means the * process is kernel-only; in that case it is normally * ok if the MMU and MMU- related data structures * still refer to the address space of the last * process that had one. Then you save work if that * process is the next one to run, which isn't * uncommon. However, here we're going to destroy the * address space, so we need to make sure that nothing * in the VM system still refers to it.) * * The call to as_deactivate() must come after we * clear the address space, or a timer interrupt might * reactivate the old address space again behind our * back. * * If p is not the current process, still remove it * from p_addrspace before destroying it as a * precaution. Note that if p is not the current * process, in order to be here p must either have * never run (e.g. cleaning up after fork failed) or * have finished running and exited. It is quite * incorrect to destroy the proc structure of some * random other process while it's still running... */ struct addrspace *as; if (proc == curproc) { as = proc_setas(NULL); as_deactivate(); } else { as = proc->p_addrspace; proc->p_addrspace = NULL; } as_destroy(as); } threadarray_cleanup(&proc->p_threads); spinlock_cleanup(&proc->p_lock); kfree(proc->p_name); kfree(proc); }