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

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

Issue 1130413003: Schedule garbage collection on worker threads using idle tasks (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebased. Created 5 years, 7 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
« no previous file with comments | « Source/core/workers/WorkerThread.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/workers/WorkerThreadTest.cpp
diff --git a/Source/core/workers/WorkerThreadTest.cpp b/Source/core/workers/WorkerThreadTest.cpp
index 5f9270a37db506064d5faf65a6e05adbe42f0fea..bf88997d26d2727d4dc6627a15632c17f5b3e738 100644
--- a/Source/core/workers/WorkerThreadTest.cpp
+++ b/Source/core/workers/WorkerThreadTest.cpp
@@ -9,6 +9,7 @@
#include "core/workers/WorkerReportingProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
#include "platform/NotImplemented.h"
+#include "public/platform/WebScheduler.h"
#include "public/platform/WebWaitableEvent.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -97,6 +98,8 @@ public:
return *m_thread;
}
+ MOCK_METHOD1(doIdleGc, bool(double deadlineSeconds));
+
PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData> startupData) override
{
return adoptRefWillBeNoop(new FakeWorkerGlobalScope(startupData->m_scriptURL, startupData->m_userAgent, this, startupData->m_starterOrigin, startupData->m_workerClients.release()));
@@ -106,6 +109,30 @@ private:
OwnPtr<WebThreadSupportingGC> m_thread;
};
+class WakeupTask : public WebThread::Task {
+public:
+ WakeupTask() { }
+
+ ~WakeupTask() override { }
+
+ void run() override { }
+};
+
+class PostDelayedWakeupTask : public WebThread::Task {
+public:
+ PostDelayedWakeupTask(WebScheduler* scheduler, long long delay) : m_scheduler(scheduler), m_delay(delay) { }
+
+ ~PostDelayedWakeupTask() override { }
+
+ void run() override
+ {
+ m_scheduler->postTimerTask(FROM_HERE, new WakeupTask(), m_delay);
+ }
+
+ WebScheduler* m_scheduler; // Not owned.
+ long long m_delay;
+};
+
class SignalTask : public WebThread::Task {
public:
SignalTask(WebWaitableEvent* completionEvent) : m_completionEvent(completionEvent) { }
@@ -161,6 +188,17 @@ public:
completionEvent->wait();
}
+ void postWakeUpTask(long long waitMs)
+ {
+ WebScheduler* scheduler = m_workerThread->backingThread().platformThread().scheduler();
+
+ // The idle task will get posted on an after wake up queue, so we need another task
+ // posted at the right time to wake the system up. We don't know the right delay here
+ // since the thread can take a variable length of time to be responsive, however this
+ // isn't a problem when posting a delayed task from within a task on the worker thread.
+ scheduler->postLoadingTask(FROM_HERE, new PostDelayedWakeupTask(scheduler, waitMs));
+ }
+
protected:
void ExpectWorkerLifetimeReportingCalls()
{
@@ -182,4 +220,76 @@ TEST_F(WorkerThreadTest, StartAndStop)
m_workerThread->terminateAndWait();
}
+TEST_F(WorkerThreadTest, GcOccursWhileIdle)
+{
+ OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitableEvent());
+
+ ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke(
+ [&gcDone](double)
+ {
+ gcDone->signal();
+ return false;
+ }));
+
+ EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1);
+
+ startAndWaitForInit();
+ postWakeUpTask(500ul);
+
+ gcDone->wait();
+ m_workerThread->terminateAndWait();
+};
+
+class RepeatingTask : public WebThread::Task {
+public:
+ RepeatingTask(WebScheduler* scheduler, WebWaitableEvent* completion)
+ : RepeatingTask(scheduler, completion, 0) { }
+
+ ~RepeatingTask() override { }
+
+ void run() override
+ {
+ m_taskCount++;
+ if (m_taskCount == 10)
+ m_completion->signal();
+
+ m_scheduler->postTimerTask(
+ FROM_HERE, new RepeatingTask(m_scheduler, m_completion, m_taskCount), 0ul);
+ m_scheduler->postLoadingTask(FROM_HERE, new WakeupTask());
+
+ }
+
+private:
+ RepeatingTask(WebScheduler* scheduler, WebWaitableEvent* completion, int taskCount)
+ : m_scheduler(scheduler)
+ , m_completion(completion)
+ , m_taskCount(taskCount)
+ { }
+
+ WebScheduler* m_scheduler; // Not owned.
+ WebWaitableEvent* m_completion;
+ int m_taskCount;
+};
+
+TEST_F(WorkerThreadTest, GcDoesNotOccurWhenNotIdle)
+{
+ OwnPtr<WebWaitableEvent> completion = adoptPtr(Platform::current()->createWaitableEvent());
+
+ EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(0);
+
+ startAndWaitForInit();
+
+ WebScheduler* scheduler = m_workerThread->backingThread().platformThread().scheduler();
+
+ // Post a repeating task that should prevent any GC from happening.
+ scheduler->postLoadingTask(FROM_HERE, new RepeatingTask(scheduler, completion.get()));
+
+ completion->wait();
+
+ // Make sure doIdleGc has not been called by this stage.
+ Mock::VerifyAndClearExpectations(m_workerThread.get());
+
+ m_workerThread->terminateAndWait();
+}
+
} // namespace blink
« no previous file with comments | « Source/core/workers/WorkerThread.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698