/* Returns the file descriptor associated with the given handle. Terminates the process if HANDLE is not associated with an open ordinary file. */ static struct file_descriptor * lookup_file_fd (int handle) { struct file_descriptor *fd = lookup_fd (handle); if (fd->file == NULL) thread_exit (); return fd; }
/* * static void test_thread(void) * This is the thread that gets started by thread_create */ static void test_thread(void) { printf("In test_thread\n"); /* Loop, doing a little work then yielding to the other thread */ while(1); thread_exit(0); }
/* A way to yield and leave the threading system for extended periods */ void thread_sdl_thread_lock(void *me) { SDL_LockMutex(m); cores[CURRENT_CORE].running = (struct thread_entry *)me; if (threads_exit) thread_exit(); }
static void suicide() { int ret = set_flag(1); assert(ret == 0); thread_exit(THREAD_SELF); assert(0); }
/* A way to yield and leave the threading system for extended periods */ void sim_thread_lock(void *me) { SDL_LockMutex(m); cores[CURRENT_CORE].running = (struct thread_entry *)me; if (threads_status != THREADS_RUN) thread_exit(); }
void thread_stub(void (*thread_main)(void *), void *arg) { interrupts_set(1); Tid ret; thread_main(arg); // call thread_main() function with arg ret = thread_exit(THREAD_SELF); assert(ret == THREAD_NONE); exit(0); }
/* * It appears on export/reboot, iokit can hold a lock, then call our * termination handler, and we end up locking-against-ourselves inside * IOKit. We are then forced to make the vnode_close() call be async. */ static void vdev_disk_close_thread(void *arg) { struct vnode *vp = arg; (void) vnode_close(vp, 0, spl_vfs_context_kernel()); thread_exit(); }
void thread_cleanup_and_exit (int status) { printf ("%s: exit(%d)\n", thread_name (), status); /* close all open file descriptors */ struct thread *t = thread_current (); struct list_elem *e; /* close all the files opened and free spaces allocated for the file list */ while (!list_empty (&t->file_list)) { e = list_pop_back (&t->file_list); struct file_elem *f_elem = list_entry (e, struct file_elem, elem); file_close (f_elem->file); free (f_elem); } /* free waited_children_list and children_list */ while (!list_empty (&t->children_list)) { e = list_pop_back (&t->children_list); struct child_elem *c_elem = list_entry (e, struct child_elem, elem); // free children from the global exit_list free_thread_from_exit_list (c_elem->pid); free (c_elem); } while (!list_empty (&t->waited_children_list)) { e = list_pop_back (&t->waited_children_list); struct wait_child_elem *w_elem = list_entry (e, struct wait_child_elem, elem); free (w_elem); } add_thread_to_exited_list (t->tid, status); /* allow file write to executable */ if (t->exec_file) { file_allow_write (t->exec_file); file_close (t->exec_file); } /* release all the locks that have not already been released */ while (!list_empty (&t->acquired_locks)) { struct list_elem *e = list_front (&t->acquired_locks); struct lock *l = list_entry (e, struct lock, elem); lock_release (l); } /* wake parent up if its waiting on it */ struct thread *parent = get_thread (thread_current ()->parent_id); if (parent) { sema_up (&parent->waiting_on_child_exit_sema); } thread_exit (); }
/* Performance monitor thread */ static void spa_perfmon_thread(spa_t *spa) { spa_perfmon_data_t *data = &spa->spa_perfmon; boolean_t done = B_FALSE; ASSERT(data); DTRACE_PROBE1(spa_pm_start, spa_t *, spa); /* take a reference against spa */ mutex_enter(&spa_namespace_lock); spa_open_ref(spa, FTAG); mutex_exit(&spa_namespace_lock); /* CONSTCOND */ while (1) { clock_t deadline = ddi_get_lbolt() + spa_special_stat_update_ticks; /* wait for the next tick, check exit condition */ mutex_enter(&data->perfmon_lock); (void) cv_timedwait(&data->perfmon_cv, &data->perfmon_lock, deadline); if (spa->spa_state == POOL_STATE_UNINITIALIZED || data->perfmon_thr_exit) done = B_TRUE; mutex_exit(&data->perfmon_lock); if (done) goto out; /* * do the monitoring work here: gather average * latency and utilization statistics */ DTRACE_PROBE1(spa_pm_work, spa_t *, spa); spa_load_stats_update(spa); /* we can adjust load and dedup at the same time */ if (spa_enable_data_placement_selection) spa_special_load_adjust(spa); if (spa->spa_dedup_best_effort) spa_special_dedup_adjust(spa); /* go to sleep until next tick */ DTRACE_PROBE1(spa_pm_sleep, spa_t *, spa); } out: /* release the reference against spa */ mutex_enter(&spa_namespace_lock); spa_close(spa, FTAG); mutex_exit(&spa_namespace_lock); DTRACE_PROBE1(spa_pm_stop, spa_t *, spa); thread_exit(); }
/* this needs to be fixed to get exit() and waitpid() working properly */ void sys__exit(int exitcode, int type) { struct addrspace *as; struct proc *p = curproc; DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode); KASSERT(curproc->p_addrspace != NULL); as_deactivate(); /* * 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. */ as = curproc_setas(NULL); as_destroy(as); lock_acquire(p->proc_exit_lock); if(!p->proc_parent_exited && p->pid > 1){ // Parent didnt exit yet, so we must only semi-destroy the proc proc_set_exit_status(p,exitcode, type); cv_broadcast(p->proc_exit_cv, p->proc_exit_lock); proc_exited_signal(p); /* detach this thread from its process */ /* note: curproc cannot be used after this call */ proc_remthread(curthread); // semi_destroy will release the proc_exit_lock for us. proc_semi_destroy(p); lock_release(p->proc_exit_lock); }else{ proc_exited_signal(p); lock_release(p->proc_exit_lock); /* detach this thread from its process */ /* note: curproc cannot be used after this call */ proc_remthread(curthread); /* if this is the last user process in the system, proc_destroy() will wake up the kernel menu thread */ proc_destroy(p); } thread_exit(); /* thread_exit() does not return, so we should never get here */ panic("return from thread_exit in sys_exit\n"); }
/* * Unfortunately the notify thread that posts the termination event to us * is inside IOkit locked loop, so we have to issue the vnode_close() * async, or vn_close()/dkclose() will wait on notify to release the lock */ static void vdev_close_thread(void *arg) { vdev_t *vd = (vdev_t *)arg; vdev_disk_t *dvd = (vdev_disk_t *)vd->vdev_tsd; if (dvd) dvd->vd_offline = B_TRUE; vdev_disk_close(vd); thread_exit(); }
static void softerr_intr( void ) { puts(current->name); puts(" DOWN.\n"); getcurrent(); thread_exit(); }
void thread_sdl_exception_wait(void) { while (1) { SDL_Delay(HZ/10); if (threads_exit) thread_exit(); } }
/* Read system call. */ static int sys_read (int handle, void *udst_, unsigned size) { uint8_t *udst = udst_; struct file_descriptor *fd; int bytes_read = 0; /* Look up file descriptor. */ if (handle != STDIN_FILENO) fd = lookup_file_fd (handle); while (size > 0) { /* How much to read into this page? */ size_t page_left = PGSIZE - pg_ofs (udst); size_t read_amt = size < page_left ? size : page_left; off_t retval; /* Check that touching this page is okay. */ if (!page_lock (udst, true)) thread_exit (); /* Read from file into page. */ if (handle != STDIN_FILENO) { retval = file_read (fd->file, udst, read_amt); if (retval < 0) { if (bytes_read == 0) bytes_read = -1; break; } bytes_read += retval; } else { size_t i; for (i = 0; i < read_amt; i++) udst[i] = input_getc (); bytes_read = read_amt; } /* Release page. */ page_unlock (udst); /* If it was a short read we're done. */ if (retval != (off_t) read_amt) break; /* Advance. */ udst += retval; size -= retval; } return bytes_read; }
static void splat_thread_work3_exit(void *priv) { thread_priv_t *tp = (thread_priv_t *)priv; ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC); splat_thread_work3_common(tp); thread_exit(); }
/* exit process */ void exit(int status) { struct thread *current_process=thread_current(); current_process->process_exit_status = status; printf("%s: exit(%d)\n",current_process->name,status); thread_exit(); }
/* Terminates the current user program. If the processes parent waits for it, this status will be returned to the parent (Parent looks at child's exit status). Status of 0 indicates success, and anything else indicates an error. After this function is called in syscall_handler(), the exit status is sent ('returned') to the kernel. */ void sys_exit(int status) { struct thread *cur = thread_current(); cur->exit_status = status; /* Process termination message, printing process' name and exit status. */ printf("%s: exit(%d)\n", cur->name, status); thread_exit(); }
void sys__exit(int exitcode) { /* The code for freeing resources used by a process are found in thread.c since we need to be able to free these resources on processes that exit abnormally (crash without calling _exit()) */ curthread->exit_status = exitcode; thread_exit(); }
void sim_thread_exception_wait(void) { while (1) { SDL_Delay(HZ/10); if (threads_status != THREADS_RUN) thread_exit(); } }
void LCUI_Thread_Exit(void* retval) /* * 功能:终止调用它的线程并返回一个指向某个对象的指针 * 说明:线程通过调用LCUI_Thread_Exit函数终止执行,就如同进程在结 * 束时调用exit函数一样。 * */ { thread_exit(retval); }
static void mmp_thread_exit(mmp_thread_t *mmp, kthread_t **mpp, callb_cpr_t *cpr) { ASSERT(*mpp != NULL); *mpp = NULL; cv_broadcast(&mmp->mmp_thread_cv); CALLB_CPR_EXIT(cpr); /* drops &mmp->mmp_thread_lock */ thread_exit(); }
void my_exit(int status) { struct thread *cur = thread_current(); printf("%s: exit(%d)\n", cur->pname, status); cur->cp->exit = status; cur->cp->wait = false; thread_exit(); }
int kern_thr_exit(struct thread *td) { struct proc *p; p = td->td_proc; /* * If all of the threads in a process call this routine to * exit (e.g. all threads call pthread_exit()), exactly one * thread should return to the caller to terminate the process * instead of the thread. * * Checking p_numthreads alone is not sufficient since threads * might be committed to terminating while the PROC_LOCK is * dropped in either ptracestop() or while removing this thread * from the tidhash. Instead, the p_pendingexits field holds * the count of threads in either of those states and a thread * is considered the "last" thread if all of the other threads * in a process are already terminating. */ PROC_LOCK(p); if (p->p_numthreads == p->p_pendingexits + 1) { /* * Ignore attempts to shut down last thread in the * proc. This will actually call _exit(2) in the * usermode trampoline when it returns. */ PROC_UNLOCK(p); return (0); } p->p_pendingexits++; td->td_dbgflags |= TDB_EXIT; if (p->p_flag & P_TRACED && p->p_flag2 & P2_LWP_EVENTS) ptracestop(td, SIGTRAP); PROC_UNLOCK(p); tidhash_remove(td); PROC_LOCK(p); p->p_pendingexits--; /* * The check above should prevent all other threads from this * process from exiting while the PROC_LOCK is dropped, so * there must be at least one other thread other than the * current thread. */ KASSERT(p->p_numthreads > 1, ("too few threads")); racct_sub(p, RACCT_NTHR, 1); tdsigcleanup(td); umtx_thread_exit(td); PROC_SLOCK(p); thread_stopped(p); thread_exit(); /* NOTREACHED */ }
/* void free_root(struct procinfo* pi){ KASSERT(pi != NULL); if (pi->parent_pid == -1){ array_set(proc) } }*/ void sys__exit(int exitcode) { struct addrspace *as; struct proc *p = curproc; /* for now, just include this to keep the compiler from complaining about an unused variable */ #if OPT_A2 struct procinfo *pi = array_get(procinfotable, p->pid-1); if(pi == NULL){ goto parentexited; } lock_acquire(p->p_waitpid_lock); pi->exit_code = _MKWAIT_EXIT(exitcode); pi->active = 0; cv_broadcast(pi->waitpid_cv,p->p_waitpid_lock); lock_release(p->p_waitpid_lock); free_children(p->pid); parentexited: #else (void)exitcode; #endif DEBUG(DB_SYSCALL,"Syscall: _exit(%d)\n",exitcode); KASSERT(curproc->p_addrspace != NULL); as_deactivate(); /* * 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. */ as = curproc_setas(NULL); as_destroy(as); /* detach this thread from its process */ /* note: curproc cannot be used after this call */ proc_remthread(curthread); /* if this is the last user process in the system, proc_destroy() will wake up the kernel menu thread */ proc_destroy(p); thread_exit(); /* thread_exit() does not return, so we should never get here */ panic("return from thread_exit in sys_exit\n"); }
/* System call handler. */ static void syscall_handler (struct intr_frame *f) { typedef int syscall_function (int, int, int); /* A system call. */ struct syscall { size_t arg_cnt; /* Number of arguments. */ syscall_function *func; /* Implementation. */ }; /* Table of system calls. */ static const struct syscall syscall_table[] = { {0, (syscall_function *) sys_halt}, {1, (syscall_function *) sys_exit}, {1, (syscall_function *) sys_exec}, {1, (syscall_function *) sys_wait}, {2, (syscall_function *) sys_create}, {1, (syscall_function *) sys_remove}, {1, (syscall_function *) sys_open}, {1, (syscall_function *) sys_filesize}, {3, (syscall_function *) sys_read}, {3, (syscall_function *) sys_write}, {2, (syscall_function *) sys_seek}, {1, (syscall_function *) sys_tell}, {1, (syscall_function *) sys_close}, {2, (syscall_function *) sys_mmap}, {1, (syscall_function *) sys_munmap}, {1, (syscall_function *) sys_chdir}, {1, (syscall_function *) sys_mkdir}, {2, (syscall_function *) sys_readdir}, {1, (syscall_function *) sys_isdir}, {1, (syscall_function *) sys_inumber}, }; const struct syscall *sc; unsigned call_nr; int args[3]; /* Get the system call. */ copy_in (&call_nr, f->esp, sizeof call_nr); if (call_nr >= sizeof syscall_table / sizeof *syscall_table) thread_exit (); sc = syscall_table + call_nr; /* Get the system call arguments. */ ASSERT (sc->arg_cnt <= sizeof args / sizeof *args); memset (args, 0, sizeof args); copy_in (args, (uint32_t *) f->esp + 1, sizeof *args * sc->arg_cnt); /* Execute the system call, and set the return value. */ f->eax = sc->func (args[0], args[1], args[2]); }
/*! Initialize threads environment */ void prog_init ( void *args ) { /* initialize dynamic memory */ pi.mpool = mem_init ( pi.heap, pi.heap_size ); /* call starting function */ ( (void (*) ( void * ) ) pi.entry ) ( args ); thread_exit ( 0 ); }
void LongJmp(FL_PAR,jmp_buf env,int val){ if( inSignalHandler ){ putsLog("##non-SIG longjmp in signal handling"); } if( ismainthread() ){ }else{ putsLog("##non-SIG longjmp in non-main-thread"); thread_exit(0); } }
/* * Command for shutting down. */ static int cmd_quit(int nargs, char **args) { (void) nargs; (void) args; vfs_sync(); sys_reboot(RB_POWEROFF); thread_exit(); return 0; }
static void txg_thread_exit(tx_state_t *tx, callb_cpr_t *cpr, kthread_t **tpp) { ASSERT(*tpp != NULL); *tpp = NULL; tx->tx_threads--; cv_broadcast(&tx->tx_exit_cv); CALLB_CPR_EXIT(cpr); /* drops &tx->tx_sync_lock */ thread_exit(); }
void exit(int status) { int i = 0; struct thread* t = thread_current(); // running thread structure struct file* f; t->exit_status = status; // save exit status printf("%s: exit(%d)\n",t->name,status); thread_exit(); }