void emancipate(int sig) { signal(sig, SIG_DFL); noitL(noit_error, "emancipate: process %d, monitored %d, signal %d\n", getpid(), noit_monitored_child_pid, sig); if(getpid() == watcher) { run_glider(noit_monitored_child_pid); kill(noit_monitored_child_pid, sig); } else if (getpid() == noit_monitored_child_pid){ it_ticks_crash(); /* slow notification path */ kill(noit_monitored_child_pid, SIGSTOP); /* stop and wait for a glide */ if(allow_async_dumps) { stop_other_threads(); /* suspend all peer threads... to safely */ close_all_fds(); /* close all our FDs */ it_ticks_crash_release(); /* notify parent that it can fork a new one */ /* the subsequent dump may take a while on big processes and slow disks */ } kill(noit_monitored_child_pid, sig); } }
/** thread routine for the thread which does unprotection of regions */ static void *unprot_thread(void *dummy_param) { unprot_thread_g = self_thread(); if(semaph_post(&init_sem_g)) { fprintf(stderr, "unprot_thread: can\'t post init semaphore\n"); return 0; } rqueue_elem_t elem; // the number of regions which have been unprotected, but have not yet been // synced to host unsigned pending_regions = 0; // starting and ending time for this time period rtime_t start_time, end_time; while(1) { rqueue_get(&unprot_queue_g, &elem); region_t *region = elem.region; switch(elem.op) { case REGION_OP_QUIT: // quit the thread return 0; case REGION_OP_UNPROTECT: //fprintf(stderr, "unprotect request received\n"); stat_inc(GPUVM_STAT_PAGEFAULTS); if(region->prot_status == PROT_NONE) { // fully unprotect region // remove protection, stop threads if necessary if(!pending_regions) { if(stat_enabled()) start_time = rtime_get(); //fprintf(stderr, "stopping other threads\n"); stop_other_threads(); //fprintf(stderr, "stopped other threads\n"); } region_unprotect(region); //fprintf(stderr, "unprotect request satisfied - BLOCK\n"); region_post_unprotect(region); pending_regions++; elem.op = REGION_OP_SYNC_TO_HOST; rqueue_put(&sync_queue_g, &elem); } else if(region->prot_status == PROT_READ) { // mark all data as actual on host only, no need to stop threads subreg_list_t *list; region_unprotect(region); for(list = region->subreg_list; list; list = list->next) subreg_sync_to_host(list->subreg); //fprintf(stderr, "unprotect request satisfied - RO\n"); region_post_unprotect(region); } else { // do nothing //fprintf(stderr, "unprotect request satisfied - NONE\n"); region_post_unprotect(region); } //fprintf(stderr, "unprotect message posted\n"); break; case REGION_OP_SYNCED_TO_HOST: pending_regions--; if(!pending_regions) { //fprintf(stderr, "continuing other threads\n"); cont_other_threads(); if(stat_enabled()) { end_time = rtime_get(); stat_acc_unblocked_double(GPUVM_STAT_PAGEFAULT_TIME, rtime_diff(&start_time, &end_time)); } } // if(!pending_regions) break; default: fprintf(stderr, "unprot_thread: invalid region operation %d\n", elem.op); break; } // switch(elem->op) } // while() } // unprot_thread()