зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset fc437d64c831 (bug 1486556) for breaking coordination between record/replay system and helper threads.
--HG-- extra : rebase_source : 6fd771863bd14d659661553667396458c9c24eec
This commit is contained in:
Родитель
1bb581bc8f
Коммит
d2583e1176
|
@ -2420,22 +2420,9 @@ HelperThread::threadLoop()
|
|||
cx.setHelperThread(this);
|
||||
JS_SetNativeStackQuota(&cx, HELPER_STACK_QUOTA);
|
||||
|
||||
if (mozilla::recordreplay::IsRecordingOrReplaying())
|
||||
mozilla::recordreplay::NotifyUnrecordedWait(WakeupAll);
|
||||
|
||||
while (!terminate) {
|
||||
MOZ_ASSERT(idle());
|
||||
|
||||
if (mozilla::recordreplay::IsRecordingOrReplaying()) {
|
||||
// Unlock the helper thread state lock before potentially
|
||||
// blocking while the main thread waits for all threads to
|
||||
// become idle. Otherwise we would need to see if we need to
|
||||
// block at every point where a helper thread acquires the
|
||||
// helper thread state lock.
|
||||
AutoUnlockHelperThreadState unlock(lock);
|
||||
mozilla::recordreplay::MaybeWaitForCheckpointSave();
|
||||
}
|
||||
|
||||
// The selectors may depend on the HelperThreadState not changing
|
||||
// between task selection and task execution, in particular, on new
|
||||
// tasks not being added (because of the lifo structure of the work
|
||||
|
@ -2445,6 +2432,19 @@ HelperThread::threadLoop()
|
|||
const TaskSpec* task = findHighestPriorityTask(lock);
|
||||
if (!task) {
|
||||
AUTO_PROFILER_LABEL("HelperThread::threadLoop::wait", IDLE);
|
||||
if (mozilla::recordreplay::IsRecordingOrReplaying()) {
|
||||
// Unlock the helper thread state lock before potentially
|
||||
// blocking while the main thread waits for all threads to
|
||||
// become idle. Otherwise we would need to see if we need to
|
||||
// block at every point where a helper thread acquires the
|
||||
// helper thread state lock.
|
||||
{
|
||||
AutoUnlockHelperThreadState unlock(lock);
|
||||
mozilla::recordreplay::MaybeWaitForCheckpointSave();
|
||||
}
|
||||
mozilla::recordreplay::NotifyUnrecordedWait(WakeupAll);
|
||||
}
|
||||
|
||||
HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -268,7 +268,8 @@ static inline bool HasDivergedFromRecording();
|
|||
//
|
||||
// The callback passed to NotifyUnrecordedWait will be invoked at most once
|
||||
// by the main thread whenever the main thread is waiting for other threads to
|
||||
// become idle.
|
||||
// become idle, and at most once after the call to NotifyUnrecordedWait if the
|
||||
// main thread is already waiting for other threads to become idle.
|
||||
//
|
||||
// The callback should poke the thread so that it is no longer blocked on the
|
||||
// resource. The thread must call MaybeWaitForCheckpointSave before blocking
|
||||
|
|
|
@ -478,6 +478,15 @@ void
|
|||
Thread::NotifyUnrecordedWait(const std::function<void()>& aCallback)
|
||||
{
|
||||
MonitorAutoLock lock(*gMonitor);
|
||||
if (mUnrecordedWaitCallback) {
|
||||
// Per the documentation for NotifyUnrecordedWait, we need to call the
|
||||
// routine after a notify, even if the routine has been called already
|
||||
// since the main thread started to wait for idle replay threads.
|
||||
mUnrecordedWaitNotified = false;
|
||||
} else {
|
||||
MOZ_RELEASE_ASSERT(!mUnrecordedWaitNotified);
|
||||
}
|
||||
|
||||
mUnrecordedWaitCallback = aCallback;
|
||||
|
||||
// The main thread might be able to make progress now by calling the routine
|
||||
|
|
Загрузка…
Ссылка в новой задаче