int memcpy_h2d (devapi_t *devapi, unsigned idev, void *tgt, void *src, size_t nbytes, size_t devoff) { // time API call rtime_t start_time, end_time; if(stat_enabled()) start_time = rtime_get(); sigprocmask(SIG_BLOCK, &devapi_block_sig_g, 0); int err = devapi->memcpy_h2d(idev, tgt, src, nbytes, devoff); sigprocmask(SIG_UNBLOCK, &devapi_block_sig_g, 0); if(stat_enabled()) { end_time = rtime_get(); stat_acc_double(GPUVM_STAT_HOST_COPY_TIME, rtime_diff(&start_time, &end_time)); } return err; } // memcpy_h2d
// Start all schedulers in the VM void machine::start(void) { // execute constants code execute_const_code(); deactivate_signals(); // Statistics sampling if(stat_enabled()) { // initiate alarm thread alarm_thread = new boost::thread(bind(&machine::slice_function, this)); } vm::All->ALL_THREADS[0]->start(); if(alarm_thread) { kill(getpid(), SIGUSR1); alarm_thread->join(); delete alarm_thread; alarm_thread = NULL; slices.write(get_stat_file(), sched_type, vm::All); } const bool will_print(show_database || dump_database); if(will_print) { if(show_database) vm::All->DATABASE->print_db(cout); if(dump_database) vm::All->DATABASE->dump_db(cout); } if(memory_statistics) { #ifdef MEMORY_STATISTICS cout << "Total memory in use: " << get_memory_in_use() / 1024 << "KB" << endl; cout << "Malloc()'s called: " << get_num_mallocs() << endl; #else cout << "Memory statistics support was not compiled in" << endl; #endif } }
/** 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()