示例#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);
	}
}
示例#2
0
void spring_time::sleep()
{
    // for very short time intervals use a yielding loop (yield is ~5x more accurate than sleep(), check the UnitTest)
    if (toMilliSecsf() < (avgSleepErrMs + avgYieldMs * 5.0f)) {
        const spring_time s = gettime();
        while ((gettime() - s) < *this) {
            thread_yield();
        }
        return;
    }

    const spring_time expectedWakeUpTime = gettime() + *this;

#if defined(SPRINGTIME_USING_STD_SLEEP)
    this_thread::sleep_for(chrono::nanoseconds(toNanoSecsi()));
#else
    boost::this_thread::sleep(boost::posix_time::microseconds(std::ceil(toNanoSecsf() * 1e-3)));
#endif

    const float diffMs = (gettime() - expectedWakeUpTime).toMilliSecsf();
    avgSleepErrMs = avgSleepErrMs * 0.9f + diffMs * 0.1f;

    //if (diffMs > 7.0f) {
    //	LOG_L(L_WARNING, "SpringTime: used sleep() function is too inaccurate");
    //}
}
示例#3
0
void spring_time::sleep()
{
	// for very short time intervals use a yielding loop (yield is ~5x more accurate than sleep(), check the UnitTest)
	if (toMilliSecsf() < (avgThreadSleepTimeMilliSecs + avgThreadYieldTimeMilliSecs * 5.0f)) {
		const spring_time s = gettime();

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

		return;
	}

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

	#if defined(SPRINGTIME_USING_STD_SLEEP)
		this_thread::sleep_for(chrono::nanoseconds(toNanoSecsi()));
	#else
		boost::this_thread::sleep(boost::posix_time::microseconds(std::ceil(toNanoSecsf() * 1e-3)));
	#endif

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

	if (t1 >= t0) {
		boost::mutex::scoped_lock lock(sleepTimeMutex);
		avgThreadSleepTimeMilliSecs = mix(avgThreadSleepTimeMilliSecs, dt.toMilliSecsf(), 0.1f);
	}
}
示例#4
0
void spring_time::sleep_until()
{
#if defined(SPRINGTIME_USING_STD_SLEEP)
    auto tp = chrono::time_point<chrono::high_resolution_clock, chrono::nanoseconds>(chrono::nanoseconds(toNanoSecsi()));
    this_thread::sleep_until(tp);
#else
    spring_time napTime = gettime() - *this;

    if (napTime.toMilliSecsf() < avgYieldMs) {
        while (napTime.isTime()) {
            thread_yield();
            napTime = gettime() - *this;
        }
        return;
    }

    napTime.sleep();
#endif
}
示例#5
0
void spring_time::sleep_until()
{
	auto tp = chrono::time_point<chrono::high_resolution_clock, chrono::nanoseconds>(chrono::nanoseconds(toNanoSecsi()));
	this_thread::sleep_until(tp);
}