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

Side by Side Diff: base/task_scheduler/scheduler_worker_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: Apply Renames 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.h" 5 #include "base/task_scheduler/scheduler_worker.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_set_(WaitableEvent::ResetPolicy::MANUAL, 37 worker_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_ = SchedulerWorker::Create( 41 worker_ = SchedulerWorker::Create(
42 ThreadPriority::NORMAL, 42 ThreadPriority::NORMAL,
43 WrapUnique(new TestSchedulerWorkerDelegate(this)), 43 WrapUnique(new TestSchedulerWorkerDelegate(this)),
44 &task_tracker_); 44 &task_tracker_,
45 SchedulerWorker::InitialState::ALIVE);
45 ASSERT_TRUE(worker_); 46 ASSERT_TRUE(worker_);
46 worker_set_.Signal(); 47 worker_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_->JoinForTesting(); 52 worker_->JoinForTesting();
52 } 53 }
53 54
54 size_t TasksPerSequence() const { return GetParam(); } 55 size_t TasksPerSequence() const { return GetParam(); }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 AutoSchedulerLock auto_lock(outer_->lock_); 165 AutoSchedulerLock auto_lock(outer_->lock_);
165 outer_->re_enqueued_sequences_.push_back(std::move(sequence)); 166 outer_->re_enqueued_sequences_.push_back(std::move(sequence));
166 EXPECT_LE(outer_->re_enqueued_sequences_.size(), 167 EXPECT_LE(outer_->re_enqueued_sequences_.size(),
167 outer_->created_sequences_.size()); 168 outer_->created_sequences_.size());
168 } 169 }
169 170
170 TimeDelta GetSleepTimeout() override { 171 TimeDelta GetSleepTimeout() override {
171 return TimeDelta::Max(); 172 return TimeDelta::Max();
172 } 173 }
173 174
175 bool CanDetach(SchedulerWorker* worker) override {
176 return false;
177 }
178
174 private: 179 private:
175 TaskSchedulerWorkerTest* outer_; 180 TaskSchedulerWorkerTest* outer_;
176 }; 181 };
177 182
178 void RunTaskCallback() { 183 void RunTaskCallback() {
179 AutoSchedulerLock auto_lock(lock_); 184 AutoSchedulerLock auto_lock(lock_);
180 ++num_run_tasks_; 185 ++num_run_tasks_;
181 EXPECT_LE(num_run_tasks_, created_sequences_.size()); 186 EXPECT_LE(num_run_tasks_, created_sequences_.size());
182 } 187 }
183 188
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 283 }
279 } 284 }
280 285
281 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence, 286 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence,
282 TaskSchedulerWorkerTest, 287 TaskSchedulerWorkerTest,
283 ::testing::Values(1)); 288 ::testing::Values(1));
284 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, 289 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence,
285 TaskSchedulerWorkerTest, 290 TaskSchedulerWorkerTest,
286 ::testing::Values(2)); 291 ::testing::Values(2));
287 292
293 namespace {
294
295 class ControllableDetachDelegate : public SchedulerWorker::Delegate {
296 public:
297 ControllableDetachDelegate()
298 : work_processed_(WaitableEvent::ResetPolicy::MANUAL,
299 WaitableEvent::InitialState::NOT_SIGNALED),
300 detach_requested_(WaitableEvent::ResetPolicy::MANUAL,
301 WaitableEvent::InitialState::NOT_SIGNALED) {}
302
303 ~ControllableDetachDelegate() override = default;
304
305 // SchedulerWorker::Delegate:
306 void OnMainEntry(SchedulerWorker* worker) override {}
307
308 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker)
309 override {
310 // Sends one item of work to signal |work_processed_|. On subsequent calls,
311 // send nullptr to indicate there's no more work to be done.
fdoray 2016/06/22 18:22:43 Send/send or Sends/sends
robliao 2016/06/22 19:24:33 Adjusted to keep the subject consistent for both s
312 if (work_requested_)
313 return nullptr;
314
315 work_requested_ = true;
316 scoped_refptr<Sequence> sequence(new Sequence);
317 std::unique_ptr<Task> task(new Task(
318 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)),
319 TaskTraits(), TimeDelta()));
320 sequence->PushTask(std::move(task));
321 return sequence;
322 }
323
324 void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override {
325 ADD_FAILURE() <<
326 "GetWork() returns a sequence of one, so there's nothing to reenqueue.";
327 }
328
329 TimeDelta GetSleepTimeout() override {
330 return TimeDelta::Max();
331 }
332
333 bool CanDetach(SchedulerWorker* worker) override {
334 detach_requested_.Signal();
335 return can_detach_;
336 }
337
338 void WaitForWorkToRun() {
339 work_processed_.Wait();
340 }
341
342 void WaitForDetachRequest() {
343 detach_requested_.Wait();
344 }
345
346 void ResetState() {
347 work_requested_ = false;
348 work_processed_.Reset();
349 detach_requested_.Reset();
350 }
351
352 void set_can_detach(bool can_detach) { can_detach_ = can_detach; }
353
354 private:
355 bool work_requested_ = false;
356 bool can_detach_ = false;
357 WaitableEvent work_processed_;
358 WaitableEvent detach_requested_;
359
360 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate);
361 };
362
363 } // namespace
364
365 TEST(TaskSchedulerWorkerTest, WorkerDetaches) {
366 TaskTracker task_tracker;
367 // Will be owned by SchedulerWorker.
368 ControllableDetachDelegate* delegate = new ControllableDetachDelegate;
369 delegate->set_can_detach(true);
370 std::unique_ptr<SchedulerWorker> worker =
371 SchedulerWorker::Create(
372 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
373 SchedulerWorker::InitialState::ALIVE);
374 worker->WakeUp();
375 delegate->WaitForWorkToRun();
376 delegate->WaitForDetachRequest();
377 // Sleep to give a chance for the detach to happen. A yield is too short.
378 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
379 ASSERT_FALSE(worker->ThreadAliveForTesting());
380 }
381
382 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) {
383 TaskTracker task_tracker;
384 // Will be owned by SchedulerWorker.
385 ControllableDetachDelegate* delegate = new ControllableDetachDelegate;
386 delegate->set_can_detach(true);
387 std::unique_ptr<SchedulerWorker> worker =
388 SchedulerWorker::Create(
389 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
390 SchedulerWorker::InitialState::ALIVE);
391 worker->WakeUp();
392 delegate->WaitForWorkToRun();
393 delegate->WaitForDetachRequest();
394 // Sleep to give a chance for the detach to happen. A yield is too short.
395 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
396 ASSERT_FALSE(worker->ThreadAliveForTesting());
397
398 delegate->ResetState();
399 delegate->set_can_detach(false);
400 worker->WakeUp();
401 delegate->WaitForWorkToRun();
402 delegate->WaitForDetachRequest();
403 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
404 ASSERT_TRUE(worker->ThreadAliveForTesting());
405 worker->JoinForTesting();
406 }
407
408 TEST(TaskSchedulerWorkerTest, CreateDetached) {
409 TaskTracker task_tracker;
410 // Will be owned by SchedulerWorker.
411 ControllableDetachDelegate* delegate = new ControllableDetachDelegate;
412 std::unique_ptr<SchedulerWorker> worker =
413 SchedulerWorker::Create(
414 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
415 SchedulerWorker::InitialState::DETACHED);
416 ASSERT_FALSE(worker->ThreadAliveForTesting());
417 worker->WakeUp();
418 delegate->WaitForWorkToRun();
419 delegate->WaitForDetachRequest();
420 ASSERT_TRUE(worker->ThreadAliveForTesting());
421 worker->JoinForTesting();
422 }
423
288 } // namespace 424 } // namespace
289 } // namespace internal 425 } // namespace internal
290 } // namespace base 426 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698