Chromium Code Reviews| 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 <algorithm> | |
| 8 #include <cstdlib> | 9 #include <cstdlib> |
| 9 #include <memory> | 10 #include <memory> |
| 10 #include <utility> | 11 #include <utility> |
| 11 #include <vector> | 12 #include <vector> |
| 12 | 13 |
| 13 #include "base/bind.h" | 14 #include "base/bind.h" |
| 14 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 15 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
| 16 #include "base/macros.h" | 17 #include "base/macros.h" |
| 17 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); | 317 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); |
| 317 } | 318 } |
| 318 #elif defined(OS_MACOSX) | 319 #elif defined(OS_MACOSX) |
| 319 // Unloading a library on the Mac is synchronous. | 320 // Unloading a library on the Mac is synchronous. |
| 320 #else | 321 #else |
| 321 NOTIMPLEMENTED(); | 322 NOTIMPLEMENTED(); |
| 322 #endif | 323 #endif |
| 323 } | 324 } |
| 324 | 325 |
| 325 // Called on the profiler thread when complete, to collect profiles. | 326 // Called on the profiler thread when complete, to collect profiles. |
| 326 void SaveProfiles(CallStackProfiles* profiles, | 327 Optional<StackSamplingProfiler::SamplingParams> SaveProfiles( |
| 327 CallStackProfiles pending_profiles) { | 328 CallStackProfiles* profiles, |
| 329 CallStackProfiles pending_profiles) { | |
| 328 *profiles = std::move(pending_profiles); | 330 *profiles = std::move(pending_profiles); |
| 331 return Optional<StackSamplingProfiler::SamplingParams>(); | |
| 329 } | 332 } |
| 330 | 333 |
| 331 // Called on the profiler thread when complete. Collects profiles produced by | 334 // 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 | 335 // the profiler, and signals an event to allow the main thread to know that that |
| 333 // the profiler is done. | 336 // the profiler is done. |
| 334 void SaveProfilesAndSignalEvent(CallStackProfiles* profiles, | 337 Optional<StackSamplingProfiler::SamplingParams> SaveProfilesAndSignalEvent( |
| 335 WaitableEvent* event, | 338 CallStackProfiles* profiles, |
| 336 CallStackProfiles pending_profiles) { | 339 WaitableEvent* event, |
| 340 CallStackProfiles pending_profiles) { | |
| 337 *profiles = std::move(pending_profiles); | 341 *profiles = std::move(pending_profiles); |
| 338 event->Signal(); | 342 event->Signal(); |
| 343 return Optional<StackSamplingProfiler::SamplingParams>(); | |
| 344 } | |
| 345 | |
| 346 // Similar to SaveProfilesAndSignalEvent(), but will schedule a second | |
| 347 // collection after the first call back. | |
| 348 Optional<StackSamplingProfiler::SamplingParams> SaveProfilesAndReschedule( | |
| 349 std::vector<CallStackProfiles>* profiles, | |
| 350 WaitableEvent* event, | |
| 351 CallStackProfiles pending_profiles) { | |
| 352 LOG(ERROR) << "SaveProfilesAndReschedule"; | |
| 353 profiles->push_back(std::move(pending_profiles)); | |
| 354 | |
| 355 event->Signal(); | |
| 356 event->Reset(); | |
|
Robert Sesek
2017/07/14 19:22:39
I've just rewritten WaitableEvent on Mac and it's
| |
| 357 | |
| 358 if (profiles->size() == 2) { | |
| 359 LOG(ERROR) << "Returning empty params"; | |
| 360 return Optional<StackSamplingProfiler::SamplingParams>(); | |
| 361 } | |
| 362 | |
| 363 StackSamplingProfiler::SamplingParams sampling_params; | |
| 364 sampling_params.initial_delay = base::TimeDelta::FromMilliseconds(100); | |
| 365 sampling_params.bursts = 1; | |
| 366 sampling_params.samples_per_burst = 1; | |
| 367 // Below are unused: | |
| 368 sampling_params.burst_interval = base::TimeDelta::FromMilliseconds(0); | |
| 369 sampling_params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | |
| 370 LOG(ERROR) << "Returning new params"; | |
| 371 return sampling_params; | |
| 339 } | 372 } |
| 340 | 373 |
| 341 // Executes the function with the target thread running and executing within | 374 // Executes the function with the target thread running and executing within |
| 342 // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup | 375 // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup |
| 343 // and shutdown work before and afterward. | 376 // and shutdown work before and afterward. |
| 344 template <class Function> | 377 template <class Function> |
| 345 void WithTargetThread(Function function, | 378 void WithTargetThread(Function function, |
| 346 const StackConfiguration& stack_config) { | 379 const StackConfiguration& stack_config) { |
| 347 TargetThread target_thread(stack_config); | 380 TargetThread target_thread(stack_config); |
| 348 PlatformThreadHandle target_thread_handle; | 381 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. | 1046 // Ensure a second request will run and not block. |
| 1014 sampling_completed.Reset(); | 1047 sampling_completed.Reset(); |
| 1015 profiles.clear(); | 1048 profiles.clear(); |
| 1016 profiler.Start(); | 1049 profiler.Start(); |
| 1017 sampling_completed.Wait(); | 1050 sampling_completed.Wait(); |
| 1018 profiler.Stop(); | 1051 profiler.Stop(); |
| 1019 ASSERT_EQ(1u, profiles.size()); | 1052 ASSERT_EQ(1u, profiles.size()); |
| 1020 }); | 1053 }); |
| 1021 } | 1054 } |
| 1022 | 1055 |
| 1056 PROFILER_TEST_F(StackSamplingProfilerTest, RescheduledByCallback) { | |
| 1057 LOG(ERROR) << "RescheduledByCallback start"; | |
| 1058 WithTargetThread([](PlatformThreadId target_thread_id) { | |
| 1059 SamplingParams params; | |
| 1060 params.sampling_interval = TimeDelta::FromMilliseconds(0); | |
| 1061 params.samples_per_burst = 1; | |
| 1062 | |
| 1063 std::vector<CallStackProfiles> profiles; | |
| 1064 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL, | |
| 1065 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 1066 const StackSamplingProfiler::CompletedCallback callback = | |
| 1067 Bind(&SaveProfilesAndReschedule, Unretained(&profiles), | |
| 1068 Unretained(&sampling_completed)); | |
| 1069 StackSamplingProfiler profiler(target_thread_id, params, callback); | |
| 1070 | |
| 1071 // Start once and wait for it to be completed. | |
| 1072 LOG(ERROR) << "RescheduledByCallback call start"; | |
| 1073 profiler.Start(); | |
| 1074 LOG(ERROR) << "RescheduledByCallback call wait1"; | |
| 1075 sampling_completed.Wait(); | |
| 1076 LOG(ERROR) << "RescheduledByCallback after wait1"; | |
| 1077 ASSERT_EQ(1u, profiles.size()); | |
| 1078 ASSERT_EQ(1u, profiles[0].size()); | |
| 1079 | |
| 1080 // Now, wait for the second callback call. | |
| 1081 LOG(ERROR) << "RescheduledByCallback call wait2"; | |
| 1082 sampling_completed.Wait(); | |
| 1083 LOG(ERROR) << "RescheduledByCallback after wait2"; | |
| 1084 profiler.Stop(); | |
| 1085 ASSERT_EQ(2u, profiles.size()); | |
| 1086 ASSERT_EQ(1u, profiles[1].size()); | |
| 1087 }); | |
| 1088 } | |
| 1089 | |
| 1023 // Checks that the different profilers may be run. | 1090 // Checks that the different profilers may be run. |
| 1024 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { | 1091 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { |
| 1025 SamplingParams params; | 1092 SamplingParams params; |
| 1026 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 1093 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
| 1027 params.samples_per_burst = 1; | 1094 params.samples_per_burst = 1; |
| 1028 | 1095 |
| 1029 std::vector<CallStackProfile> profiles; | 1096 std::vector<CallStackProfile> profiles; |
| 1030 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); | 1097 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); |
| 1031 ASSERT_EQ(1u, profiles.size()); | 1098 ASSERT_EQ(1u, profiles.size()); |
| 1032 | 1099 |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1496 EXPECT_EQ(9u, profiler_thread1.profiles()[0].samples.size()); | 1563 EXPECT_EQ(9u, profiler_thread1.profiles()[0].samples.size()); |
| 1497 ASSERT_EQ(1u, profiler_thread2.profiles().size()); | 1564 ASSERT_EQ(1u, profiler_thread2.profiles().size()); |
| 1498 EXPECT_EQ(8u, profiler_thread2.profiles()[0].samples.size()); | 1565 EXPECT_EQ(8u, profiler_thread2.profiles()[0].samples.size()); |
| 1499 | 1566 |
| 1500 profiler_thread1.Join(); | 1567 profiler_thread1.Join(); |
| 1501 profiler_thread2.Join(); | 1568 profiler_thread2.Join(); |
| 1502 }); | 1569 }); |
| 1503 } | 1570 } |
| 1504 | 1571 |
| 1505 } // namespace base | 1572 } // namespace base |
| OLD | NEW |