/* * nk_thread_exit * * exit from this thread * * @retval: the value to return to the parent * * If there is someone waiting on this thread, this * function will wake them up. This will also call * any destructors for thread local storage * */ void nk_thread_exit (void * retval) { nk_thread_t * me = get_cur_thread(); /* clear any thread local storage that may have been allocated */ tls_exit(); while (__sync_lock_test_and_set(&me->lock, 1)); /* wait for my children to finish */ nk_join_all_children(NULL); me->output = retval; me->status = NK_THR_EXITED; /* wake up everyone who is waiting on me */ nk_wake_waiters(); me->refcount--; SCHED_DEBUG("Thread %p (tid=%u) exiting, joining with children\n", me, me->tid); __sync_lock_release(&me->lock); cli(); nk_schedule(); /* we should never get here! */ panic("Should never get here!\n"); }
/* * Called once (from main) to clean up STM infrastructure. */ _CALLCONV void stm_exit(void) { PRINT_DEBUG("==> stm_exit()\n"); if (!_tinystm.initialized) return; tls_exit(); stm_quiesce_exit(); #ifdef EPOCH_GC gc_exit(); #endif /* EPOCH_GC */ _tinystm.initialized = 0; }
/* * Called once (from main) to clean up STM infrastructure. */ _CALLCONV void stm_exit(void) { PRINT_DEBUG("==> stm_exit()\n"); if (!_tinystm.initialized) return; tls_exit(); stm_quiesce_exit(); # ifdef STM_F2C2 char filename[512]; int cpu_id=0, fd; for (cpu_id=0; cpu_id<sysconf(_SC_NPROCESSORS_CONF); cpu_id++) { sprintf(filename, "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_setspeed",cpu_id); //printf("Filename: %s", filename); fd=open(filename, O_WRONLY); if(fd==-1){ printf("\nError opening file %s", filename); exit(1); } char target_freq[]="800000"; write(fd, &target_freq, sizeof(target_freq)); close(fd); } if (semctl(semid, 0, IPC_RMID) < 0) { printf("\nCould not delete semaphore"); } #endif /* STM_F2C2 */ #ifdef EPOCH_GC gc_exit(); #endif /* EPOCH_GC */ _tinystm.initialized = 0; }