diff --git a/projects/clr/rocclr/thread/monitor.cpp b/projects/clr/rocclr/thread/monitor.cpp index 9c77f961dc..6c1e496682 100644 --- a/projects/clr/rocclr/thread/monitor.cpp +++ b/projects/clr/rocclr/thread/monitor.cpp @@ -251,7 +251,7 @@ void Monitor::wait() { } // now go to sleep else { - suspend.wait(); + suspend.timedWait(10); } spinCount++; } diff --git a/projects/clr/rocclr/thread/semaphore.cpp b/projects/clr/rocclr/thread/semaphore.cpp index 5e19be3e46..4b67e5fbfb 100644 --- a/projects/clr/rocclr/thread/semaphore.cpp +++ b/projects/clr/rocclr/thread/semaphore.cpp @@ -74,7 +74,7 @@ void Semaphore::post() { // We have threads waiting on this event. #ifdef _WIN32 ReleaseSemaphore(static_cast(handle_), 1, NULL); -#else // !_WIN32 +#else // !_WIN32 if (0 != sem_post(&sem_)) { fatal("sem_post() failed"); } @@ -100,4 +100,40 @@ void Semaphore::wait() { #endif // !_WIN32 } +void Semaphore::timedWait(int millis) { + if (state_-- > 0) { + return; + } + +#ifdef _WIN32 + DWORD status = WaitForSingleObject(static_cast(handle_), millis); + if (WAIT_OBJECT_0 != status && WAIT_TIMEOUT != status) { + fatal("WaitForSingleObject failed"); + } +#else // !_WIN32 + struct timespec ts; + + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + fatal("clock_gettime() failed"); + } + + ts.tv_sec += millis / 1000; + ts.tv_nsec += ((long)millis % 1000) * 1000000; + + if (ts.tv_nsec >= 1000000000) { + ts.tv_sec += 1; + ts.tv_nsec -= 1000000000; + } + + int status; + while ((status = sem_timedwait(&sem_, &ts)) != 0) { + if (ETIMEDOUT == errno) { + break; + } else if (EINTR != errno) { + fatal("sem_wait() failed"); + } + } +#endif // !_WIN32 +} + } // namespace amd diff --git a/projects/clr/rocclr/thread/semaphore.hpp b/projects/clr/rocclr/thread/semaphore.hpp index 975b3238f0..1554390443 100644 --- a/projects/clr/rocclr/thread/semaphore.hpp +++ b/projects/clr/rocclr/thread/semaphore.hpp @@ -58,6 +58,7 @@ public: //! \brief Decrement this semaphore void wait(); + void timedWait(int millis); //! \brief Increment this semaphore void post();