// Exit the current process. Does not return. // An exited process remains in the zombie state // until its parent calls wait() to find out it exited. void exit(void) { struct proc *p; int fd; if(proc == initproc) panic("init exiting"); // Close all open files. for(fd = 0; fd < NOFILE; fd++){ if(proc->ofile[fd]){ fileclose(proc->ofile[fd]); proc->ofile[fd] = 0; } } #ifndef SELECTION_NONE #ifdef VERBOSE_PRINT_TRUE char* state; if(proc->state >= 0 && proc->state < NELEM(states) && states[proc->state]) state = states[proc->state]; else state = "???"; print_proc_data(proc, state); cprintf("\n"); #endif free_proc_pgmd(proc,1); //remove swap file and pages metadata #endif begin_op(); iput(proc->cwd); end_op(); proc->cwd = 0; acquire(&ptable.lock); // Parent might be sleeping in wait(). wakeup1(proc->parent); // Pass abandoned children to init. for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->parent == proc){ p->parent = initproc; if(p->state == ZOMBIE) wakeup1(initproc); } } // Jump into the scheduler, never to return. proc->state = ZOMBIE; sched(); panic("zombie exit"); }
void proc_view_cmd(int argc, char **args, int call_type) { int with_pid; int with_ppid; int with_status; int with_threads; int with_tid; int with_tstatus; switch (call_type) { case CALL_TYPE_HELP: puts("PRINT INFORMATION ABOUT THE RUNNING PROCESSES\n"); return; case CALL_TYPE_DESC: puts("[pid] [ppid] [status] [threads] [tid] [tstatus]\n"); puts("\tpid\tPRINT THE PROCESS ID OF EACH PROCESS\n"); puts("\tppid\tPRINT THE PARENT PROCESS ID OF EACH PROCESS\n"); puts("\tstatus\tPRINT THE STATUS OF EACH PROCESS\n"); puts("\tthreads\tPRINT THE THREADS OF EACH PROCESS\n"); puts("\ttid\tPRINT THE THREAD ID OF EACH THREAD\n"); puts("\ttstatus\tPRINT THE STATUS OF EACH THREAD\n"); return; } with_pid = with_ppid = with_status = with_threads = with_tid = with_tstatus = 0; while (argc--) { if (!strcmp(*args, "pid")) with_pid = 1; else if (!strcmp(*args, "ppid")) with_ppid = 1; else if (!strcmp(*args, "status")) with_status = 1; else if (!strcmp(*args, "threads")) with_threads = 1; else if (!strcmp(*args, "tid")) with_tid = 1; else if (!strcmp(*args, "tstatus")) with_tstatus = 1; args++; } print_proc_data(with_pid, with_ppid, with_status, with_threads, with_tid, with_tstatus); }
//PAGEBREAK: 36 // Print a process listing to console. For debugging. // Runs when user types ^P on console. // No lock to avoid wedging a stuck machine further. void procdump(void) { int i; struct proc *p; char *state; uint pc[10]; for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state == UNUSED) continue; if(p->state >= 0 && p->state < NELEM(states) && states[p->state]) state = states[p->state]; else state = "???"; #ifndef SELECTION_NONE print_proc_data(p, state); #else cprintf("%d %s %s", p->pid, state, p->name); #endif if(p->state == SLEEPING){ getcallerpcs((uint*)p->context->ebp+2, pc); for(i=0; i<10 && pc[i] != 0; i++) cprintf(" %p", pc[i]); } cprintf("\n"); } #ifndef SELECTION_NONE uint currently_free = get_freepages_num(); if (currently_free == 0) currently_free = 1; uint precentage = ((float)currently_free / (float)free_pages_after_kernel) * 100; cprintf("%d%% free pages in the system\n", precentage); #endif }