[threading linux] Fix nanosleep using microseconds

Add Sleep Test for 50ms.
Fix Sleep under linux that was using microseconds as nanoseconds.
Factor timespec creation to template function using div/mod and nanoseconds
from duration cast.
This commit is contained in:
Sandy Carter 2018-03-11 14:48:55 -04:00 committed by Rick Gibbed
parent 6c79c93f2b
commit d8d8a7dbb8
2 changed files with 16 additions and 4 deletions

View File

@ -15,6 +15,7 @@ namespace xe {
namespace base { namespace base {
namespace test { namespace test {
using namespace threading; using namespace threading;
using namespace std::chrono_literals;
TEST_CASE("Fence") { TEST_CASE("Fence") {
// TODO(bwrsandman): // TODO(bwrsandman):
@ -43,8 +44,11 @@ TEST_CASE("Sync with Memory Barrier", "SyncMemory") {
} }
TEST_CASE("Sleep Current Thread", "Sleep") { TEST_CASE("Sleep Current Thread", "Sleep") {
// TODO(bwrsandman): auto wait_time = 50ms;
REQUIRE(true); auto start = std::chrono::steady_clock::now();
Sleep(wait_time);
auto duration = std::chrono::steady_clock::now() - start;
REQUIRE(duration >= wait_time);
} }
TEST_CASE("Sleep Current Thread in Alertable State", "Sleep") { TEST_CASE("Sleep Current Thread in Alertable State", "Sleep") {

View File

@ -23,6 +23,15 @@
namespace xe { namespace xe {
namespace threading { namespace threading {
template <typename _Rep, typename _Period>
inline timespec DurationToTimeSpec(
std::chrono::duration<_Rep, _Period> duration) {
auto nanoseconds =
std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
auto div = ldiv(nanoseconds.count(), 1000000000L);
return timespec{div.quot, div.rem};
}
// TODO(dougvj) // TODO(dougvj)
void EnableAffinityConfiguration() {} void EnableAffinityConfiguration() {}
@ -47,8 +56,7 @@ void MaybeYield() {
void SyncMemory() { __sync_synchronize(); } void SyncMemory() { __sync_synchronize(); }
void Sleep(std::chrono::microseconds duration) { void Sleep(std::chrono::microseconds duration) {
timespec rqtp = {time_t(duration.count() / 1000000), timespec rqtp = DurationToTimeSpec(duration);
time_t(duration.count() % 1000)};
nanosleep(&rqtp, nullptr); nanosleep(&rqtp, nullptr);
// TODO(benvanik): spin while rmtp >0? // TODO(benvanik): spin while rmtp >0?
} }