summaryrefslogtreecommitdiffstats
path: root/js/src/vm/HelperThreads.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/HelperThreads.cpp')
-rw-r--r--js/src/vm/HelperThreads.cpp45
1 files changed, 36 insertions, 9 deletions
diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp
index da8231c1dc..d50c9a134a 100644
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -889,25 +889,23 @@ void GlobalHelperThreadState::assertIsLockedByCurrentThread() const {
}
#endif // DEBUG
-void GlobalHelperThreadState::dispatch(
- DispatchReason reason, const AutoLockHelperThreadState& locked) {
- if (canStartTasks(locked) && tasksPending_ < threadCount) {
+void GlobalHelperThreadState::dispatch(DispatchReason reason,
+ const AutoLockHelperThreadState& lock) {
+ if (canStartTasks(lock) && tasksPending_ < threadCount) {
// This doesn't guarantee that we don't dispatch more tasks to the external
// pool than necessary if tasks are taking a long time to start, but it does
// limit the number.
tasksPending_++;
- // The hazard analysis can't tell that the callback doesn't GC.
- JS::AutoSuppressGCAnalysis nogc;
-
- dispatchTaskCallback(reason);
+ lock.queueTaskToDispatch(reason);
}
}
void GlobalHelperThreadState::wait(
- AutoLockHelperThreadState& locked,
+ AutoLockHelperThreadState& lock,
TimeDuration timeout /* = TimeDuration::Forever() */) {
- consumerWakeup.wait_for(locked, timeout);
+ MOZ_ASSERT(!lock.hasQueuedTasks());
+ consumerWakeup.wait_for(lock, timeout);
}
void GlobalHelperThreadState::notifyAll(const AutoLockHelperThreadState&) {
@@ -1534,6 +1532,10 @@ void js::RunPendingSourceCompressions(JSRuntime* runtime) {
HelperThreadState().startHandlingCompressionTasks(
GlobalHelperThreadState::ScheduleCompressionTask::API, nullptr, lock);
+ {
+ // Dispatch tasks.
+ AutoUnlockHelperThreadState unlock(lock);
+ }
// Wait until all tasks have started compression.
while (!HelperThreadState().compressionWorklist(lock).empty()) {
@@ -1735,3 +1737,28 @@ void GlobalHelperThreadState::runTaskLocked(HelperThreadTask* task,
js::oom::SetThreadType(js::THREAD_TYPE_NONE);
}
+
+void AutoHelperTaskQueue::queueTaskToDispatch(JS::DispatchReason reason) const {
+ // This is marked const because it doesn't release the mutex.
+
+ if (reason == JS::DispatchReason::FinishedTask) {
+ finishedTasksToDispatch++;
+ return;
+ }
+
+ newTasksToDispatch++;
+}
+
+void AutoHelperTaskQueue::dispatchQueuedTasks() {
+ // The hazard analysis can't tell that the callback doesn't GC.
+ JS::AutoSuppressGCAnalysis nogc;
+
+ for (size_t i = 0; i < newTasksToDispatch; i++) {
+ HelperThreadState().dispatchTaskCallback(JS::DispatchReason::NewTask);
+ }
+ for (size_t i = 0; i < finishedTasksToDispatch; i++) {
+ HelperThreadState().dispatchTaskCallback(JS::DispatchReason::FinishedTask);
+ }
+ newTasksToDispatch = 0;
+ finishedTasksToDispatch = 0;
+}