forked from mirrors/gecko-dev
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:
parent
1bb581bc8f
commit
d2583e1176
3 changed files with 24 additions and 14 deletions
|
|
@ -2420,22 +2420,9 @@ HelperThread::threadLoop()
|
||||||
cx.setHelperThread(this);
|
cx.setHelperThread(this);
|
||||||
JS_SetNativeStackQuota(&cx, HELPER_STACK_QUOTA);
|
JS_SetNativeStackQuota(&cx, HELPER_STACK_QUOTA);
|
||||||
|
|
||||||
if (mozilla::recordreplay::IsRecordingOrReplaying())
|
|
||||||
mozilla::recordreplay::NotifyUnrecordedWait(WakeupAll);
|
|
||||||
|
|
||||||
while (!terminate) {
|
while (!terminate) {
|
||||||
MOZ_ASSERT(idle());
|
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
|
// The selectors may depend on the HelperThreadState not changing
|
||||||
// between task selection and task execution, in particular, on new
|
// between task selection and task execution, in particular, on new
|
||||||
// tasks not being added (because of the lifo structure of the work
|
// tasks not being added (because of the lifo structure of the work
|
||||||
|
|
@ -2445,6 +2432,19 @@ HelperThread::threadLoop()
|
||||||
const TaskSpec* task = findHighestPriorityTask(lock);
|
const TaskSpec* task = findHighestPriorityTask(lock);
|
||||||
if (!task) {
|
if (!task) {
|
||||||
AUTO_PROFILER_LABEL("HelperThread::threadLoop::wait", IDLE);
|
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);
|
HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,8 @@ static inline bool HasDivergedFromRecording();
|
||||||
//
|
//
|
||||||
// The callback passed to NotifyUnrecordedWait will be invoked at most once
|
// 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
|
// 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
|
// The callback should poke the thread so that it is no longer blocked on the
|
||||||
// resource. The thread must call MaybeWaitForCheckpointSave before blocking
|
// resource. The thread must call MaybeWaitForCheckpointSave before blocking
|
||||||
|
|
|
||||||
|
|
@ -478,6 +478,15 @@ void
|
||||||
Thread::NotifyUnrecordedWait(const std::function<void()>& aCallback)
|
Thread::NotifyUnrecordedWait(const std::function<void()>& aCallback)
|
||||||
{
|
{
|
||||||
MonitorAutoLock lock(*gMonitor);
|
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;
|
mUnrecordedWaitCallback = aCallback;
|
||||||
|
|
||||||
// The main thread might be able to make progress now by calling the routine
|
// The main thread might be able to make progress now by calling the routine
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue