__attribute__((noinline)) static void tm_process_exit(int code) { spinlock_acquire(¤t_thread->status_lock); if(code != -9) current_process->exit_reason.cause = __EXIT; current_process->exit_reason.ret = code; current_process->exit_reason.pid = current_process->pid; spinlock_release(¤t_thread->status_lock); /* update times */ if(current_process->parent) { time_t total_utime = current_process->utime + current_process->cutime; time_t total_stime = current_process->stime + current_process->cstime; atomic_fetch_add_explicit(¤t_process->parent->cutime, total_utime, memory_order_relaxed); atomic_fetch_add_explicit(¤t_process->parent->cstime, total_stime, memory_order_relaxed); } file_close_all(); if(current_process->root) vfs_icache_put(current_process->root); if(current_process->cwd) vfs_icache_put(current_process->cwd); mutex_destroy(¤t_process->fdlock); mm_destroy_all_mappings(current_process); linkedlist_destroy(&(current_process->mappings)); valloc_destroy(¤t_process->mmf_valloc); /* this is done before SIGCHILD is sent out */ atomic_fetch_or(¤t_process->flags, PROCESS_EXITED); if(current_process->parent) { struct process *init = tm_process_get(0); assert(init); __linkedlist_lock(process_list); struct process *child; struct linkedentry *node; for(node = linkedlist_iter_start(process_list); node != linkedlist_iter_end(process_list); node = linkedlist_iter_next(node)) { child = linkedentry_obj(node); if(child->parent == current_process) { tm_process_inc_reference(init); child->parent = init; tm_process_put(current_process); } } __linkedlist_unlock(process_list); tm_signal_send_process(current_process->parent, SIGCHILD); tm_blocklist_wakeall(¤t_process->waitlist); tm_process_put(init); } tm_process_put(current_process); /* fork starts us out at refs = 1 */ }
static void __raise_action(struct pty *pty, int sig) { __linkedlist_lock(process_list); struct linkedentry *node; for (node = linkedlist_iter_start(process_list); node != linkedlist_iter_end(process_list); node = linkedlist_iter_next(node)) { struct process *proc = linkedentry_obj(node); if (proc->pty == pty) { tm_signal_send_process(proc, sig); } } __linkedlist_unlock(process_list); }