Example #1
0
void spring_time::sleep(bool forceThreadSleep)
{
	if (forceThreadSleep) {
		spring::this_thread::sleep_for(chrono::nanoseconds(toNanoSecsi()));
		return;
	}


	// for very short time intervals use a yielding loop (yield is ~5x more accurate than sleep(), check the UnitTest)
	if (toMicroSecsi() < (avgThreadSleepTimeMicroSecs + avgThreadYieldTimeMicroSecs * 5)) {
		const spring_time s = gettime();

		while ((gettime() - s) < *this)
			thread_yield();

		return;
	}

	// expected wakeup time
	const spring_time t0 = gettime() + *this;

	spring::this_thread::sleep_for(chrono::nanoseconds(toNanoSecsi()));

	const spring_time t1 = gettime();
	const spring_time dt = t1 - t0;

	if (t1 >= t0) {
		// yes, it's not 100% thread correct, but it's okay when 1 of 1 million writes is dropped
		int avg = avgThreadSleepTimeMicroSecs.load();
		int newAvg = mix<float>(avg, dt.toMicroSecsf(), 0.1f);
		avgThreadSleepTimeMicroSecs.store(newAvg);
	}
}
Example #2
0
static void thread_yield()
{
	const spring_time t0 = spring_time::gettime();
	this_thread::yield();
	const spring_time t1 = spring_time::gettime();
	const spring_time dt = t1 - t0;

	if (t1 >= t0) {
		// yes, it's not 100% thread correct, but it's okay when 1 of 1 million writes is dropped
		int avg = avgThreadYieldTimeMicroSecs.load();
		int newAvg = mix<float>(avg, dt.toMicroSecsf(), 0.1f);
		avgThreadYieldTimeMicroSecs.store(newAvg);
	}
}