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

Side by Side Diff: base/task_scheduler/scheduler_worker_thread_unittest.cc

Issue 2044023003: Virtualize The Existence of a Scheduler Worker Thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@detach
Patch Set: CR Feedback Created 4 years, 6 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "base/task_scheduler/scheduler_worker_thread.h" 5 #include "base/task_scheduler/scheduler_worker_thread.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <vector> 10 #include <vector>
(...skipping 23 matching lines...) Expand all
34 : main_entry_called_(WaitableEvent::ResetPolicy::MANUAL, 34 : main_entry_called_(WaitableEvent::ResetPolicy::MANUAL,
35 WaitableEvent::InitialState::NOT_SIGNALED), 35 WaitableEvent::InitialState::NOT_SIGNALED),
36 num_get_work_cv_(lock_.CreateConditionVariable()), 36 num_get_work_cv_(lock_.CreateConditionVariable()),
37 worker_thread_set_(WaitableEvent::ResetPolicy::MANUAL, 37 worker_thread_set_(WaitableEvent::ResetPolicy::MANUAL,
38 WaitableEvent::InitialState::NOT_SIGNALED) {} 38 WaitableEvent::InitialState::NOT_SIGNALED) {}
39 39
40 void SetUp() override { 40 void SetUp() override {
41 worker_thread_ = SchedulerWorkerThread::Create( 41 worker_thread_ = SchedulerWorkerThread::Create(
42 ThreadPriority::NORMAL, 42 ThreadPriority::NORMAL,
43 WrapUnique(new TestSchedulerWorkerThreadDelegate(this)), 43 WrapUnique(new TestSchedulerWorkerThreadDelegate(this)),
44 &task_tracker_); 44 &task_tracker_,
45 SchedulerWorkerThread::InitialWorkerState::ALIVE);
45 ASSERT_TRUE(worker_thread_); 46 ASSERT_TRUE(worker_thread_);
46 worker_thread_set_.Signal(); 47 worker_thread_set_.Signal();
47 main_entry_called_.Wait(); 48 main_entry_called_.Wait();
48 } 49 }
49 50
50 void TearDown() override { 51 void TearDown() override {
51 worker_thread_->JoinForTesting(); 52 worker_thread_->JoinForTesting();
52 } 53 }
53 54
54 size_t TasksPerSequence() const { return GetParam(); } 55 size_t TasksPerSequence() const { return GetParam(); }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 AutoSchedulerLock auto_lock(outer_->lock_); 166 AutoSchedulerLock auto_lock(outer_->lock_);
166 outer_->re_enqueued_sequences_.push_back(std::move(sequence)); 167 outer_->re_enqueued_sequences_.push_back(std::move(sequence));
167 EXPECT_LE(outer_->re_enqueued_sequences_.size(), 168 EXPECT_LE(outer_->re_enqueued_sequences_.size(),
168 outer_->created_sequences_.size()); 169 outer_->created_sequences_.size());
169 } 170 }
170 171
171 TimeDelta GetSleepTimeout() override { 172 TimeDelta GetSleepTimeout() override {
172 return TimeDelta::Max(); 173 return TimeDelta::Max();
173 } 174 }
174 175
176 bool CanDetach(SchedulerWorkerThread* worker_thread) override {
177 return false;
178 }
179
175 private: 180 private:
176 TaskSchedulerWorkerThreadTest* outer_; 181 TaskSchedulerWorkerThreadTest* outer_;
177 }; 182 };
178 183
179 void RunTaskCallback() { 184 void RunTaskCallback() {
180 AutoSchedulerLock auto_lock(lock_); 185 AutoSchedulerLock auto_lock(lock_);
181 ++num_run_tasks_; 186 ++num_run_tasks_;
182 EXPECT_LE(num_run_tasks_, created_sequences_.size()); 187 EXPECT_LE(num_run_tasks_, created_sequences_.size());
183 } 188 }
184 189
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 284 }
280 } 285 }
281 286
282 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence, 287 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence,
283 TaskSchedulerWorkerThreadTest, 288 TaskSchedulerWorkerThreadTest,
284 ::testing::Values(1)); 289 ::testing::Values(1));
285 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, 290 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence,
286 TaskSchedulerWorkerThreadTest, 291 TaskSchedulerWorkerThreadTest,
287 ::testing::Values(2)); 292 ::testing::Values(2));
288 293
294 namespace {
295
296 class ControllableDetachDelegate : public SchedulerWorkerThread::Delegate {
297 public:
298 ControllableDetachDelegate()
299 : work_requested_(false),
300 can_detach_(false),
301 work_processed_(WaitableEvent::ResetPolicy::MANUAL,
302 WaitableEvent::InitialState::NOT_SIGNALED),
303 detach_requested_(WaitableEvent::ResetPolicy::MANUAL,
304 WaitableEvent::InitialState::NOT_SIGNALED) {}
305
306 ~ControllableDetachDelegate() override = default;
307
308 // SchedulerWorkerThread::Delegate:
309 void OnMainEntry(SchedulerWorkerThread* worker_thread) override {}
310
311 scoped_refptr<Sequence> GetWork(SchedulerWorkerThread* worker_thread)
gab 2016/06/10 16:15:21 Document what this does.
robliao 2016/06/10 18:03:42 Done.
312 override {
313 if (work_requested_)
314 return nullptr;
315
316 work_requested_ = true;
317 scoped_refptr<Sequence> sequence(new Sequence);
318 std::unique_ptr<Task> task(new Task(
319 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)),
320 TaskTraits(), TimeDelta()));
321 sequence->PushTask(std::move(task));
322 return sequence;
323 }
324
325 void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override {
326 NOTREACHED() <<
327 "GetWork() never returns a sequence so there's nothing to reenqueue.";
gab 2016/06/10 16:15:21 That's not true : it does return a sequence but it
robliao 2016/06/10 18:03:42 Indeed! Updated this copy+paste line.
328 }
329
330 TimeDelta GetSleepTimeout() override {
331 return TimeDelta::Max();
332 }
333
334 bool CanDetach(SchedulerWorkerThread* worker_thread) override {
335 detach_requested_.Signal();
336 return can_detach_;
337 }
338
339 void WaitForWorkToRun() {
340 work_processed_.Wait();
341 }
342
343 void WaitForDetachRequest() {
344 detach_requested_.Wait();
345 }
346
347 void ResetAll() {
348 work_requested_ = false;
349 work_processed_.Reset();
350 detach_requested_.Reset();
351 }
352
353 void set_can_detach(bool can_detach) { can_detach_ = can_detach; }
354
355 private:
356 bool work_requested_;
357 bool can_detach_;
gab 2016/06/10 16:15:21 = false; for 2 lines above instead of in construct
robliao 2016/06/10 18:03:42 Done. It's too bad we can't do the same for non-PO
358 WaitableEvent work_processed_;
359 WaitableEvent detach_requested_;
360
361 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate);
362 };
363
364 } // namespace
365
366 TEST(TaskSchedulerWorkerThreadTest, WorkerDetaches) {
367 TaskTracker task_tracker;
368 // Will be owned by SchedulerWorkerThread.
369 ControllableDetachDelegate* delegate = new ControllableDetachDelegate;
370 delegate->set_can_detach(true);
371 std::unique_ptr<SchedulerWorkerThread> worker_thread =
372 SchedulerWorkerThread::Create(
373 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
374 SchedulerWorkerThread::InitialWorkerState::ALIVE);
375 worker_thread->WakeUp();
376 delegate->WaitForWorkToRun();
377 delegate->WaitForDetachRequest();
378 // Sleep to give a chance for the detach to happen. A yield is too short.
379 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
380 ASSERT_FALSE(worker_thread->WorkerAliveForTesting());
381 }
382
383 TEST(TaskSchedulerWorkerThreadTest, WorkerDetachesAndWakes) {
384 TaskTracker task_tracker;
385 // Will be owned by SchedulerWorkerThread.
386 ControllableDetachDelegate* delegate = new ControllableDetachDelegate;
387 delegate->set_can_detach(true);
388 std::unique_ptr<SchedulerWorkerThread> worker_thread =
389 SchedulerWorkerThread::Create(
390 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
391 SchedulerWorkerThread::InitialWorkerState::ALIVE);
392 worker_thread->WakeUp();
393 delegate->WaitForWorkToRun();
394 delegate->WaitForDetachRequest();
395 // Sleep to give a chance for the detach to happen. A yield is too short.
396 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
397 ASSERT_FALSE(worker_thread->WorkerAliveForTesting());
398
399 delegate->ResetAll();
400 delegate->set_can_detach(false);
gab 2016/06/10 16:15:21 I'd expected ResetAll() to also reset "detach" to
robliao 2016/06/10 18:03:42 This used to be ResetAllAndDisallowDetach, but tha
401 worker_thread->WakeUp();
402 delegate->WaitForWorkToRun();
403 delegate->WaitForDetachRequest();
404 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
405 ASSERT_TRUE(worker_thread->WorkerAliveForTesting());
406 worker_thread->JoinForTesting();
407 }
408
409 TEST(TaskSchedulerWorkerThreadTest, CreateDetached) {
410 TaskTracker task_tracker;
411 // Will be owned by SchedulerWorkerThread.
412 ControllableDetachDelegate* delegate = new ControllableDetachDelegate;
413 std::unique_ptr<SchedulerWorkerThread> worker_thread =
414 SchedulerWorkerThread::Create(
415 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
416 SchedulerWorkerThread::InitialWorkerState::DETACHED);
417 ASSERT_FALSE(worker_thread->WorkerAliveForTesting());
418 worker_thread->WakeUp();
419 delegate->WaitForWorkToRun();
420 delegate->WaitForDetachRequest();
421 ASSERT_TRUE(worker_thread->WorkerAliveForTesting());
422 worker_thread->JoinForTesting();
423 }
424
289 } // namespace 425 } // namespace
290 } // namespace internal 426 } // namespace internal
291 } // namespace base 427 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698