| OLD | NEW |
| 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 "platform/scheduler/base/queueing_time_estimator.h" | 5 #include "platform/scheduler/base/queueing_time_estimator.h" |
| 6 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 #include "platform/scheduler/base/test_time_source.h" | 7 #include "platform/scheduler/base/test_time_source.h" |
| 8 #include "testing/gmock/include/gmock/gmock.h" | 8 #include "testing/gmock/include/gmock/gmock.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 10 |
| 11 namespace blink { | 11 namespace blink { |
| 12 namespace scheduler { | 12 namespace scheduler { |
| 13 | 13 |
| 14 using QueueingTimeEstimatorTest = testing::Test; | 14 using QueueingTimeEstimatorTest = ::testing::Test; |
| 15 | 15 |
| 16 class TestQueueingTimeEstimatorClient : public QueueingTimeEstimator::Client { | 16 class TestQueueingTimeEstimatorClient : public QueueingTimeEstimator::Client { |
| 17 public: | 17 public: |
| 18 void OnQueueingTimeForWindowEstimated( | 18 void OnQueueingTimeForWindowEstimated( |
| 19 base::TimeDelta queueing_time, | 19 base::TimeDelta queueing_time, |
| 20 base::TimeTicks window_start_time) override { | 20 base::TimeTicks window_start_time) override { |
| 21 expected_queueing_times_.push_back(queueing_time); | 21 expected_queueing_times_.push_back(queueing_time); |
| 22 } | 22 } |
| 23 const std::vector<base::TimeDelta>& expected_queueing_times() { | 23 const std::vector<base::TimeDelta>& expected_queueing_times() { |
| 24 return expected_queueing_times_; | 24 return expected_queueing_times_; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 51 estimator.OnTopLevelTaskCompleted(time); | 51 estimator.OnTopLevelTaskCompleted(time); |
| 52 } | 52 } |
| 53 | 53 |
| 54 // Flush the data by adding a task in the next window. | 54 // Flush the data by adding a task in the next window. |
| 55 time += base::TimeDelta::FromMilliseconds(5000); | 55 time += base::TimeDelta::FromMilliseconds(5000); |
| 56 estimator.OnTopLevelTaskStarted(time); | 56 estimator.OnTopLevelTaskStarted(time); |
| 57 time += base::TimeDelta::FromMilliseconds(500); | 57 time += base::TimeDelta::FromMilliseconds(500); |
| 58 estimator.OnTopLevelTaskCompleted(time); | 58 estimator.OnTopLevelTaskCompleted(time); |
| 59 | 59 |
| 60 EXPECT_THAT(client.expected_queueing_times(), | 60 EXPECT_THAT(client.expected_queueing_times(), |
| 61 testing::ElementsAre(base::TimeDelta::FromMilliseconds(300))); | 61 ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(300))); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // One 20 second long task, starting 3 seconds into the first window. | 64 // One 20 second long task, starting 3 seconds into the first window. |
| 65 // Window 1: Probability of being within task = 2/5. Expected delay within task: | 65 // Window 1: Probability of being within task = 2/5. Expected delay within task: |
| 66 // avg(20, 18). Total expected queueing time = 7.6s. | 66 // avg(20, 18). Total expected queueing time = 7.6s. |
| 67 // Window 2: Probability of being within task = 1. Expected delay within task: | 67 // Window 2: Probability of being within task = 1. Expected delay within task: |
| 68 // avg(18, 13). Total expected queueing time = 15.5s. | 68 // avg(18, 13). Total expected queueing time = 15.5s. |
| 69 // Window 5: Probability of being within task = 3/5. Expected delay within task: | 69 // Window 5: Probability of being within task = 3/5. Expected delay within task: |
| 70 // avg(3, 0). Total expected queueing time = 0.9s. | 70 // avg(3, 0). Total expected queueing time = 0.9s. |
| 71 TEST_F(QueueingTimeEstimatorTest, MultiWindowTask) { | 71 TEST_F(QueueingTimeEstimatorTest, MultiWindowTask) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 83 time += base::TimeDelta::FromMilliseconds(20000); | 83 time += base::TimeDelta::FromMilliseconds(20000); |
| 84 estimator.OnTopLevelTaskCompleted(time); | 84 estimator.OnTopLevelTaskCompleted(time); |
| 85 | 85 |
| 86 // Flush the data by adding a task in the next window. | 86 // Flush the data by adding a task in the next window. |
| 87 time += base::TimeDelta::FromMilliseconds(5000); | 87 time += base::TimeDelta::FromMilliseconds(5000); |
| 88 estimator.OnTopLevelTaskStarted(time); | 88 estimator.OnTopLevelTaskStarted(time); |
| 89 time += base::TimeDelta::FromMilliseconds(500); | 89 time += base::TimeDelta::FromMilliseconds(500); |
| 90 estimator.OnTopLevelTaskCompleted(time); | 90 estimator.OnTopLevelTaskCompleted(time); |
| 91 | 91 |
| 92 EXPECT_THAT(client.expected_queueing_times(), | 92 EXPECT_THAT(client.expected_queueing_times(), |
| 93 testing::ElementsAre(base::TimeDelta::FromMilliseconds(7600), | 93 ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(7600), |
| 94 base::TimeDelta::FromMilliseconds(15500), | 94 base::TimeDelta::FromMilliseconds(15500), |
| 95 base::TimeDelta::FromMilliseconds(10500), | 95 base::TimeDelta::FromMilliseconds(10500), |
| 96 base::TimeDelta::FromMilliseconds(5500), | 96 base::TimeDelta::FromMilliseconds(5500), |
| 97 base::TimeDelta::FromMilliseconds(900))); | 97 base::TimeDelta::FromMilliseconds(900))); |
| 98 } | 98 } |
| 99 | 99 |
| 100 // The main thread is considered unresponsive during a single long task. In this | 100 // The main thread is considered unresponsive during a single long task. In this |
| 101 // case, the single long task is 3 seconds long. | 101 // case, the single long task is 3 seconds long. |
| 102 // Probability of being with the task = 3/5. Expected delay within task: | 102 // Probability of being with the task = 3/5. Expected delay within task: |
| 103 // avg(0, 3). Total expected queueing time = 3/5 * 3/2 = 0.9s. | 103 // avg(0, 3). Total expected queueing time = 3/5 * 3/2 = 0.9s. |
| 104 // In this example, the queueing time comes from the current, incomplete window. | 104 // In this example, the queueing time comes from the current, incomplete window. |
| 105 TEST_F(QueueingTimeEstimatorTest, | 105 TEST_F(QueueingTimeEstimatorTest, |
| 106 EstimateQueueingTimeDuringSingleLongTaskIncompleteWindow) { | 106 EstimateQueueingTimeDuringSingleLongTaskIncompleteWindow) { |
| 107 TestQueueingTimeEstimatorClient client; | 107 TestQueueingTimeEstimatorClient client; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 time += base::TimeDelta::FromMilliseconds(1000); | 246 time += base::TimeDelta::FromMilliseconds(1000); |
| 247 estimator.OnTopLevelTaskCompleted(time); | 247 estimator.OnTopLevelTaskCompleted(time); |
| 248 | 248 |
| 249 // Flush the data by adding a task in the next window. | 249 // Flush the data by adding a task in the next window. |
| 250 time += base::TimeDelta::FromMilliseconds(5000); | 250 time += base::TimeDelta::FromMilliseconds(5000); |
| 251 estimator.OnTopLevelTaskStarted(time); | 251 estimator.OnTopLevelTaskStarted(time); |
| 252 time += base::TimeDelta::FromMilliseconds(500); | 252 time += base::TimeDelta::FromMilliseconds(500); |
| 253 estimator.OnTopLevelTaskCompleted(time); | 253 estimator.OnTopLevelTaskCompleted(time); |
| 254 | 254 |
| 255 EXPECT_THAT(client.expected_queueing_times(), | 255 EXPECT_THAT(client.expected_queueing_times(), |
| 256 testing::ElementsAre(base::TimeDelta::FromMilliseconds(0), | 256 ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(0), |
| 257 base::TimeDelta::FromMilliseconds(0), | 257 base::TimeDelta::FromMilliseconds(0), |
| 258 base::TimeDelta::FromMilliseconds(0), | 258 base::TimeDelta::FromMilliseconds(0), |
| 259 base::TimeDelta::FromMilliseconds(0), | 259 base::TimeDelta::FromMilliseconds(0), |
| 260 base::TimeDelta::FromMilliseconds(100))); | 260 base::TimeDelta::FromMilliseconds(100))); |
| 261 } | 261 } |
| 262 | 262 |
| 263 // If a task is too long, we assume it's invalid. Perhaps the user's machine | 263 // If a task is too long, we assume it's invalid. Perhaps the user's machine |
| 264 // went to sleep during a task, resulting in an extremely long task. Ignore | 264 // went to sleep during a task, resulting in an extremely long task. Ignore |
| 265 // these long tasks completely. | 265 // these long tasks completely. |
| 266 TEST_F(QueueingTimeEstimatorTest, IgnoreExtremelyLongTasks) { | 266 TEST_F(QueueingTimeEstimatorTest, IgnoreExtremelyLongTasks) { |
| 267 TestQueueingTimeEstimatorClient client; | 267 TestQueueingTimeEstimatorClient client; |
| 268 QueueingTimeEstimatorForTest estimator(&client, | 268 QueueingTimeEstimatorForTest estimator(&client, |
| 269 base::TimeDelta::FromSeconds(5), 1); | 269 base::TimeDelta::FromSeconds(5), 1); |
| 270 // Start with a 1 second task. | 270 // Start with a 1 second task. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 283 time += base::TimeDelta::FromMilliseconds(1000); | 283 time += base::TimeDelta::FromMilliseconds(1000); |
| 284 estimator.OnTopLevelTaskCompleted(time); | 284 estimator.OnTopLevelTaskCompleted(time); |
| 285 | 285 |
| 286 // Flush the data by adding a task in the next window. | 286 // Flush the data by adding a task in the next window. |
| 287 time += base::TimeDelta::FromMilliseconds(5000); | 287 time += base::TimeDelta::FromMilliseconds(5000); |
| 288 estimator.OnTopLevelTaskStarted(time); | 288 estimator.OnTopLevelTaskStarted(time); |
| 289 time += base::TimeDelta::FromMilliseconds(500); | 289 time += base::TimeDelta::FromMilliseconds(500); |
| 290 estimator.OnTopLevelTaskCompleted(time); | 290 estimator.OnTopLevelTaskCompleted(time); |
| 291 | 291 |
| 292 EXPECT_THAT(client.expected_queueing_times(), | 292 EXPECT_THAT(client.expected_queueing_times(), |
| 293 testing::ElementsAre(base::TimeDelta::FromMilliseconds(100), | 293 ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(100), |
| 294 base::TimeDelta::FromMilliseconds(0), | 294 base::TimeDelta::FromMilliseconds(0), |
| 295 base::TimeDelta::FromMilliseconds(0), | 295 base::TimeDelta::FromMilliseconds(0), |
| 296 base::TimeDelta::FromMilliseconds(0), | 296 base::TimeDelta::FromMilliseconds(0), |
| 297 base::TimeDelta::FromMilliseconds(0), | 297 base::TimeDelta::FromMilliseconds(0), |
| 298 base::TimeDelta::FromMilliseconds(0), | 298 base::TimeDelta::FromMilliseconds(0), |
| 299 base::TimeDelta::FromMilliseconds(0), | 299 base::TimeDelta::FromMilliseconds(0), |
| 300 base::TimeDelta::FromMilliseconds(100))); | 300 base::TimeDelta::FromMilliseconds(100))); |
| 301 } | 301 } |
| 302 | 302 |
| 303 // ^ Instantaneous queuing time | 303 // ^ Instantaneous queuing time |
| 304 // | | 304 // | |
| 305 // | | 305 // | |
| 306 // | |\ . | 306 // | |\ . |
| 307 // | | \ . | 307 // | | \ . |
| 308 // | | \ . | 308 // | | \ . |
| 309 // | | \ . | 309 // | | \ . |
| 310 // | | \ | . | 310 // | | \ | . |
| (...skipping 12 matching lines...) Expand all Loading... |
| 323 estimator.OnTopLevelTaskStarted(time); | 323 estimator.OnTopLevelTaskStarted(time); |
| 324 time += base::TimeDelta::FromMilliseconds(5000); | 324 time += base::TimeDelta::FromMilliseconds(5000); |
| 325 estimator.OnTopLevelTaskCompleted(time); | 325 estimator.OnTopLevelTaskCompleted(time); |
| 326 | 326 |
| 327 time += base::TimeDelta::FromMilliseconds(6000); | 327 time += base::TimeDelta::FromMilliseconds(6000); |
| 328 | 328 |
| 329 estimator.OnTopLevelTaskStarted(time); | 329 estimator.OnTopLevelTaskStarted(time); |
| 330 estimator.OnTopLevelTaskCompleted(time); | 330 estimator.OnTopLevelTaskCompleted(time); |
| 331 | 331 |
| 332 EXPECT_THAT(client.expected_queueing_times(), | 332 EXPECT_THAT(client.expected_queueing_times(), |
| 333 testing::ElementsAre(base::TimeDelta::FromMilliseconds(900), | 333 ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(900), |
| 334 base::TimeDelta::FromMilliseconds(1600), | 334 base::TimeDelta::FromMilliseconds(1600), |
| 335 base::TimeDelta::FromMilliseconds(2100), | 335 base::TimeDelta::FromMilliseconds(2100), |
| 336 base::TimeDelta::FromMilliseconds(2400), | 336 base::TimeDelta::FromMilliseconds(2400), |
| 337 base::TimeDelta::FromMilliseconds(2500), | 337 base::TimeDelta::FromMilliseconds(2500), |
| 338 base::TimeDelta::FromMilliseconds(1600), | 338 base::TimeDelta::FromMilliseconds(1600), |
| 339 base::TimeDelta::FromMilliseconds(900), | 339 base::TimeDelta::FromMilliseconds(900), |
| 340 base::TimeDelta::FromMilliseconds(400), | 340 base::TimeDelta::FromMilliseconds(400), |
| 341 base::TimeDelta::FromMilliseconds(100), | 341 base::TimeDelta::FromMilliseconds(100), |
| 342 base::TimeDelta::FromMilliseconds(0))); | 342 base::TimeDelta::FromMilliseconds(0))); |
| 343 } | 343 } |
| 344 | 344 |
| 345 // ^ Instantaneous queuing time | 345 // ^ Instantaneous queuing time |
| 346 // | | 346 // | |
| 347 // | | 347 // | |
| 348 // | |\ . | 348 // | |\ . |
| 349 // | | \ . | 349 // | | \ . |
| 350 // | | \ . | 350 // | | \ . |
| 351 // | | \ |\ . | 351 // | | \ |\ . |
| 352 // | | \ | \ | . | 352 // | | \ | \ | . |
| (...skipping 28 matching lines...) Expand all Loading... |
| 381 base::TimeDelta::FromMilliseconds(400), | 381 base::TimeDelta::FromMilliseconds(400), |
| 382 base::TimeDelta::FromMilliseconds(600), | 382 base::TimeDelta::FromMilliseconds(600), |
| 383 base::TimeDelta::FromMilliseconds(625), | 383 base::TimeDelta::FromMilliseconds(625), |
| 384 base::TimeDelta::FromMilliseconds(725), | 384 base::TimeDelta::FromMilliseconds(725), |
| 385 base::TimeDelta::FromMilliseconds(725), | 385 base::TimeDelta::FromMilliseconds(725), |
| 386 base::TimeDelta::FromMilliseconds(325), | 386 base::TimeDelta::FromMilliseconds(325), |
| 387 base::TimeDelta::FromMilliseconds(125), | 387 base::TimeDelta::FromMilliseconds(125), |
| 388 base::TimeDelta::FromMilliseconds(100), | 388 base::TimeDelta::FromMilliseconds(100), |
| 389 base::TimeDelta::FromMilliseconds(0)}; | 389 base::TimeDelta::FromMilliseconds(0)}; |
| 390 EXPECT_THAT(client.expected_queueing_times(), | 390 EXPECT_THAT(client.expected_queueing_times(), |
| 391 testing::ElementsAreArray(expected_durations)); | 391 ::testing::ElementsAreArray(expected_durations)); |
| 392 } | 392 } |
| 393 | 393 |
| 394 // ^ Instantaneous queuing time | 394 // ^ Instantaneous queuing time |
| 395 // | | 395 // | |
| 396 // | | 396 // | |
| 397 // | |\ . | 397 // | |\ . |
| 398 // | | \ . | 398 // | | \ . |
| 399 // | | \ . | 399 // | | \ . |
| 400 // | | \ |\ . | 400 // | | \ |\ . |
| 401 // | | \| \ | . | 401 // | | \| \ | . |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 base::TimeDelta::FromMilliseconds(600), | 438 base::TimeDelta::FromMilliseconds(600), |
| 439 base::TimeDelta::FromMilliseconds(700), | 439 base::TimeDelta::FromMilliseconds(700), |
| 440 base::TimeDelta::FromMilliseconds(725), | 440 base::TimeDelta::FromMilliseconds(725), |
| 441 base::TimeDelta::FromMilliseconds(725), | 441 base::TimeDelta::FromMilliseconds(725), |
| 442 base::TimeDelta::FromMilliseconds(325), | 442 base::TimeDelta::FromMilliseconds(325), |
| 443 base::TimeDelta::FromMilliseconds(125), | 443 base::TimeDelta::FromMilliseconds(125), |
| 444 base::TimeDelta::FromMilliseconds(25), | 444 base::TimeDelta::FromMilliseconds(25), |
| 445 base::TimeDelta::FromMilliseconds(0)}; | 445 base::TimeDelta::FromMilliseconds(0)}; |
| 446 | 446 |
| 447 EXPECT_THAT(client.expected_queueing_times(), | 447 EXPECT_THAT(client.expected_queueing_times(), |
| 448 testing::ElementsAreArray(expected_durations)); | 448 ::testing::ElementsAreArray(expected_durations)); |
| 449 } | 449 } |
| 450 | 450 |
| 451 } // namespace scheduler | 451 } // namespace scheduler |
| 452 } // namespace blink | 452 } // namespace blink |
| OLD | NEW |