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

Side by Side Diff: Source/core/workers/WorkerThreadTest.cpp

Issue 1128093003: Revert of Schedule garbage collection on worker threads using idle tasks (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/workers/WorkerThread.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/workers/WorkerThread.h" 6 #include "core/workers/WorkerThread.h"
7 7
8 #include "core/inspector/ConsoleMessage.h" 8 #include "core/inspector/ConsoleMessage.h"
9 #include "core/workers/WorkerReportingProxy.h" 9 #include "core/workers/WorkerReportingProxy.h"
10 #include "core/workers/WorkerThreadStartupData.h" 10 #include "core/workers/WorkerThreadStartupData.h"
11 #include "platform/NotImplemented.h" 11 #include "platform/NotImplemented.h"
12 #include "public/platform/WebScheduler.h"
13 #include "public/platform/WebWaitableEvent.h" 12 #include "public/platform/WebWaitableEvent.h"
14 #include <gmock/gmock.h> 13 #include <gmock/gmock.h>
15 #include <gtest/gtest.h> 14 #include <gtest/gtest.h>
16 15
17 using testing::_; 16 using testing::_;
18 using testing::Invoke; 17 using testing::Invoke;
19 using testing::Return; 18 using testing::Return;
20 using testing::Mock; 19 using testing::Mock;
21 20
22 namespace blink { 21 namespace blink {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 90 }
92 91
93 ~WorkerThreadForTest() override { } 92 ~WorkerThreadForTest() override { }
94 93
95 // WorkerThread implementation: 94 // WorkerThread implementation:
96 WebThreadSupportingGC& backingThread() override 95 WebThreadSupportingGC& backingThread() override
97 { 96 {
98 return *m_thread; 97 return *m_thread;
99 } 98 }
100 99
101 MOCK_METHOD1(doIdleGc, bool(double deadlineSeconds));
102
103 PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr <WorkerThreadStartupData> startupData) override 100 PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr <WorkerThreadStartupData> startupData) override
104 { 101 {
105 return adoptRefWillBeNoop(new FakeWorkerGlobalScope(startupData->m_scrip tURL, startupData->m_userAgent, this, startupData->m_starterOrigin, startupData- >m_workerClients.release())); 102 return adoptRefWillBeNoop(new FakeWorkerGlobalScope(startupData->m_scrip tURL, startupData->m_userAgent, this, startupData->m_starterOrigin, startupData- >m_workerClients.release()));
106 } 103 }
107 104
108 private: 105 private:
109 OwnPtr<WebThreadSupportingGC> m_thread; 106 OwnPtr<WebThreadSupportingGC> m_thread;
110 }; 107 };
111 108
112 class WakeupTask : public WebThread::Task {
113 public:
114 WakeupTask() { }
115
116 ~WakeupTask() override { }
117
118 void run() override { }
119 };
120
121 class PostDelayedWakeupTask : public WebThread::Task {
122 public:
123 PostDelayedWakeupTask(WebScheduler* scheduler, long long delay) : m_schedule r(scheduler), m_delay(delay) { }
124
125 ~PostDelayedWakeupTask() override { }
126
127 void run() override
128 {
129 m_scheduler->postTimerTask(FROM_HERE, new WakeupTask(), m_delay);
130 }
131
132 WebScheduler* m_scheduler; // Not owned.
133 long long m_delay;
134 };
135
136 class SignalTask : public WebThread::Task { 109 class SignalTask : public WebThread::Task {
137 public: 110 public:
138 SignalTask(WebWaitableEvent* completionEvent) : m_completionEvent(completion Event) { } 111 SignalTask(WebWaitableEvent* completionEvent) : m_completionEvent(completion Event) { }
139 112
140 ~SignalTask() override { } 113 ~SignalTask() override { }
141 114
142 void run() override 115 void run() override
143 { 116 {
144 m_completionEvent->signal(); 117 m_completionEvent->signal();
145 } 118 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 154
182 void startAndWaitForInit() 155 void startAndWaitForInit()
183 { 156 {
184 OwnPtr<WebWaitableEvent> completionEvent = adoptPtr(Platform::current()- >createWaitableEvent()); 157 OwnPtr<WebWaitableEvent> completionEvent = adoptPtr(Platform::current()- >createWaitableEvent());
185 158
186 m_workerThread->start(); 159 m_workerThread->start();
187 m_workerThread->backingThread().postTask(FROM_HERE, new SignalTask(compl etionEvent.get())); 160 m_workerThread->backingThread().postTask(FROM_HERE, new SignalTask(compl etionEvent.get()));
188 completionEvent->wait(); 161 completionEvent->wait();
189 } 162 }
190 163
191 void postWakeUpTask(long long waitMs)
192 {
193 WebScheduler* scheduler = m_workerThread->backingThread().platformThread ().scheduler();
194
195 // The idle task will get posted on an after wake up queue, so we need a nother task
196 // posted at the right time to wake the system up. We don't know the ri ght delay here
197 // since the thread can take a variable length of time to be responsive, however this
198 // isn't a problem when posting a delayed task from within a task on the worker thread.
199 scheduler->postLoadingTask(FROM_HERE, new PostDelayedWakeupTask(schedule r, waitMs));
200 }
201
202 protected: 164 protected:
203 void ExpectWorkerLifetimeReportingCalls() 165 void ExpectWorkerLifetimeReportingCalls()
204 { 166 {
205 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1); 167 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1);
206 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1); 168 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1);
207 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1); 169 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1);
208 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1); 170 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1);
209 } 171 }
210 172
211 RefPtr<SecurityOrigin> m_securityOrigin; 173 RefPtr<SecurityOrigin> m_securityOrigin;
212 OwnPtr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider; 174 OwnPtr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider;
213 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; 175 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy;
214 RefPtr<WorkerThreadForTest> m_workerThread; 176 RefPtr<WorkerThreadForTest> m_workerThread;
215 }; 177 };
216 178
217 TEST_F(WorkerThreadTest, StartAndStop) 179 TEST_F(WorkerThreadTest, StartAndStop)
218 { 180 {
219 startAndWaitForInit(); 181 startAndWaitForInit();
220 m_workerThread->terminateAndWait(); 182 m_workerThread->terminateAndWait();
221 } 183 }
222 184
223 TEST_F(WorkerThreadTest, GcOccursWhileIdle)
224 {
225 OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitab leEvent());
226
227 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke(
228 [&gcDone](double)
229 {
230 gcDone->signal();
231 return false;
232 }));
233
234 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1);
235
236 startAndWaitForInit();
237 postWakeUpTask(310ul); // 10ms after the quiescent period ends.
238
239 gcDone->wait();
240 m_workerThread->terminateAndWait();
241 };
242
243 class RepeatingTask : public WebThread::Task {
244 public:
245 RepeatingTask(WebScheduler* scheduler, WebWaitableEvent* completion)
246 : RepeatingTask(scheduler, completion, 0) { }
247
248 ~RepeatingTask() override { }
249
250 void run() override
251 {
252 m_taskCount++;
253 if (m_taskCount == 10)
254 m_completion->signal();
255
256 m_scheduler->postTimerTask(
257 FROM_HERE, new RepeatingTask(m_scheduler, m_completion, m_taskCount) , 50ul);
258 m_scheduler->postLoadingTask(FROM_HERE, new WakeupTask());
259
260 }
261
262 private:
263 RepeatingTask(WebScheduler* scheduler, WebWaitableEvent* completion, int tas kCount)
264 : m_scheduler(scheduler)
265 , m_completion(completion)
266 , m_taskCount(taskCount)
267 { }
268
269 WebScheduler* m_scheduler; // Not owned.
270 WebWaitableEvent* m_completion;
271 int m_taskCount;
272 };
273
274 TEST_F(WorkerThreadTest, GcDoesNotOccurIfGapBetweenDelayedTasksIsTooSmall)
275 {
276 OwnPtr<WebWaitableEvent> completion = adoptPtr(Platform::current()->createWa itableEvent());
277
278 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(0);
279
280 startAndWaitForInit();
281
282 WebScheduler* scheduler = m_workerThread->backingThread().platformThread().s cheduler();
283
284 // Post a repeating task that should prevent any GC from happening.
285 scheduler->postLoadingTask(FROM_HERE, new RepeatingTask(scheduler, completio n.get()));
286
287 completion->wait();
288
289 // Make sure doIdleGc has not been called by this stage.
290 Mock::VerifyAndClearExpectations(m_workerThread.get());
291
292 m_workerThread->terminateAndWait();
293 }
294
295 TEST_F(WorkerThreadTest, LongGcDeadline_NoFutureTasks)
296 {
297 OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitab leEvent());
298 double deadlineLength = 0;
299
300 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke(
301 [&gcDone, &deadlineLength](double deadline)
302 {
303 gcDone->signal();
304 deadlineLength = deadline -Platform::current()->monotonicallyIncreas ingTime();
305 return false;
306 }));
307
308 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1);
309
310 startAndWaitForInit();
311 postWakeUpTask(310ul);
312
313 gcDone->wait();
314
315 // The deadline should be close to 1s in duration if there are no tasks that need to run soon.
316 EXPECT_GT(deadlineLength, 0.9);
317
318 m_workerThread->terminateAndWait();
319 }
320
321 TEST_F(WorkerThreadTest, LongGcDeadline_NextTaskAfterIdlePeriod)
322 {
323 OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitab leEvent());
324 double deadlineLength = 0;
325
326 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke(
327 [&gcDone, &deadlineLength](double deadline)
328 {
329 gcDone->signal();
330 deadlineLength = deadline -Platform::current()->monotonicallyIncreas ingTime();
331 return false;
332 }));
333
334 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1);
335
336 startAndWaitForInit();
337 postWakeUpTask(310ul);
338 postWakeUpTask(675ul); // Task that runs shortly after the 50ms idle period ends.
339
340 gcDone->wait();
341
342 // The worker thread calls canExceedIdleDeadlineIfRequired which only consid ers if
343 // there are any delayed tasks scheduled for the current long idle period. Since the
344 // next task is in the following idle period, a long gc deadline is allowed.
345 EXPECT_GT(deadlineLength, 0.9);
346
347 m_workerThread->terminateAndWait();
348 }
349
350 TEST_F(WorkerThreadTest, ShortGcDeadline)
351 {
352 OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitab leEvent());
353 double deadlineLength = 0;
354
355 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke(
356 [&gcDone, &deadlineLength](double deadline)
357 {
358 gcDone->signal();
359 deadlineLength = deadline - Platform::current()->monotonicallyIncrea singTime();
360 return false;
361 }));
362
363 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1);
364
365 startAndWaitForInit();
366 postWakeUpTask(310ul);
367 postWakeUpTask(625ul); // Task that runs during the idle period.
368
369 gcDone->wait();
370
371 // The deadline should be < 50ms if there's a task that needs to run during the idle period.
372 EXPECT_LT(deadlineLength, 0.025);
373
374 m_workerThread->terminateAndWait();
375 }
376
377 } // namespace blink 185 } // namespace blink
OLDNEW
« 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