Periodically wake up the thread in monitor::wait
There is a small window where a thread can go to sleep in
Monitor::wait after releasing the lock but before another thread
notifies the monitor and updates the on-deck thread.
A simple approach to fix this problem is to wake-up the Monitor::wait
every 10 milliseconds and check if it is on-deck.
Change-Id: I4b9abda89d1fc653cdae2b4c84cdda01efde1cf2
[ROCm/clr commit: 5079410c94]
这个提交包含在:
@@ -251,7 +251,7 @@ void Monitor::wait() {
|
||||
}
|
||||
// now go to sleep
|
||||
else {
|
||||
suspend.wait();
|
||||
suspend.timedWait(10);
|
||||
}
|
||||
spinCount++;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ void Semaphore::post() {
|
||||
// We have threads waiting on this event.
|
||||
#ifdef _WIN32
|
||||
ReleaseSemaphore(static_cast<HANDLE>(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>(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
|
||||
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
|
||||
//! \brief Decrement this semaphore
|
||||
void wait();
|
||||
void timedWait(int millis);
|
||||
|
||||
//! \brief Increment this semaphore
|
||||
void post();
|
||||
|
||||
在新工单中引用
屏蔽一个用户