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

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

Issue 956333002: Refactor TimeBase to post tasks. Workers to use real Idle tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Now uses the WebThread's WebScheduler Created 5 years, 8 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
Index: Source/core/workers/WorkerThread.cpp
diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp
index 2aca66e16137532daf87b69df63db26681759046..a0778a001360ed3aeab51e897cafa49629943e21 100644
--- a/Source/core/workers/WorkerThread.cpp
+++ b/Source/core/workers/WorkerThread.cpp
@@ -38,13 +38,12 @@
#include "core/workers/WorkerClients.h"
#include "core/workers/WorkerReportingProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
-#include "platform/PlatformThreadData.h"
#include "platform/Task.h"
-#include "platform/ThreadTimers.h"
#include "platform/heap/SafePoint.h"
#include "platform/heap/ThreadState.h"
#include "platform/weborigin/KURL.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebScheduler.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebWaitableEvent.h"
#include "wtf/Noncopyable.h"
@@ -54,8 +53,6 @@
namespace blink {
namespace {
-const int64_t kShortIdleHandlerDelayMs = 1000;
-const int64_t kLongIdleHandlerDelayMs = 10*1000;
class MicrotaskRunner : public WebThread::TaskObserver {
public:
@@ -131,69 +128,6 @@ private:
bool m_taskCanceled;
};
-class WorkerSharedTimer : public SharedTimer {
-public:
- explicit WorkerSharedTimer(WorkerThread* workerThread)
- : m_workerThread(workerThread)
- , m_running(false)
- { }
-
- typedef void (*SharedTimerFunction)();
- virtual void setFiredFunction(SharedTimerFunction func)
- {
- m_sharedTimerFunction = func;
- }
-
- virtual void setFireInterval(double interval)
- {
- ASSERT(m_sharedTimerFunction);
-
- // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of
- // why ceil is used in the interval calculation.
- int64_t delay = static_cast<int64_t>(ceil(interval * 1000));
-
- if (delay < 0) {
- delay = 0;
- }
-
- m_running = true;
-
- if (m_lastQueuedTask.get())
- m_lastQueuedTask->cancelTask();
-
- // Now queue the task as a cancellable one.
- OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::create(bind(&WorkerSharedTimer::OnTimeout, this));
- m_lastQueuedTask = task->createWeakPtr();
- m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay);
- }
-
- virtual void stop()
- {
- m_running = false;
- m_lastQueuedTask = nullptr;
- }
-
-private:
- void OnTimeout()
- {
- ASSERT(m_workerThread->workerGlobalScope());
-
- m_lastQueuedTask = nullptr;
-
- if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalScope()->isClosing())
- m_sharedTimerFunction();
- }
-
- WorkerThread* m_workerThread;
- SharedTimerFunction m_sharedTimerFunction;
- bool m_running;
-
- // The task to run OnTimeout, if any. While OnTimeout resets
- // m_lastQueuedTask, this must be a weak pointer because the
- // worker runloop may delete the task as it is shutting down.
- WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask;
-};
-
class WorkerThreadTask : public blink::WebThread::Task {
WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThreadTask);
public:
@@ -264,6 +198,7 @@ WorkerThread::WorkerThread(const char* threadName, PassRefPtr<WorkerLoaderProxy>
, m_isolate(nullptr)
, m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()))
, m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()))
+ , m_webScheduler(nullptr)
{
MutexLocker lock(threadSetMutex());
workerThreads().add(this);
@@ -299,6 +234,22 @@ PlatformThreadId WorkerThread::platformThreadId() const
return m_thread->platformThread().threadId();
}
+class WorkerThreadIdleTask : public WebThread::IdleTask {
+public:
+ explicit WorkerThreadIdleTask(WorkerThread* thread)
+ : m_thread(thread) { }
+
+ ~WorkerThreadIdleTask() override { }
+
+ void run(double deadlineSeconds) override
+ {
+ m_thread->idleTask(deadlineSeconds);
+ }
+
+private:
+ RawPtr<WorkerThread> m_thread;
+};
+
void WorkerThread::initialize()
{
KURL scriptURL = m_startupData->m_scriptURL;
@@ -325,8 +276,6 @@ void WorkerThread::initialize()
m_isolate = initializeIsolate();
m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release());
m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.get() ? cachedMetaData->size() : 0);
-
- PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this)));
}
// The corresponding call to stopRunLoop() is in ~WorkerScriptController().
@@ -348,7 +297,8 @@ void WorkerThread::initialize()
postInitialize();
- postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs);
+ m_webScheduler = m_thread->platformThread().scheduler();
+ m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask(this));
Sami 2015/04/16 14:23:38 There's no way this can run after this thread obje
alex clarke (OOO till 29th) 2015/04/16 17:20:01 I don't think so because when the thread goes away
}
PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC()
@@ -381,9 +331,6 @@ void WorkerThread::cleanup()
workerReportingProxy().workerThreadTerminated();
m_terminationEvent->signal();
-
- // Clean up PlatformThreadData before WTF::WTFThreadData goes away!
- PlatformThreadData::current().destroy();
}
class WorkerThreadShutdownFinishTask : public ExecutionContextTask {
@@ -418,7 +365,6 @@ public:
{
WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
workerGlobalScope->stopActiveDOMObjects();
- PlatformThreadData::current().threadTimers().setSharedTimer(nullptr);
// Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
// which become dangling once Heap is destroyed.
@@ -510,21 +456,28 @@ bool WorkerThread::isCurrentThread() const
return m_thread && m_thread->isCurrentThread();
}
-void WorkerThread::idleHandler()
+void WorkerThread::idleTask(double deadlineSeconds)
{
- ASSERT(m_workerGlobalScope.get());
- int64_t delay = kLongIdleHandlerDelayMs;
+ double gcDeadlineSeconds = deadlineSeconds;
+
+ // The V8 GC does some GC steps (e.g. compaction) only when the idle notification is ~1s.
+ // TODO(rmcilroy): Refactor so extending the deadline like this this isn't needed.
+ if (m_webScheduler->canExceedIdleDeadlineIfRequired())
+ gcDeadlineSeconds = Platform::current()->monotonicallyIncreasingTime() + 1.0;
- // Do a script engine idle notification if the next event is distant enough.
- const double kMinIdleTimespan = 0.3;
- const double nextFireTime = PlatformThreadData::current().threadTimers().nextFireTime();
- if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) {
- bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::current()->monotonicallyIncreasingTime() + 1.0);
- if (hasMoreWork)
- delay = kShortIdleHandlerDelayMs;
+ if (doIdleGc(gcDeadlineSeconds))
+ m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask(this));
+ else
+ m_webScheduler->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this));
+}
+
+bool WorkerThread::doIdleGc(double deadlineSeconds)
+{
+ if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) {
+ return isolate()->IdleNotificationDeadline(deadlineSeconds);
}
- postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay);
+ return false;
}
void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task)

Powered by Google App Engine
This is Rietveld 408576698