diff --git a/tools/profiler/platform-linux.cc b/tools/profiler/platform-linux.cc index e380a699ebf..85fef75fb33 100644 --- a/tools/profiler/platform-linux.cc +++ b/tools/profiler/platform-linux.cc @@ -631,19 +631,26 @@ void TickSample::PopulateContext(void* aContext) } } -// WARNING: Works with values up to 1 second void OS::SleepMicro(int microseconds) { + if (MOZ_UNLIKELY(microseconds >= 1000000)) { + // Use usleep for larger intervals, because the nanosleep + // code below only supports intervals < 1 second. + MOZ_ALWAYS_TRUE(!::usleep(microseconds)); + return; + } + struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = microseconds * 1000UL; - while (true) { - // in the case of interrupt we keep waiting - // nanosleep puts the remaining to back into ts - if (!nanosleep(&ts, &ts) || errno != EINTR) { - return; - } - } -} + int rv = ::nanosleep(&ts, &ts); + while (rv != 0 && errno == EINTR) { + // Keep waiting in case of interrupt. + // nanosleep puts the remaining time back into ts. + rv = ::nanosleep(&ts, &ts); + } + + MOZ_ASSERT(!rv, "nanosleep call failed"); +}