void erts_thr_progress_fatal_error_wait(SWord timeout) { erts_aint32_t bc; SWord time_left = timeout; ErtsMonotonicTime timeout_time; ErtsSchedulerData *esdp = erts_get_scheduler_data(); /* * Counting poll intervals may give us a too long timeout * if cpu is busy. We use timeout time to try to prevent * this. In case we havn't got time correction this may * however fail too... */ timeout_time = erts_get_monotonic_time(esdp); timeout_time += ERTS_MSEC_TO_MONOTONIC((ErtsMonotonicTime) timeout); while (1) { if (erts_milli_sleep(ERTS_THR_PRGR_FTL_ERR_BLCK_POLL_INTERVAL) == 0) time_left -= ERTS_THR_PRGR_FTL_ERR_BLCK_POLL_INTERVAL; bc = erts_atomic32_read_acqb(&intrnl->misc.data.block_count); if (bc == 0) break; /* Succefully blocked all managed threads */ if (time_left <= 0) break; /* Timeout */ if (timeout_time <= erts_get_monotonic_time(esdp)) break; /* Timeout */ } }
static int ms_wait(Process *c_p, Eterm etimeout, int busy) { ErtsSchedulerData *esdp = erts_proc_sched_data(c_p); ErtsMonotonicTime time, timeout_time; Sint64 ms; if (!term_to_Sint64(etimeout, &ms)) return 0; time = erts_get_monotonic_time(esdp); if (ms < 0) timeout_time = time; else timeout_time = time + ERTS_MSEC_TO_MONOTONIC(ms); while (time < timeout_time) { if (busy) erts_thr_yield(); else { ErtsMonotonicTime timeout = timeout_time - time; #ifdef __WIN32__ Sleep((DWORD) ERTS_MONOTONIC_TO_MSEC(timeout)); #else { ErtsMonotonicTime to = ERTS_MONOTONIC_TO_USEC(timeout); struct timeval tv; tv.tv_sec = (long) to / (1000*1000); tv.tv_usec = (long) to % (1000*1000); select(0, NULL, NULL, NULL, &tv); } #endif } time = erts_get_monotonic_time(esdp); } return 1; }