OLD | NEW |
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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <cstdlib> | 8 #include <cstdlib> |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); | 316 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); |
317 } | 317 } |
318 #elif defined(OS_MACOSX) | 318 #elif defined(OS_MACOSX) |
319 // Unloading a library on the Mac is synchronous. | 319 // Unloading a library on the Mac is synchronous. |
320 #else | 320 #else |
321 NOTIMPLEMENTED(); | 321 NOTIMPLEMENTED(); |
322 #endif | 322 #endif |
323 } | 323 } |
324 | 324 |
325 // Called on the profiler thread when complete, to collect profiles. | 325 // Called on the profiler thread when complete, to collect profiles. |
326 void SaveProfiles(CallStackProfiles* profiles, | 326 bool SaveProfiles(CallStackProfiles* profiles, |
327 CallStackProfiles pending_profiles) { | 327 CallStackProfiles pending_profiles, |
| 328 StackSamplingProfiler::SamplingParams* sampling_params) { |
328 *profiles = std::move(pending_profiles); | 329 *profiles = std::move(pending_profiles); |
| 330 return false; |
329 } | 331 } |
330 | 332 |
331 // Called on the profiler thread when complete. Collects profiles produced by | 333 // Called on the profiler thread when complete. Collects profiles produced by |
332 // the profiler, and signals an event to allow the main thread to know that that | 334 // the profiler, and signals an event to allow the main thread to know that that |
333 // the profiler is done. | 335 // the profiler is done. |
334 void SaveProfilesAndSignalEvent(CallStackProfiles* profiles, | 336 bool SaveProfilesAndSignalEvent( |
335 WaitableEvent* event, | 337 CallStackProfiles* profiles, |
336 CallStackProfiles pending_profiles) { | 338 WaitableEvent* event, |
| 339 CallStackProfiles pending_profiles, |
| 340 StackSamplingProfiler::SamplingParams* sampling_params) { |
337 *profiles = std::move(pending_profiles); | 341 *profiles = std::move(pending_profiles); |
338 event->Signal(); | 342 event->Signal(); |
| 343 return false; |
| 344 } |
| 345 |
| 346 // Similar to SaveProfilesAndSignalEvent(), but will schedule a second |
| 347 // collection after the first call back. |
| 348 bool SaveProfilesAndReschedule( |
| 349 std::vector<CallStackProfiles>* profiles, |
| 350 WaitableEvent* event, |
| 351 CallStackProfiles pending_profiles, |
| 352 StackSamplingProfiler::SamplingParams* sampling_params) { |
| 353 profiles->push_back(std::move(pending_profiles)); |
| 354 |
| 355 event->Signal(); |
| 356 event->Reset(); |
| 357 |
| 358 if (profiles->size() == 2) |
| 359 return false; |
| 360 |
| 361 sampling_params->initial_delay = base::TimeDelta::FromSeconds(1); |
| 362 sampling_params->bursts = 1; |
| 363 sampling_params->samples_per_burst = 1; |
| 364 // Below are unused: |
| 365 sampling_params->burst_interval = base::TimeDelta::FromMilliseconds(0); |
| 366 sampling_params->sampling_interval = base::TimeDelta::FromMilliseconds(0); |
| 367 return true; |
339 } | 368 } |
340 | 369 |
341 // Executes the function with the target thread running and executing within | 370 // Executes the function with the target thread running and executing within |
342 // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup | 371 // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup |
343 // and shutdown work before and afterward. | 372 // and shutdown work before and afterward. |
344 template <class Function> | 373 template <class Function> |
345 void WithTargetThread(Function function, | 374 void WithTargetThread(Function function, |
346 const StackConfiguration& stack_config) { | 375 const StackConfiguration& stack_config) { |
347 TargetThread target_thread(stack_config); | 376 TargetThread target_thread(stack_config); |
348 PlatformThreadHandle target_thread_handle; | 377 PlatformThreadHandle target_thread_handle; |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 // Ensure a second request will run and not block. | 1042 // Ensure a second request will run and not block. |
1014 sampling_completed.Reset(); | 1043 sampling_completed.Reset(); |
1015 profiles.clear(); | 1044 profiles.clear(); |
1016 profiler.Start(); | 1045 profiler.Start(); |
1017 sampling_completed.Wait(); | 1046 sampling_completed.Wait(); |
1018 profiler.Stop(); | 1047 profiler.Stop(); |
1019 ASSERT_EQ(1u, profiles.size()); | 1048 ASSERT_EQ(1u, profiles.size()); |
1020 }); | 1049 }); |
1021 } | 1050 } |
1022 | 1051 |
| 1052 PROFILER_TEST_F(StackSamplingProfilerTest, RescheduledByCallback) { |
| 1053 WithTargetThread([](PlatformThreadId target_thread_id) { |
| 1054 SamplingParams params; |
| 1055 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
| 1056 params.samples_per_burst = 1; |
| 1057 |
| 1058 std::vector<CallStackProfiles> profiles; |
| 1059 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL, |
| 1060 WaitableEvent::InitialState::NOT_SIGNALED); |
| 1061 const StackSamplingProfiler::CompletedCallback callback = |
| 1062 Bind(&SaveProfilesAndReschedule, Unretained(&profiles), |
| 1063 Unretained(&sampling_completed)); |
| 1064 StackSamplingProfiler profiler(target_thread_id, params, callback); |
| 1065 |
| 1066 // Start once and wait for it to be completed. |
| 1067 profiler.Start(); |
| 1068 sampling_completed.Wait(); |
| 1069 ASSERT_EQ(1u, profiles.size()); |
| 1070 ASSERT_EQ(1u, profiles[0].size()); |
| 1071 |
| 1072 // Now, wait for the second callback call. |
| 1073 sampling_completed.Wait(); |
| 1074 profiler.Stop(); |
| 1075 ASSERT_EQ(2u, profiles.size()); |
| 1076 ASSERT_EQ(1u, profiles[1].size()); |
| 1077 }); |
| 1078 } |
| 1079 |
1023 // Checks that the different profilers may be run. | 1080 // Checks that the different profilers may be run. |
1024 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { | 1081 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { |
1025 SamplingParams params; | 1082 SamplingParams params; |
1026 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 1083 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
1027 params.samples_per_burst = 1; | 1084 params.samples_per_burst = 1; |
1028 | 1085 |
1029 std::vector<CallStackProfile> profiles; | 1086 std::vector<CallStackProfile> profiles; |
1030 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); | 1087 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); |
1031 ASSERT_EQ(1u, profiles.size()); | 1088 ASSERT_EQ(1u, profiles.size()); |
1032 | 1089 |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 EXPECT_EQ(9u, profiler_thread1.profiles()[0].samples.size()); | 1553 EXPECT_EQ(9u, profiler_thread1.profiles()[0].samples.size()); |
1497 ASSERT_EQ(1u, profiler_thread2.profiles().size()); | 1554 ASSERT_EQ(1u, profiler_thread2.profiles().size()); |
1498 EXPECT_EQ(8u, profiler_thread2.profiles()[0].samples.size()); | 1555 EXPECT_EQ(8u, profiler_thread2.profiles()[0].samples.size()); |
1499 | 1556 |
1500 profiler_thread1.Join(); | 1557 profiler_thread1.Join(); |
1501 profiler_thread2.Join(); | 1558 profiler_thread2.Join(); |
1502 }); | 1559 }); |
1503 } | 1560 } |
1504 | 1561 |
1505 } // namespace base | 1562 } // namespace base |
OLD | NEW |