Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(969)

Unified Diff: Source/core/workers/WorkerThread.cpp

Issue 507873003: [Blink-Worker] WorkerThread fires idleHandler only at the end of processing all tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Implemented new idleHandler firing logic. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« Source/core/workers/WorkerThread.h ('K') | « Source/core/workers/WorkerThread.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/workers/WorkerThread.cpp
diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp
index 8832399a59bd08bf883af07249593c1d2ea2534f..6819793790d71efbfa2a69a30d9f7994bed03421 100644
--- a/Source/core/workers/WorkerThread.cpp
+++ b/Source/core/workers/WorkerThread.cpp
@@ -45,7 +45,7 @@
#include "public/platform/WebThread.h"
#include "public/platform/WebWaitableEvent.h"
#include "public/platform/WebWorkerRunLoop.h"
-#include "wtf/Noncopyable.h"
+#include "wtf/Atomics.h"
#include "wtf/text/WTFString.h"
#include <utility>
@@ -178,48 +178,50 @@ private:
WorkerThreadCancelableTask* m_lastQueuedTask;
};
-class WorkerThreadTask : public blink::WebThread::Task {
- WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
- {
- return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented));
- }
+// WorkerThreadTask made private to WorkerThread
- virtual ~WorkerThreadTask() { }
+PassOwnPtr<WorkerThread::WorkerThreadTask> WorkerThread::WorkerThreadTask::create(WorkerThread& workerThread
+ , PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
+{
+ return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented));
+}
- virtual void run() OVERRIDE
- {
- WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope();
- // Tasks could be put on the message loop after the cleanup task,
- // ensure none of those are ran.
- if (!workerGlobalScope)
- return;
+void WorkerThread::WorkerThreadTask::run()
+{
+ WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope();
+ // Tasks could be put on the message loop after the cleanup task,
+ // ensure none of those are ran.
+ if (!workerGlobalScope)
+ return;
- if (m_isInstrumented)
- InspectorInstrumentation::willPerformExecutionContextTask(workerGlobalScope, m_task.get());
- if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask())
+ if (m_isInstrumented)
+ InspectorInstrumentation::willPerformExecutionContextTask(workerGlobalScope, m_task.get());
+ if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask())
+ if (!m_isIdleHandlerTask || (m_isIdleHandlerTask && !m_workerThread.taskCount())) {
m_task->performTask(workerGlobalScope);
- if (m_isInstrumented)
- InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope);
- }
-
-private:
- WorkerThreadTask(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
- : m_workerThread(workerThread)
- , m_task(task)
- , m_isInstrumented(isInstrumented)
- {
- if (m_isInstrumented)
- m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty();
- if (m_isInstrumented)
- InspectorInstrumentation::didPostExecutionContextTask(m_workerThread.workerGlobalScope(), m_task.get());
- }
+ }
+ if (m_isInstrumented)
+ InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope);
+
+ // If no more tasks are queued up after this, then queue up the idleHandler
+ // to trigger GC.
+ if (!m_isIdleHandlerTask && !m_workerThread.decrementAndReturnTaskCount()
+ && !m_workerThread.m_IdleHandlerTaskPosted)
jochen (gone - plz use gerrit) 2014/10/14 13:46:03 nit. put on previous line
+ m_workerThread.queueUpIdleHandlerNow(kLongIdleHandlerDelayMs);
+}
- WorkerThread& m_workerThread;
- OwnPtr<ExecutionContextTask> m_task;
- bool m_isInstrumented;
-};
+WorkerThread::WorkerThreadTask::WorkerThreadTask(WorkerThread& workerThread
+ , PassOwnPtr<ExecutionContextTask> task, bool isInstrumented)
+ : m_workerThread(workerThread)
+ , m_task(task)
+ , m_isInstrumented(isInstrumented)
+ , m_isIdleHandlerTask(false)
+{
+ if (m_isInstrumented)
+ m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty();
+ if (m_isInstrumented)
+ InspectorInstrumentation::didPostExecutionContextTask(m_workerThread.workerGlobalScope(), m_task.get());
+}
class RunDebuggerQueueTask FINAL : public ExecutionContextTask {
public:
@@ -246,6 +248,8 @@ WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReporting
, m_startupData(startupData)
, m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()))
, m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()))
+ , m_IdleHandlerTaskPosted(false)
+ , m_tasksCount(0)
{
MutexLocker lock(threadSetMutex());
workerThreads().add(this);
@@ -321,8 +325,6 @@ void WorkerThread::initialize()
script->evaluate(ScriptSourceCode(sourceCode, scriptURL));
postInitialize();
-
- postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs);
}
void WorkerThread::cleanup()
@@ -459,29 +461,58 @@ bool WorkerThread::isCurrentThread() const
return m_thread && m_thread->isCurrentThread();
}
+void WorkerThread::queueUpIdleHandlerNow(long long delayMs)
+{
+ OwnPtr<WorkerThreadTask> idleHandlerTask = WorkerThreadTask::create(*this,
jochen (gone - plz use gerrit) 2014/10/14 13:46:03 nit, put on one line
Mayur Kankanwadi 2014/11/04 06:36:58 Done.
+ createSameThreadTask(&WorkerThread::idleHandler, this), true);
+ idleHandlerTask.get()->setIsIdleHandlerTask(true);
jochen (gone - plz use gerrit) 2014/10/14 13:46:03 should work without get()
Mayur Kankanwadi 2014/11/04 06:36:58 Done.
+ m_thread->postDelayedTask(idleHandlerTask.leakPtr(), delayMs);
+ m_IdleHandlerTaskPosted = true;
+}
+
void WorkerThread::idleHandler()
{
ASSERT(m_workerGlobalScope.get());
int64 delay = kLongIdleHandlerDelayMs;
+ // Some tasks may have been started in the mean time, so lets return back
+ // and wait for the next idleHandler to be fired.
+ if (m_tasksCount) {
+ m_IdleHandlerTaskPosted = false;
jochen (gone - plz use gerrit) 2014/10/14 13:46:03 nit. move this up outside the if()
Mayur Kankanwadi 2014/11/04 06:36:58 Done.
+ return;
+ }
// Do a script engine idle notification if the next event is distant enough.
const double kMinIdleTimespan = 0.3;
+ // This is set to true when idleNotification returns false.
+ // idleNotification returns false only when more GC is required. It returns
+ // true if no more GC is required and that is when callGCAgain will be set to false.
+ bool callGCAgain = false;
if (m_sharedTimer->nextFireTime() == 0.0 || m_sharedTimer->nextFireTime() > currentTime() + kMinIdleTimespan) {
- bool hasMoreWork = !m_workerGlobalScope->idleNotification();
- if (hasMoreWork)
+ callGCAgain = !m_workerGlobalScope->idleNotification();
+ if (callGCAgain)
delay = kShortIdleHandlerDelayMs;
}
+ if (callGCAgain)
+ queueUpIdleHandlerNow(delay);
jochen (gone - plz use gerrit) 2014/10/14 13:46:03 should be 0
+ else
+ m_IdleHandlerTaskPosted = false;
jochen (gone - plz use gerrit) 2014/10/14 13:46:03 not needed anymore after the one above is mvoed
Mayur Kankanwadi 2014/11/04 06:36:58 Done.
+}
- postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), delay);
+int WorkerThread::decrementAndReturnTaskCount()
+{
+ atomicDecrement(&m_tasksCount);
+ return m_tasksCount;
}
void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task)
{
+ atomicIncrement(&m_tasksCount);
m_thread->postTask(WorkerThreadTask::create(*this, task, true).leakPtr());
}
void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long long delayMs)
{
+ atomicIncrement(&m_tasksCount);
m_thread->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPtr(), delayMs);
}
« Source/core/workers/WorkerThread.h ('K') | « Source/core/workers/WorkerThread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698